changeset 1099:be4292f84a3b

upgrade package freetds to cvs
author Mark Brand <mabrand@mabrand.nl>
date Tue, 17 Aug 2010 20:55:16 +0200
parents 914d3e98b61f
children ef9fcd8df707
files src/freetds-1-fastforward.patch src/freetds.mk
diffstat 2 files changed, 153674 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/freetds-1-fastforward.patch	Tue Aug 17 20:55:16 2010 +0200
@@ -0,0 +1,153669 @@
+This file is part of mingw-cross-env.
+See doc/index.html for further information.
+
+Fast-forward to latest FreeTDS from cvs
+http://sourceforge.net/scm/?type=cvs&group.id=33106
+
+Produced with this script:
+#--------------------------------------------------------------------#
+#!/bin/bash
+
+(
+  echo "This file is part of mingw-cross-env."
+  echo "See doc/index.html for further information."
+  echo
+  echo "Fast-forward to latest FreeTDS from cvs"
+  echo "http://sourceforge.net/scm/?type=cvs&group.id=33106"
+  echo
+  echo "Produced with this script:"
+  echo "#--------------------------------------------------------------------#"
+  cat "$0"
+  echo "#--------------------------------------------------------------------#"
+) > src/freetds-1-fastforward.patch
+
+GITDIR=~/projects/freetds.dev/git-freetds
+PKGDIR=freetds-0.82
+
+# create or update clone
+#git cvsimport -v -d:pserver:anonymous@freetds.cvs.sourceforge.net:/cvsroot/freetds freetds
+
+rm -rf $PKGDIR
+tar xf pkg/$PKGDIR.tar.gz
+
+(
+  cd $GITDIR
+  git reset --hard
+  git checkout R0_82
+)
+
+lst="\
+  ChangeLog-0.82 \
+  INSTALL.CVS \
+  TODO.freddy \
+  configure.ac \
+  doc/htdoc/news.html \
+  doc/htdoc/faq.html \
+  doc/htdoc/contrib.html \
+  doc/htdoc/support.html \
+  doc/README.releasing \
+  doc/txt2man \
+  misc/freetds_autobuild \
+  misc/test-dist.sh \
+  misc/test-auto.sh \
+  misc/test-other.sh \
+  mkinstalldirs \
+  samples/odbc_rpc.pl \
+  src/pool/stream.c \
+  src/tds/alternative_character_sets.h \
+  src/tds/character_sets.h \
+  src/tds/encodings.pl \
+  src/tds/num_limits.pl \
+  src/tds/unittests/flags.c \
+  src/tds/tds_willconvert.pl \
+  src/odbc/unittests/rownumber.c \
+  src/odbc/checkexport.sh \
+  vms/Makefile.am \
+  win32/build_dsw.pl \
+  "
+
+lst="$lst $(cd $GITDIR && find -name .cvsignore)"
+
+for a in $lst; do
+   if [ -f $PKGDIR/$a ]; then
+       cp $PKGDIR/$a $GITDIR/$a
+   else
+       rm $GITDIR/$a
+   fi
+done
+
+# write reset patch
+(
+  cd $GITDIR
+  echo
+  echo "======== reset files to match 0.82 tag"
+  git diff -R R0_82 -- $lst
+) >> src/freetds-1-fastforward.patch
+
+(
+  cd $GITDIR
+  git reset --hard
+)
+
+# write rewind commits
+(
+  cd $GITDIR
+  echo
+  echo "======== climb down out of branch"
+  git log -R -p ^branch-0-82 R0_82
+  #git diff -R branch-0-82 R0_82
+) >> src/freetds-1-fastforward.patch
+
+
+(
+  cd $GITDIR
+  git checkout master
+  git reset --hard
+)
+
+# write fast forward commits
+(
+  cd $GITDIR
+  echo
+  echo "======== fast forward to latest"
+  git log --reverse -p ^branch-0-82 master
+  #git diff branch-0-82 master
+) >> src/freetds-1-fastforward.patch
+
+# check the results
+cat src/freetds-1-fastforward.patch \
+    | patch -d $PKGDIR -p1 -s 
+diff -x Makefile.in -rq $GITDIR $PKGDIR
+#--------------------------------------------------------------------#
+
+======== reset files to match 0.82 tag
+diff --git b/.cvsignore a/.cvsignore
+new file mode 100644
+index 0000000..d6098e5
+--- /dev/null
++++ a/.cvsignore
+@@ -0,0 +1,21 @@
++config.log
++config.cache
++config.status
++config.sub
++config.guess
++configure
++Makefile
++Makefile.in
++libtool
++ltmain.sh
++ltconfig
++ltcf-c.sh
++aclocal.m4
++autom4te.cache
++depcomp
++so_locations
++freetds.spec
++PWD
++doxyfile
++test-dist.log
++compile
+diff --git b/ChangeLog-0.82 a/ChangeLog-0.82
+new file mode 100644
+index 0000000..cc4cbea
+--- /dev/null
++++ a/ChangeLog-0.82
+@@ -0,0 +1,2289 @@
++Tue Jan  8 10:31:43 EST 2008	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am added freetds.conf.5
++	* src/dblib/bcp.c applied BCPKEEPIDENTIY patch 
++	- from Jonathan Olson <jpolsonaz@mac.com>
++
++Tue Jan  8 14:28:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS doc/README.releasing doc/userguide.sgml:
++	- updates for new release
++
++Tue Jan  8 10:33:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: relax for no-dm
++
++Mon Jan  7 19:32:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
++	- fix millisecond round off for TIMESTAMP
++	- improve genparams test to catch this problem
++	- make genparams works with MS ODBC
++
++Mon Jan  7 15:04:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdssrv.h src/server/login.c src/server/server.c:
++	* src/server/unittest.c:
++	- small improves
++	* src/pool/user.c: style update
++
++Sun Jan  6 11:48:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: even SQLExecDirect support parameters!
++	* src/odbc/unittests/genparams.c: improve
++
++Sat Jan  5 12:23:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c:
++	- add parameterized flag calling sp_cursoropen if needed
++
++Wed Jan  2 00:08:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/apps/Makefile.am:
++	- remove GNU style
++	* src/dblib/dblib.c: make it compile
++
++
++Mon Dec 31 15:05:16 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c fixed DBPRPAD, maybe
++
++Mon Dec 31 11:29:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh src/odbc/odbc.c:
++	- relax test for cursor
++
++Mon Dec 31 11:06:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c src/odbc/unittests/attributes.c:
++	* src/odbc/unittests/describecol.c src/tds/convert.c:
++	* src/tds/login.c src/tds/mem.c:
++	- minor signed/unsigned fixes
++	* src/dblib/bcp.c: minor performance improve
++	* src/dblib/dblib.c: fix date portability
++
++Fri Dec 28 17:57:08 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/token.c minor change
++	* src/tds/convert.c simpler tds_strftime
++	* src/dblib/unittests/done_handling.c no spurious messages
++
++Wed Dec 28 15:11:48 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: accepted patch #1854381
++
++Wed Dec 28 14:44:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild misc/test-other.sh:
++	- make amd64 works
++	* misc/test-auto.sh: add --help option
++	* src/tds/convert.c:
++	- fix overflow in tds_convert_char
++	- minor fixes for tds_strftime
++
++Thu Dec 27 14:43:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/.cvsignore: ignore autogenerated
++	* include/tds.h src/replacements/vasprintf.c src/tds/convert.c:
++	* src/tds/login.c src/tds/query.c src/tds/read.c:
++	- remove some warnings
++
++Thu Dec 27 11:20:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c: make unixODBC happy
++	* win32/config.h: define TDS_I64_FORMAT
++
++Thu Dec 27 10:19:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/buffering.h:
++	- remove warning if compiled with NDEBUG defined
++
++Wed Dec 26 21:57:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/attributes.c: make it works
++
++Wed Dec 26 19:44:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/freetds.conf.5: typo fix
++	* src/ctlib/unittests/common.c: make tests compile
++	* src/odbc/odbc.c: add diagnostic for truncate
++
++Tue Dec 25 00:55:02 EST 2007	JK Lowden <jklowden@freetds.org>
++	* freetds.conf doc/Makefile.am doc/freetds.conf.5 (added)
++	- shortened default freetds.conf and moved documentation
++	- to a proper man page.  Merry Christmas! 
++
++Mon Dec 24 11:34:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: removed unused fields
++
++Sun Dec 23 16:08:29 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c 
++	* src/ctlib/cs.c src/ctlib/unittests/common.c
++	* src/dblib/dblib.c
++	* src/tds/config.c src/tds/unittests/convert.c
++	- added STD_DATETIME_FMT to allow for WIN32 shortcomings
++
++Fri Dec 21 16:20:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/ct.c src/odbc/odbc.c src/tds/query.c:
++	- make odbc cursor test work using sp_cursoropen with parameters
++
++Fri Dec 21 11:38:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
++	* src/odbc/unittests/cursor5.c:
++	- cursor tests should work
++
++Fri Dec 21 10:05:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/replacements.h src/replacements/vasprintf.c:
++	* win32/config.h:
++	- applied modified patch #1848920
++
++Thu Dec 20 22:56:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/setnull.c src/dblib/unittests/thread.c:
++	- remove warnings
++
++Thu Dec 20 17:46:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- improve cursor attribute setting
++	- fix a small issue with unixODBC and 64 bit
++
++Wed Dec 19 16:08:17 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
++	- remove warnings
++
++Wed Dec 19 15:35:22 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/attributes.c(added) src/odbc/unittests/attributes.in(added):
++	* src/odbc/unittests/Makefile.am: add a test for statement attributes
++	* src/odbc/unittests/describecol.c: fix possible core
++
++Tue Dec 18 09:09:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/cursor3.c(added):
++	* src/odbc/unittests/cursor4.c(added) src/odbc/unittests/cursor5.c(added):
++	- merged test from Sebastien FLAESCH
++
++Sun Dec 16 19:08:38 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/api_status.txt 
++	- set useless db-lib functions' status to 'never'
++
++Sun Dec 16 16:58:35 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/bsqlodbc.txt doc/osql.txt
++	* doc/userguide.sgml
++	- updated for next release
++
++Fri Dec 14 11:23:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh: fix some strange echo portability
++	* src/dblib/unittests/null.c src/dblib/unittests/null2.c:
++	- make ignore less verbose
++
++Thu Dec 13 23:45:55 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am build bsqlodbc out-of-tree
++	* src/dblib/unittests/null.c prettier & correct, passes
++
++Thu Dec 13 21:12:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/buffering.h: fix null2
++
++Thu Dec 13 19:04:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/Makefile.am:
++	- fix bsqlodbc compile if not standard sql.h path
++
++Wed Dec 12 07:27:07 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: fix for 64bit
++
++Tue Dec 11 11:09:52 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: remove warning
++	* misc/freetds_autobuild: fix if password empty
++
++Tue Dec 11 00:02:16 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml minor touchups 
++	* src/dblib/dblib.c src/dblib/unittests/setnull.c
++	- unittests/setnull.c passes.
++
++Mon Dec 10 14:05:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: remove warning
++
++Mon Dec 10 00:08:45 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/userguide.sgml some improvements
++	doc/grep_sample_code doc/images/caution.gif 
++	doc/images/warning.gif
++	doc/images/callouts/1.gif doc/images/callouts/2.gif
++	doc/images/callouts/3.gif doc/images/callouts/4.gif
++	doc/images/callouts/5.gif doc/images/callouts/6.gif
++	doc/images/callouts/7.gif doc/images/callouts/8.gif
++	doc/images/callouts/9.gif doc/images/callouts/10.gif
++	- added from http://tldp.org/LDP/abs/images/
++
++Sun Dec  9 19:51:11 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml added tenderfoot tutorial
++
++Fri Dec  7 00:26:01 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/dblib/dblib.c
++	* src/dblib/dbutil.c src/tds/util.c
++	- pass errno via tdserror.  
++
++Thu Dec  6 21:41:23 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/convert.c tds_willconvert returns size
++
++Thu Dec  6 21:32:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix for 64bit machines
++	* src/dblib/unittests/setnull.c: improve
++
++Thu Dec  6 19:59:59 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/replacements.h src/apps/bsqldb.c:
++	* src/dblib/unittests/setnull.c:
++	- use basename from MingW if available
++	* src/dblib/dblib.c: fix malloc portability problem
++
++Thu Dec  6 10:18:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/rpc.c src/dblib/unittests/setnull.c:
++	- fix compile problems
++
++Thu Dec  6 01:00:42 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/buffering.h src/dblib/dblib.c:
++	- dbgetnull tolerates negative varlen, looks pretty good
++
++Wed Dec  5 10:38:55 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c:
++	- t0011 passes but copy_data_to_host_var likely wrong
++
++Tue Dec  4 20:19:38 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/buffering.h src/dblib/dblib.c:
++	- removed _db_set_null and associated mallocs
++	- dblib/unittest/t0011.c failing mysteriously
++
++Mon Dec  3 23:18:55 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c src/dblib/unittests/setnull.c:
++	- corrected dbsetnull()
++
++Mon Dec  3 18:45:22 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/unittests/rpc.c
++	* src/dblib/unittests/setnull.c src/dblib/unittests/t0001.c
++	* src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c
++	* src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c
++	* src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c
++	* src/dblib/unittests/t0008.c src/dblib/unittests/t0011.c
++	* src/dblib/unittests/t0015.c src/dblib/unittests/t0018.c
++	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c
++	* src/dblib/unittests/thread.c src/dblib/unittests/timeout.c:
++	- dbbind uses zero, not -1 to indicate sufficient space.  
++
++Mon Dec  3 17:57:54 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c: don't cast malloc and don't assume it worked. 
++
++Mon Dec  3 19:54:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/Makefile.am: remove GNU make pattern
++
++Mon Dec  3 15:35:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c:
++	- do not call dbcolptr for compute result but call new dbacolptr
++	- dbcolptr return TDSCOLUMN* to optimize it
++
++Mon Dec  3 11:53:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: remove a warning
++
++Mon Dec  3 10:18:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/dblib/unittests/.cvsignore:
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/setnull.c(added):
++	- add a test for setnull
++
++Sun Dec  2 17:58:40 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/api_status.txt
++	* include/dblib.h include/sybdb.h include/tds.h
++	* src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c
++	- full implementation of dbsetnull().
++	- Replaced _DB_GETCOLINFO macro with dbcolptr(). 
++
++Sat Dec  1 14:05:54 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/unittests/null.c
++	- correct TDS 5.0 bcp offset table calcuation in presence of NULLs.
++
++Fri Nov 30 09:54:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: missing new line
++
++Thu Nov 29 09:03:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/null2.c: improve
++
++Wed Nov 28 15:15:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac:
++	- include windows.h under windows
++	- include sql.h directly to avoid MingW problems
++	* include/dblib.h src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
++	- avoid core checking for parameters if argument are expected
++	* src/dblib/unittests/null.c src/dblib/unittests/null2.c:
++	- avoid invalid references to deallocated stack
++
++Wed Nov 28 09:48:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: remove warnings
++
++Wed Nov 28 00:27:36 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c fixed TDS 5.0 null-column bug, cf. ML
++	* doc/tds.html Added BCP, made 4.01 strict, validated. 
++
++Tue Nov 27 16:12:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/null2.c(added):
++	- test dbbind/dbnullbind with NULLs
++	* src/dblib/unittests/null.c: add note
++
++Tue Nov 27 13:37:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0022.c:
++	- compile with Sybase libraries
++	* src/dblib/unittests/t0008.c: more verbose
++
++Mon Nov 26 21:02:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array_out.c: fix silly core
++
++Mon Nov 26 19:11:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tdsodbc.h src/odbc/odbc.c:
++	* src/odbc/unittests/array_out.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/describecol.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/insert_speed.c src/odbc/unittests/timeout.c:
++	* src/odbc/unittests/timeout3.c src/odbc/unittests/type.c:
++	- minor fixes for 64bit
++
++Mon Nov 26 16:47:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/apps/fisql/fisql.c:
++	- do not use functions not availables
++
++Mon Nov 26 09:43:03 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/tds/unittests/iconv_fread.c
++	- small changes
++
++Mon Nov 26 09:51:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/bcp.c: fix printf
++
++Mon Nov 26 07:24:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
++	* src/odbc/unittests/const_params.c src/odbc/unittests/cursor1.c:
++	* src/odbc/unittests/describecol.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/insert_speed.c src/odbc/unittests/raiserror.c:
++	* src/odbc/unittests/rpc.c src/odbc/unittests/scroll.c:
++	* src/tds/challenge.c:
++	- fix minor issues with 64bit
++
++Thu Nov 22 09:43:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/ctlib/Makefile.am src/dblib/Makefile.am:
++	* src/odbc/Makefile.am:
++	- do not filter symbols under MacOsX (avoid libtool problems)
++
++Wed Nov 21 11:31:37 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/blk.c: correctly test result of cs_convert
++	* src/dblib/rpc.c: minor edits
++	* src/dblib/unittests/bcp.c src/dblib/unittests/bcp.h:
++	- test works for TDS 7.0.
++
++Tue Nov 20 23:08:15 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/unittests/bcp.c:
++	* src/dblib/dblib.c src/tds/convert.c src/tds/net.c:
++	- small changes
++
++Thu Nov 15 14:32:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/.cvsignore src/dblib/dblib.c:
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/null.c:
++	- fix problem with empty string and TEXT
++	- add a test to test empty/NULL behavior of dbdatlen/dbdata
++
++Thu Nov 15 10:18:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: return error if no username given and no Kerberos
++
++Tue Nov 13 10:13:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/challenge.c src/tds/gssapi.c:
++	* src/tds/login.c src/tds/token.c:
++	- port ntlm to new authentication code
++	- move all ntlm stuff to challenge.c
++
++Mon Nov 12 17:15:03 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h src/dblib/bcp.c
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/dblib/rpc.c
++	* src/tds/log.c src/tds/login.c
++	- trying to convince Doxygen not to ignore functions, 
++	- e.g. dbinit 
++
++Mon Nov 12 13:38:04 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/dbutil.c
++	* src/dblib/dblib.c src/dblib/rpc.c src/dblib/bcp.c
++	- added DBDEAD test to all public functions
++
++Mon Nov 12 14:32:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac: cleanup
++	* src/tds/gssapi.c: compute fqdn name in service name
++
++Mon Nov 12 12:34:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds.h src/tds/gssapi.c:
++	* src/tds/login.c src/tds/mem.c src/tds/token.c:
++	- new TDSAUTHENTICATION structure
++	- new --enable-krb5 to enable Kerberos authentication
++	  (disable by default)
++
++Fri Nov 09 11:29:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: remove some leaks
++
++Mon Nov 05 11:05:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: use pipes to avoid infinite counter
++
++Mon Nov 05 09:29:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: fix log avoidance for long logins
++
++Sun Nov 04 09:16:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/gssapi.c: small cleanup
++
++Sat Nov 03 14:31:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/config.c src/tds/mem.c:
++	- add server_host_name to TDSCONNECTION
++	* src/tds/gssapi.c: some improves
++
++Fri Nov 02 11:33:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/gssapi.c: add small comment
++
++Tue Oct 30 16:45:41 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am src/tds/gssapi.c src/tds/login.c:
++	- include developing code for GSSAPI
++
++Tue Oct 30 16:36:29 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/login.c src/ctlib/ct.c src/tds/read.c:
++	* src/tds/token.c:
++	- finish merging tds9 code as developing
++
++Tue Oct 30 16:02:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- make odbc row_count 64bit
++
++Tue Oct 30 13:14:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c src/tds/query.c:
++	- more merge for tds9
++
++Tue Oct 30 11:31:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c:
++	* src/server/server.c src/tds/token.c:
++	- merge partially tds9 patch
++
++Tue Oct 30 11:15:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- avoid wrong assert if error and tdserror called
++	* src/tds/query.c: limit data length to maximun allowed
++
++Wed Oct 24 17:55:56 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* include/sqldb.h define dbfreelogin
++	* src/dblib/unittests/common.h add commentary
++
++Tue Oct 23 19:41:03 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/net.c src/tds/util.c
++	- ct-lib seems OK with EINTR (sqsh works) but db-lib
++	- applications get a weird message. 
++
++Tue Oct 23 18:08:00 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/net.c 
++	- return from tds_select as if timed out on EINTR. 
++	- sqsh still unhappy when ^C pressed on long-running query. 
++
++Thu Oct 18 16:48:23 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix core
++
++Thu Oct 18 13:49:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c src/tds/token.c:
++	- more free(NULL)
++
++Tue Oct 16 16:59:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c src/ctlib/blk.c src/ctlib/cs.c src/ctlib/ct.c:
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
++	* src/dblib/unittests/rpc.c src/odbc/error.c src/odbc/odbc.c:
++	* src/odbc/sql2tds.c src/odbc/unittests/binary_test.c:
++	* src/pool/config.c src/tds/locale.c src/tds/login.c:
++	* src/tds/mem.c src/tds/query.c src/tds/token.c:
++	* src/tds/vstrbuild.c src/tds/unittests/dataread.c:
++	- do not check for free(NULL)
++
++Wed Oct 10 13:59:37 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c 
++	- added some error checking for malloc/realloc, more needed
++
++Tue Oct 09 13:40:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: fix small memory leak
++
++Mon Sep 24 13:12:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: limit size preparing queries
++
++Mon Sep 24 12:01:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/server/query.c src/server/server.c:
++	- small server improve
++
++Thu Sep 20 17:32:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/sybdb.h src/dblib/dblib.c src/dblib/dbopen.c:
++	- apply constify patch #1786200
++
++Thu Sep 20 17:02:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: do not strip empty lines
++
++Mon Sep 17 17:22:32 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c correct freebcp -L behavior 
++	* src/tds/net.c TDSECONN on no socket failure 
++	* src/tds/util.c change iconv messages
++
++Mon Sep 17 17:52:09 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update for tds9
++	* src/server/login.c: remove warning
++
++Mon Sep 17 12:13:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c:
++	- improve for very large query (from 9.2 to 0.3 seconds on my 
++	  test machine)
++
++Mon Sep 17 10:42:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update
++	* src/ctlib/unittests/get_send_data.c: small fix
++	* include/sybdb.h src/dblib/dblib.c src/dblib/unittests/t0022.c:
++	- small update for future tds9
++	* src/pool/main.c src/pool/user.c src/server/login.c:
++	- improve portability and possible remote leakage
++
++Thu Sep 13 12:42:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c:
++	- make it works even if login is quite long
++
++Thu Sep 13 08:57:26 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/dynamic1.c: use tds_set_param_type
++
++Thu Sep 06 13:15:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update for tds9
++	* src/tds/read.c: work if initial in_pos is != 0
++
++Sat Aug 25 12:32:01 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
++	- use ODBC_API instead of SQL_API to allow combined compile
++
++Fri Aug 24 11:50:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/login.c:
++	* src/tds/query.c src/tds/token.c:
++	- small changes for TDS 9.0
++
++Mon Aug 16 10:09:42 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/Makefile.am src/tds/net.c:
++	* src/tds/unittests/Makefile.am:
++	- remove other warnings
++
++Mon Aug 16 08:29:38 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/convert.c win32/initnet.c:	
++	- remove some warnings compiling with MingW
++
++Sat Aug 11 08:51:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c vms/config_h.vms vms/descrip_mms.template:
++	- applied Craig A. Berry patch #1772080 for VMS systems
++
++Fri Aug 10 11:17:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS: updated
++
++Fri Aug 10 11:14:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/dev-cpp/Makefile.win: add missing file
++
++Thu Aug 09 14:52:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: small fixes
++
++Thu Aug 09 10:26:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: document port override syntax
++
++Thu Aug 09 09:49:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/htdoc/basic_jdbc_question.html doc/htdoc/contrib.html:
++	* doc/htdoc/docs.html doc/htdoc/index.html doc/htdoc/news.html:
++	* doc/htdoc/software.html doc/htdoc/support.html:
++	* doc/htdoc/vague_jdbc_question.html doc/htdoc/which_api.html:
++	- make xhtml compatible
++
++Wed Aug 08 15:24:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/Makefile.am win32/version.rc.in:
++	- fix odbc cross compile using MingW
++
++Wed Aug 08 11:34:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild:
++	- improved adding test for server:port and server\instance case
++
++Wed Aug 08 11:10:36 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: fix bug #1759652 (cannot use server\INSTANCE)
++
++Tue Aug 07 15:34:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: improve cursor updates
++	* src/odbc/unittests/cursor1.c: improved and fixed
++
++Tue Aug 07 11:55:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: use table name for update
++
++Tue Aug 07 11:19:33 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/odbc.c src/odbc/unittests/getdata.c:
++	- fix bug #1758831
++	- additional fixes and checks for SQLGetData
++
++Tue Aug 07 10:29:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: update links
++
++Fri Aug 03 13:15:42 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: lookup server name correctly for instances
++
++Thu Aug 02 13:31:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/sqlfront.h: small compatiblity improve with ms
++
++Fri Jul 13 18:56:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/getdata.c: portability fix
++
++Thu Jul 12 16:31:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix for SQLGetData using empty fields
++	* src/odbc/unittests/getdata.c:
++	- improve test to catch previous problem
++
++Sat Jul 07 19:55:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/sprintf_i64_format.m4: improve portability
++
++Sat Jul 07 19:09:59 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- check cbValueMax in SQLGetData even if DM present
++
++Tue Jul 03 17:12:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/compute.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/typeinfo.c:
++	- relax test for Sybase
++	* src/tds/token.c: fix length computation
++
++Tue Jul 03 15:37:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c:
++	* src/odbc/odbc.c src/tds/mem.c src/tds/token.c:
++	- add table_column_name to read real column name (if available),
++	  read from wire and use when needed
++
++Sun Jul 01 12:10:31 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsstring.h src/odbc/connectparams.c:
++	* src/odbc/descriptor.c src/odbc/odbc.c src/tds/config.c:
++	* src/tds/tdsstring.c:
++	- added tds_dstr_dup to duplicate DSTR
++	- use tds_dstr_dup
++	- improve tds_dstr_set
++
++Wed Jun 27 16:51:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: add Column Info token
++	* src/odbc/unittests/timeout2.c: portability fix
++
++Mon Jun 25 11:47:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/api_status.txt include/cspublic.h include/ctlib.h:
++	* src/ctlib/cs.c src/ctlib/ct.c:
++	- applied patch #1729392, it adds support for ctlib locale
++
++Mon Jun 25 10:20:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: review cursors
++
++Thu Jun 21 09:19:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: test for Sybase 15
++	* src/odbc/unittests/data.c: bigint for Sybase
++	* src/tds/data.c src/tds/mem.c src/tds/read.c src/tds/tds_checks.c:
++	- add support for Sybase bigint
++	- do not check decault capabilities if not necessary
++
++Tue Jun 19 15:30:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/ct.c src/odbc/odbc_util.c:
++	* src/pool/stream.c src/tds/data.c src/tds/net.c:
++	* src/tds/tds_checks.c src/tds/tds_checks.h src/tds/token.c:
++	- fix problem with Sybase LONGCHAR
++
++Tue Jun 19 14:06:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/t0007.c src/odbc/unittests/prepare_results.c:
++	- more verbose
++	- fix for possible Sybase conversion
++	* src/odbc/odbc.c: additional check if no dm
++
++Mon Jun 18 15:20:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c:
++	- patch #1736289 for bcp/bulk insert problem
++
++Mon Jun 18 14:02:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c src/tds/locale.c:
++	- use correct charset based on locale
++
++Mon Jun 18 13:58:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: remove warning
++
++Sun Jun 17 19:38:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c src/odbc/unittests/timeout3.c:
++	- fix small thread problem
++	- fix possible deadlock
++
++Sun Jun 17 09:45:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c src/odbc/unittests/genparams.c:
++	- fix thread and small portability
++
++Sun Jun 17 09:08:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/dblib.h src/dblib/buffering.h src/dblib/dblib.c:
++	- patch #1717123 for dbsetnull implementation (removed warnings)
++
++Sun Jun 17 08:16:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c:
++	- patch #1703363 for delimiters (modified)
++
++Wed Jun 13 09:26:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/fisql/fisql.c: compile even if readline is not available
++
++Mon Jun  4 17:09:03 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am skip bsqlodb if ODBC disabled
++
++Mon Jun 04 10:03:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/.cvsignore src/dblib/unittests/Makefile.am:
++	* src/dblib/unittests/hang.c(added) src/tds/net.c:
++	- fix problem with tds_select (detected by Perception Technologies)
++
++Fri Jun 01 10:52:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: avoid overflow leading to memory errors
++
++Thu May 31 17:02:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- fixes, partially from Brent of Perception Technologies Ltd
++
++Thu May 31 10:54:14 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* TODO add recent potential bug reports
++
++Thu May 31 14:21:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/ac_nullzero.m4: fix cross compile test
++
++Wed May 30 09:55:52 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/threadsafe.c:
++	- implement gethostbyname_r with getaddrinfo (for UnixWare 7 and others)
++
++Tue May 29 10:48:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac win32/config.h: cleanup
++
++Fri May 25 11:07:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c:
++	- remove a FIXME
++	* src/odbc/odbc.c:
++	- fix bug #1716594 ("SQLFreeStmt with SQL_CLOSE shouldn't 
++	  unprepare statement")
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/freeclose.c(added)
++	* src/odbc/unittests/.cvsignore:
++	- add a test for bug #1716594
++
++Mon May 21 14:01:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- fix cursor updates, this undo part of change of src/odbc/odbc.c
++	  from 1.331 to 1.332, log:
++	  Wed Jul 21 16:50:11 CET 2004
++	   : some fix for SQLFetch and multiple rows
++	  but tests works
++	* src/odbc/unittests/cursor1.c: improve
++
++Mon May 21 10:40:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c: improve test
++
++Thu May 17 12:32:33 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_checks.c:
++	* src/odbc/odbc_util.c:
++	- avoid core
++	- fix and check invalid values of num_param_rows and curr_param_row
++
++Thu May 17 09:18:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/warning.c: improve and comments
++
++Wed May 16 14:23:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	* src/odbc/sql2tds.c:
++	- support row binding in RPC
++	- reuse new odbc_get_octet_len
++
++Wed May 16 14:23:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: minor updates
++
++Mon May 14 16:04:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: remove copy error
++
++Mon May 14 10:16:37 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c src/tds/mem.c src/tds/token.c src/tds/util.c:
++	- give proper errors on protocol autodiscovery
++
++Wed May 09 10:31:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: finish ODBC timeout
++
++Fri May 03 14:54:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/const_params.c:
++	- reset statement to be sure to cleanup
++
++Wed May 02 16:54:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- use query timeout from freetds.conf
++
++Mon Apr 30 15:14:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: use default linkage for static functions
++
++Mon Apr 30 15:02:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c: fix strange link error using gcc 4.1
++
++Mon Apr 23 09:56:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: fix portability issue
++
++Fri Apr 20 15:26:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
++	* src/odbc/unittests/scroll.c:
++	- make valgrind more happy if Sybase is used
++
++Fri Apr 20 11:13:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/timeout4.c(added):
++	- add a test for timeout
++	- fix timeout on prepare (not detected)
++	- fix timeout if connection broken
++
++Thu Apr 19 11:11:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
++	* src/odbc/unittests/scroll.c:
++	- give only warning for Sybase
++
++Thu Apr 19 10:45:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- say we not still support cursors for sybase
++
++Wed Apr 18 16:28:29 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy include/tdsodbc.h src/odbc/odbc.c:
++	* src/odbc/odbc_util.c src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- fix cursor updates
++
++Mon Apr 16 22:08:07 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqlodbc.c ODBC3 conformant 
++
++Sun Apr 15 10:01:36 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix leak
++
++Fri Apr 13 17:27:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: cursor update
++
++Fri Apr 13 17:22:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/query.c:
++	- add cursor update to libTDS
++
++Fri Apr 13 10:08:07 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c:
++	- catch all error
++	- fix some memory problems
++
++Thu Apr 12 15:33:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/funccall.c:
++	- add test from ML
++
++Thu Apr 12 15:07:09 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* freetds.spec.in: fix odbc directory
++	* src/dblib/unittests/Makefile.am: fix for make distcheck
++	* src/odbc/unittests/raiserror.c src/odbc/unittests/warning.c:
++	- relax if dm used
++
++Thu Apr 12 09:47:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/copydesc.c:
++	- test and fix a problem with SQLAllocHandle
++	* src/odbc/unittests/connect2.c: add test for not existing dbs
++
++Thu Apr 12 09:05:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/array_bind.c src/ctlib/unittests/ct_diagall.c:
++	* src/ctlib/unittests/ct_diagclient.c:
++	- fix buffer overflow leading in core
++
++Wed Apr 11 14:55:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/odbc/unittests/common.c:
++	- remove warning compiling with MingW
++
++Wed Apr 11 13:52:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c src/odbc/odbc.c:
++	* src/odbc/unittests/connect2.c:
++	- finish and fix test for change_database
++
++Wed Apr 11 11:47:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/connect2.c: fix test
++	* src/odbc/unittests/describecol.in: relax test
++
++Wed Apr 11 09:09:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/connect2.c src/odbc/unittests/Makefile.am:
++	- add a test for change_database
++
++Tue Apr 10 16:00:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	- fixes for describecol test
++
++Tue Apr 10 15:16:28 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/coverage.sh: remove system files
++	* src/odbc/unittests/describecol.in: relax test
++
++Fri Apr 06 10:52:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdssrv.h src/server/login.c src/server/unittest.c:
++	- remove warning
++
++Fri Apr 06 10:29:31 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS src/odbc/unittests/funccall.c src/tds/mem.c:
++	* src/tds/query.c:
++	- added some notes
++
++Thu Apr 05 16:16:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* INSTALL INSTALL.CVS NEWS README doc/userguide.sgml:
++	- merge from 0.64
++
++Wed Apr 04 13:39:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS: updated
++
++Wed Apr 04 11:53:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h include/tdsodbc.h src/ctlib/ct.c src/dblib/rpc.c:
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c src/tds/mem.c:
++	* src/tds/token.c src/tds/unittests/dynamic1.c:
++	- removed unused paramter from tds_alloc_param_data
++	- fix possible problem in prepare_rpc
++
++Wed Apr 04 11:39:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* vms/descrip_mms.template: add log.c
++	* src/server/query.c: use constants
++
++Wed Apr 04 09:14:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: improve slow check
++
++Tue Apr 03 16:23:17 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/dev-cpp/FreeTDS.dev win32/dev-cpp/Makefile.win:
++	- updated adding log.c
++
++Mon Apr 02 17:06:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: add encryption parameter
++
++Thu Mar 29 16:32:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c: initial fix for bcp state
++
++Thu Mar 29 16:25:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/server/login.c src/tds/config.c:
++	* src/tds/login.c:
++	- added encryption setting in freetds.conf
++
++Thu Mar 29 12:17:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac: check includes for ODBC
++
++Thu Mar 29 09:44:11 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: add test for money
++
++Wed Mar 28 14:43:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* freetds.spec.in src/odbc/unittests/Makefile.am:
++	- fix test-dist test
++
++Mon Mar 26 13:27:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/.cvsignore src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	* win32/build_dsw.pl:
++	- distribute projects for vc6 unittests
++
++Mon Mar 26 10:05:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/htdoc/news.html: validate page
++
++Sun Mar 24 09:23:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c:
++	- avoid dangerous casts
++
++Tue Mar 20 16:24:26 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/gettimeofday.c src/apps/datacopy.c:
++	- remove warning
++
++Mon Mar 19 11:01:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/replacements.h: fix warning for win32
++
++Sun Mar 18 12:37:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/odbc/unittests/timeout2.c:
++	* src/odbc/unittests/timeout3.c:
++	- fix cross-compile for win32
++
++Sun Mar 18 12:09:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/Makefile.am 	src/apps/bsqlodbc.c src/apps/tsql.c:
++	* src/apps/fisql/Makefile.am 	win32/winsetup.c:
++	- fix cross-compile for win32
++
++Fri Mar 16 16:32:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/Makefile.am src/tds/Makefile.am:
++	- full libTDS privatization
++	* src/server/unittest.c: use mnemonic
++
++Wed Mar 14 17:18:23 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update
++	* include/tdssrv.h src/pool/user.c src/server/login.c:
++	* src/server/query.c src/server/server.c src/server/unittest.c:
++	- update server stuff, at least login works
++	* src/tds/tdsstring.c: fix possible mising NUL terminator
++	* src/apps/tsql.c: fix wrong error handler result
++
++Wed Mar 14 09:47:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html include/tds.h: update documentation
++
++Tue Mar 13 17:24:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/pool/user.c src/server/login.c:
++	* src/server/unittest.c src/tds/login.c src/tds/query.c:
++	- use mnemonic for packet types
++
++Tue Mar 13 16:45:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: added known tokens
++
++Tue Mar 13 14:18:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: updated from code
++
++Mon Mar 12 14:27:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/ctlib.h include/dblib.h include/des.h include/md4.h:
++	* include/md5.h include/replacements.h include/tdsiconv.h:
++	* include/tdsstring.h include/replacements/readpassphrase.h:
++	* src/server/Makefile.am:
++	- privatize functions using gcc visibility if available
++	- privatize server library
++
++Mon Mar 12 13:31:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/blk_in2.c(added) src/ctlib/unittests/Makefile.am:
++	- added test from ML to test cancel and bulk together
++
++Mon Mar 12 10:52:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: improved, added types
++
++Fri Feb 16 14:52:10 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: improve documentation
++
++Mon Feb 12 14:29:53 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: Increase size of dbprrow() conversion buffer to 8K.
++
++Mon Feb 12 10:53:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/timeout3.c:
++	- use thread instead of fork
++
++Wed Feb  7 01:11:27 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqlodbc.c don't exit on SQL_SUCCESS_WITH_INFO
++
++Wed Feb  7 00:04:15 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c exit noisily on severe errors
++	* src/dblib/dblib.c src/tds/token.c 
++	- fix timeout with buffering problem per yesterday's ML. 
++
++Tue Feb  6 17:14:50 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- Sybase docs for dbsqlok() says: "If the command buffer contains
++	  multiple commands, a run-time error will not cause dbsqlok to
++	  fail.  Instead, failure will occur with the dbresults call that
++	  processes the command causing the run-time error."
++	* src/apps/fisql/fisql.c:
++	- Correct result set processing.
++	
++Tue Feb  6 14:11:02 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: Don't print or store column separator after final result column
++
++Tue Feb 06 10:18:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/Makefile.am:
++	- use -module option only for darwin
++
++Tue Feb 06 09:53:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c:
++	- make more functions static
++	- remove warning
++	* src/tds/net.c: remove warning
++
++Mon Feb  5 21:48:58 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am src/apps/bsqlodbc.c src/apps/osql
++	- added bsqlodbc as general batch script processor. 
++
++Mon Feb 05 09:41:02 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh phptests/null.php:
++	- fixed PHP check, updated test to PHP 5.2
++
++Fri Feb 02 11:51:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/timeout3.c(added):
++	- added a test for connection timeout
++	- fix timeout connection in odbc
++
++Mon Jan 29 12:02:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/apps/fisql/fisql.c:
++	* src/tds/net.c:
++	- remove some warnings
++
++Fri Jan 26 18:19:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/fisql/fisql.c:
++	- remove warning
++	- reuse malloc
++	- fix compile error including config.h
++	* src/dblib/dblib.c: remove warning
++
++Fri Jan 26 18:06:44 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/error.c src/odbc/odbc.c:
++	- remove warning compiling
++
++Wed Jan 24 14:14:55 EST 2007	Nick Castellano <entropy@freetds.org>
++	* doc/fisql.txt: compute rows in fisql work now, remove BUGS entry
++
++Wed Jan 24 14:11:56 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: indent
++
++Wed Jan 24 14:08:09 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: good enough compute layout
++
++Wed Jan 24 12:24:30 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: almost correct compute layout
++
++Wed Jan 24 11:32:56 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: minor compute layout fixes, still more to do
++
++Tue Jan 23 17:15:33 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: better compute results, layout needs fixing
++
++Tue Jan 23 11:24:40 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: fix off-by-one bug in dbbylist()
++
++Mon Jan 22 15:54:02 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: fix :r with unreadable file
++
++Mon Jan 22 15:50:31 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: print line separator after compute results
++
++Mon Jan 22 00:56:12 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/odbc/connectparams.c src/odbc/error.c
++	* src/odbc/odbc.c
++	- added log entry for API functions
++	* src/odbc/unittests/common.c always use '/' separator
++
++Sat Jan 20 15:24:03 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h include/sybdb.h src/dblib/dblib.c
++	- moved DBOPTION to dblib.h and removed unused members.
++
++Sat Jan 20 01:29:36 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/defncopy.txt doc/fisql.txt cleanup formatting
++	* src/apps/bsqldb.c src/dblib/dblib.c fix compute row headers
++
++Sat Jan 20 01:30:22 EST 2007	Nick Castellano <entropy@freetds.org>
++	* ChangeLog src/apps/fisql/edit.c src/apps/fisql/edit.h
++	* src/apps/fisql/fisql.c src/apps/fisql/handlers.c
++	* src/apps/fisql/handlers.h src/apps/fisql/interrupt.c
++	* src/apps/fisql/interrupt.h src/apps/fisql/terminal.c
++	* src/apps/fisql/terminal.h:
++	- Fix my name and the program name
++
++Sat Jan 20 01:20:39 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: 
++	- Be slightly less stupid about compute rows.
++
++Sat Jan 20 00:54:57 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- do not return bogus nul character in dbgetchar()
++
++Sat Jan 20 00:35:45 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- dbspr*() functions get nul termination not line termination
++	
++Fri Jan 19 22:39:00 EST 2007	Nick Castellano <entropy@freetds.org>
++	* doc/fisql.txt: restore compute rows BUGS entry.
++
++Fri Jan 19 14:05:13 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: 
++	- Provide xmalloc() and xrealloc() instead of relying on
++	  libreadline for these.
++	
++Fri Jan 19 13:47:42 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/Makefile.am
++	* src/apps/fisql/fisql.c
++	* src/apps/fisql/xgetpass.c(removed)
++	* src/apps/fisql/xgetpass.h(removed):
++	- use readpassphrase() in fisql application.
++
++Fri Jan 19 13:31:31 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/edit.c src/apps/fisql/fisql.c
++	* src/apps/fisql/handlers.c src/apps/fisql/handlers.h
++	* src/apps/fisql/interrupt.c src/apps/fisql/interrupt.h
++	* src/apps/fisql/terminal.c src/apps/fisql/terminal.h
++	* src/apps/fisql/xgetpass.c:
++	- Indent fisql to standard FreeTDS coding style
++
++Fri Jan 19 13:19:04 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: remove obsolete code
++
++Fri Jan 19 13:12:56 EST 2007	Nick Castellano <entropy@freetds.org>
++	* doc/fisql.txt: fisql now works, update doc
++
++Fri Jan 19 13:01:53 EST 2007	Nick Castellano <entropy@freetds.org>
++	* .cvsignore doc/.cvsignore: clean up
++
++Fri Jan 19 12:45:27 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: fix dbspr1row(), fisql now works
++
++Fri Jan 19 11:17:13 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/fisql.txt
++	* src/apps/fisql/edit.c src/apps/fisql/edit.h
++	* src/apps/fisql/handlers.c src/apps/fisql/handlers.h
++	* src/apps/fisql/interrupt.c src/apps/fisql/interrupt.h
++	* src/apps/fisql/terminal.c src/apps/fisql/terminal.h
++	* src/apps/fisql/xgetpass.c src/apps/fisql/xgetpass.h
++	* src/apps/fisql/fisql.c
++	- Added notice of copyright and GPL license
++
++Thu Jan 18 23:55:17 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/fisql.txt added man page for fisql
++	* src/apps/fisql/fisql.c fixed discarding const warnings
++	* doc/api_status.txt include/sybdb.h src/dblib/dblib.c
++	-  added dbgettime()
++
++Thu Jan 18 17:57:52 EST 2007	Nick Castellano <entropy@freetds.org>
++	* AUTHORS: credit myself as a contributor
++
++Thu Jan 18 17:50:18 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- fix dbprrow() to print character data correctly
++	- fix dbprrow() to not loop endlessly on aggregate rows
++
++Thu Jan 18 08:57:10 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/utf8_2.c: fix error handler
++
++Wed Jan 17 09:48:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/fisql/fisql.c: use mkstemp instead of mktemp
++	* src/tds/util.c: cleanup
++
++Tue Jan 16 16:30:42 EDT 2007	Nick Castellano <entropy@freetds.org>
++	* configure.ac
++	* src/apps/Makefile.am
++	* src/apps/fisql: contribute free DB-Libary isql application
++
++Tue Jan 16 09:57:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/util.c: fix messages
++
++Tue Jan 16 09:48:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh: fix problem with Perl 5.8.8
++	* src/dblib/dblib.c: fix possible thread problem
++
++Tue Jan 16 00:28:28 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/bcp.c
++	* src/dblib/dblib.c src/dblib/unittests/rpc.c
++	- support variadic form of dbperror
++
++Mon Jan 15 14:40:35 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/common.c
++	* src/dblib/unittests/rpc.c
++	* src/dblib/unittests/t0004.c
++	* src/dblib/unittests/t0005.c
++	* src/dblib/unittests/t0007.c
++	* src/dblib/unittests/t0019.c
++	* src/dblib/unittests/t0020.c
++	- fail if an unanticipated message/error is received
++
++Sun Jan 14 23:16:17 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/config.c src/tds/login.c
++	- began work on autodetecting the server's TDSVER
++	- works with libtds, not db-lib
++
++Sun Jan 14 20:38:25 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h include/tds.h
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0012.c
++	* src/dblib/unittests/timeout.c
++	* src/tds/net.c TODO
++	- timeout unit test also works with dbsetinterrupt
++
++Sat Jan 13 17:09:05 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/timeout.c added 
++	* src/dblib/dblib.c 
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/t0001.c
++	* src/tds/login.c src/tds/query.c src/tds/util.c
++	- new timeout unit test works. 
++
++Fri Jan 12 14:28:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: update code to new libTDS timeout code
++	* src/tds/net.c: handle send/recv errors
++	* src/tds/util.c: fix msgno if error not found in table
++
++Thu Jan 11 10:49:52 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql 
++	- fixed incorrect report when drivername is not a file
++
++Tue Jan 09 22:44:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: fix option problem
++
++Tue Jan  9 00:16:46 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* src/tds/net.c simpler tds_select, thanks Frediano
++
++Sun Jan  7 10:45:23 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* src/ctlib/ctutil.c works with tdserror()
++
++Sun Jan  7 00:41:19 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* include/tds.h
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/tds/net.c src/tds/query.c
++	* src/tds/token.c src/tds/util.c
++	- implement new timeout strategy using tds_select() and 
++	- calling the client library's error handler (via tdserror). 
++	- db-lib no worse than before, others not yet tested. 
++
++Fri Jan 05 14:08:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/token.c: new token
++	* src/tds/util.c: optimize
++
++Fri Jan  5 02:08:54 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* include/tds.h src/tds/net.c src/tds/util.c
++	- begin new timeout strategy, not done.
++
++Thu Jan  4 18:47:46 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/bsqldb.txt src/apps/bsqldb.c nicer headers
++	* doc/osql.txt src/apps/osql allow ini location override
++
++Tue Jan  2 15:42:09 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* include/dblib.h include/tds.h
++	* src/apps/tsql.c
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/tds/iconv.c src/tds/login.c src/tds/net.c
++	* src/tds/token.c src/tds/util.c
++	- replace tds_client_msg with tdserror()
++
++Mon Jan 01 12:56:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/tds/query.c:
++	- remove some warning compiling with SUN compiler
++	- Happy New Year
++
++Fri Dec 29 20:43:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: remove warning and optimize
++
++Fri Dec 29 20:42:41 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: remove warnings
++
++Fri Dec 29 20:05:00 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h: cleanup
++
++Fri Dec 29 20:03:30 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/rpc_ct_param.c:
++	* src/ctlib/unittests/rpc_ct_setparam.c src/odbc/odbc.c:
++	- remove warnings
++
++Fri Dec 29 17:18:42 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/tds/log.c:
++	- use localtime_r if available
++
++Fri Dec 29 10:06:56 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/log.c:
++	- avoid locking if no logging
++
++Tue Dec 26 15:57:38 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h	src/ctlib/unittests/array_bind.c:
++	* src/ctlib/unittests/ct_diagall.c:
++	* src/ctlib/unittests/get_send_data.c:
++	* src/ctlib/unittests/lang_ct_param.c:
++	* src/dblib/bcp.c src/dblib/dblib.c:
++	* src/dblib/dbutil.c src/dblib/rpc.c:
++	* src/dblib/xact.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/t0016.c src/odbc/connectparams.c:
++	* src/odbc/descriptor.c src/odbc/error.c:
++	* src/odbc/odbc.c src/odbc/odbc_checks.c:
++	* src/odbc/prepare_query.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/describecol.c src/pool/config.c:
++	* src/pool/main.c src/pool/member.c src/pool/stream.c:
++	* src/pool/user.c src/pool/util.c:
++	* src/replacements/readpassphrase.c:
++	* src/replacements/strtok_r.c src/replacements/vasprintf.c:
++	* src/server/login.c src/server/unittest.c:
++	* src/tds/config.c src/tds/convert.c src/tds/data.c:
++	* src/tds/getmac.c src/tds/iconv.c src/tds/locale.c:
++	* src/tds/login.c src/tds/net.c src/tds/numeric.c:
++	* src/tds/tds_checks.c src/tds/tdsstring.c src/tds/threadsafe.c:
++	* src/tds/write.c src/tds/unittests/common.h win32/winlogin.c:
++	* win32/winsetup.c:
++	- include stdarg.h always before stdio.h to fix portability
++	  issues defining va_list
++
++Tue Dec 26 13:54:25 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am src/tds/util.c src/tds/log.c (added):
++	- separate log stuff
++
++Sun Dec 24 12:40:19 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/descriptor.c: cleanup
++
++Fri Dec 22 09:34:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: fix typo error
++
++Mon Dec 21 14:07:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/iconv.c: use cp1252 instead of iso8859-1 for mssql
++
++Wed Dec 20 22:47:36 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/tds/iconv.c src/tds/token.c log server charset changes
++	* src/tds/unittests/convert.c permit varbinary
++
++Mon Dec 18 10:50:34 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am: distribute enum_cap.h
++
++Fri Dec 15 14:41:14 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/tds/tds_willconvert.pl allow varbinary
++
++Thu Dec 14 22:18:16 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/tds/mem.c src/tds/unittests/t0001.c
++	- Added tds_capability_set and enumerated capabilities
++	* src/tds/enum_cap.h added
++
++Tue Dec 12 08:45:12 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	- improve describecol test
++
++Sun Dec 10 16:04:02 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/faq.html minor fixes
++	* src/apps/tsql.c send *sybase* charset name in login record
++	* src/tds/net.c src/tds/read.c a little less logging
++
++Thu Dec  7 17:06:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: make get_send_data works
++
++Tue Dec  5 11:42:04 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/funccall.c: add a test
++
++Fri Dec  1 16:45:59 EST 2006	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h src/dblib/bcp.c src/apps/freebcp.c
++	- Changed freetbcp batch-copied information messages to 
++	- match the output of Sybase's bcp utility.  
++
++Wed Nov 29 15:46:38 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c fixed broken "go" option handling.
++
++Tue Nov 28 11:52:27 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c fix -o option code
++	* src/tds/net.c reorganize tds_open_socket()
++
++Mon Nov 27 18:31:18 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/tds/net.c more detailed log of connect(2)
++
++Sun Nov 26 15:26:31 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/apps/tsql.c added connection timer feedback
++	* src/tds/login.c src/tds/net.c slightly better logging
++
++Thu Nov 23 09:43:00 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c:
++	- fix possible problem with very remote servers
++
++Thu Oct 26 15:09:48 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dbutil.c log error message from server
++	* src/tds/net.c log TDS version
++
++Thu Oct 26 14:26:27 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/common.c src/dblib/unittests/common.h
++	* src/dblib/unittests/t0001.c
++	- corrected command-line option handling
++
++Sat Oct 21 16:42:08 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/dblib.c src/dblib/unittests/t0022.c:
++	- dbresults succeeds if metadata or only return status is
++	- present, cf. ML yesterday.
++
++Sat Oct 21 14:22:44 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* autogen.sh: fix some portability issues
++
++Wed Oct 18 21:38:57 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/tables.c:
++	- fix problem with mssql2005 and SQLTables
++
++Mon Oct 16 09:48:31 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: reduce system calls required
++
++Thu Oct 12 11:19:02 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c:
++	- fix wrong assert
++	- return correctly RETURNSTATUS under Sybase
++
++Wed Oct 11 16:37:04 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix wrong assert using numerics
++
++Tue Oct 10 15:52:22 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* doc/osql.txt clarified
++
++Fri Oct  6 17:08:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/freebcp.c src/apps/freebcp.h doc/freebcp.txt
++	- applied -0 patch from ML
++	- by Constantin Vasilyev <vasilyev@ncbi.nlm.nih.gov>
++
++Wed Oct  4 19:46:29 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/apps/freebcp.c 
++	- applied -P from stdin patch 
++	- from ML Constantin Vasilyev <vasilyev@ncbi.nlm.nih.gov>
++
++Wed Oct  4 17:36:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql GNU sed does not support -E
++
++Wed Oct  4 14:48:20 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/osql.txt added osql man page
++
++Wed Oct  4 14:12:25 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am add osql as installable script
++
++Tue Oct  3 15:40:12 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c test fwrite(3) correctly
++
++Tue Sep 26 16:57:42 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/dblib.c
++	* src/tds/convert.c src/tds/net.c src/tds/token.c
++	- added more user-level error checking, checking against 
++	- known list of db-lib error messages
++	* src/apps/osql added
++
++Wed Sep 13 13:55:24 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* samples/Makefile.am samples/unixodbc.freetds.driver.template.in:
++	- add Setup entry to unixODBC template
++	- unixODBC templates are not executables
++
++Wed Sep 13 13:52:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: enable wide table
++
++Wed Sep 13 11:47:27 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c:
++	- fix really broken tds5_process_result
++
++Fri Sep 08 11:58:24 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/tds/threadsafe.c:
++	- fix threadsafe problem on NetBSD
++
++Fri Sep 08 11:17:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/token.c: make splint a bit more happy
++	* src/odbc/odbc.c: small 64bit improvements
++
++Thu Sep 07 23:10:29 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c: fix paramset (Levente Tamási)
++
++Fri Sep  1 10:34:20 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h include/tdsstring.h src/ctlib/ct.c:
++	* src/odbc/connectparams.c src/odbc/odbc.c src/server/login.c:
++	* src/tds/config.c src/tds/tdsstring.c:
++	- add dstr_size to DSTR
++	- add tds_dstr_alloc, tds_dstr_setlen, tds_dstr_buf
++
++Wed Aug 30 13:58:56 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/challenge.c src/tds/login.c:
++	- make tds_answer_challenge return flags
++	- tds_dstr fix
++	* src/dblib/dblib.c: small fix
++	* src/odbc/odbc.c: constification
++	* src/tds/query.c:
++	- some static functions rename
++	- do not convert string in tds7_build_param_def_from_query
++	* src/tds/threadsafe.c: cleanup
++
++Mon Aug 28 09:36:32 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/cspublic.h:
++	- applied Norbert Sendetzky patch for ctlib compatibility
++
++Fri Aug 25 11:03:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/t0017.c:
++	* src/dblib/unittests/t0017.in.be(added):
++	- fix big endian problem with t0017 test
++
++Fri Aug 25 09:17:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: remove 1024 char limit on tsql_readline
++
++Thu Aug 24 21:18:48 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: applied Christos Zoulas patch for no-tty
++
++Thu Aug 24 16:29:17 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/sybdb.h src/dblib/dblib.c:
++	- do not change compatibility
++	* src/tds/config.c: small optimization
++
++Thu Aug 24 11:37:15 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/sprintf_i64_format.m4: fix 64bit problem for LP64
++
++Thu Aug 24 11:17:26 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/apps/tsql.c src/ctlib/Makefile.am:
++	* src/dblib/Makefile.am src/tds/net.c win32/initnet.c:
++	* win32/winsetup.c win32/dev-cpp/FreeTDS.dev:
++	* win32/dev-cpp/Makefile.win win32/msvc6/FreeTDS.dsp:
++	- initialize socket library on win32
++
++Thu Aug 24 08:32:07 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c:
++	- do not print return status if quiet (patch from Christos Zoulas)
++
++Wed Aug 23 21:43:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tsql.txt: applied Christos Zoulas updates
++	* doc/txt2man: updated
++
++Wed Aug 23 17:16:10 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- clean error before reading SO_ERROR, some system need this
++	* src/tds/util.c src/ctlib/ct.c: cross compile fixes
++
++Wed Aug 23 16:25:25 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/ac_tds_func_which_getpwuid_r.m4 m4/sprintf_i64_format.m4:
++	* configure.ac src/ctlib/cs.c src/apps/tsql.c:
++	* src/replacements/asprintf.c src/tds/query.c:
++	- fixes some cross compile issues with hp-ux
++
++Mon Aug 21 11:08:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: remove small buffer overflow
++
++Thu Aug 17 11:13:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds.h src/dblib/unittests/Makefile.am:
++	* src/tds/net.c src/tds/query.c src/tds/token.c src/tds/util.c:
++	* m4/acx_pthread.m4(added):
++	- timeout more precise and use monotonic clock if available
++	- check pthread support more deeply
++
++Wed Aug 16 13:04:48 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: cleanup, fix possible problem under Linux
++	* src/tds/read.c: avoid invalid in_pos value on tds_peek
++
++Mon Aug 14 19:12:58 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c:
++	* src/dblib/unittests/common.c:
++	- fix warnings compiling with SUN cc
++	* src/dblib/unittests/thread.c: make error more verbose
++
++Sun Aug 13 15:02:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/data.c:
++	* src/odbc/unittests/transaction.c:
++	- fix minor issues with 64-bit machines
++
++Thu Aug 10 10:10:30 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: fix possible buffer overflow
++	* src/replacements/gettimeofday.c: add comment
++	* src/tds/threadsafe.c: better and simple win implementation
++	* vms/descrip_mms.template win32/config.h:
++	* win32/dev-cpp/FreeTDS.dev win32/msvc6/libTDS.dsp:
++	- update build file
++
++Tue Aug 08 19:14:32 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/htdoc/index.html: update link
++	* src/tds/query.c: add comment
++
++Tue Aug 08 16:42:39 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c src/tds/util.c:
++	- fix timeout problem setting correctly query_start_time
++
++Tue Aug 08 14:43:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/timeout2.c(added):
++	- added a test for timeout problem (cf "Query Time Out" on ML)
++
++Mon Aug 07 21:37:39 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsstring.h src/odbc/odbc_util.c:
++	* src/replacements/iconv.c src/tds/challenge.c:
++	* src/tds/config.c src/tds/convert.c:
++	* src/tds/iconv.c src/tds/mem.c src/tds/net.c:
++	* src/tds/query.c src/tds/read.c src/tds/tdsstring.c:
++	* src/tds/token.c src/tds/write.c:
++	- updated doxygen comments
++
++Sun Aug 06 17:54:11 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* freetds.spec.in: fix rpm build on suse
++
++Thu Aug 03 20:30:07 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS include/tds.h src/ctlib/ct.c src/odbc/odbc.c:
++	* src/tds/mem.c src/tds/query.c src/tds/tds_checks.c:
++	* src/tds/token.c src/tds/util.c:
++	- use reference counting for TDSCURSOR to avoid memory errors
++
++Thu Aug 03 10:32:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/iconv_fread.c(added):
++	* src/tds/iconv.c src/tds/unittests/.cvsignore:
++	* src/tds/unittests/Makefile.am:
++	- fix tds_iconv_fread and add a test for it
++
++Mon Jul 31 13:27:53 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c
++	- proper error message for using bcp with TDS version 4.2
++
++Mon Jul 31 13:23:44 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h src/dblib/dblib.c
++	- proper error message for using bcp with TDS version 4.2
++
++Thu Jul 27 15:22:27 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* samples/odbc_rpc.pl	use fetchrow_array
++	* src/tds/unittests/Makefile.am include parent directory
++
++Tue Jul 25 10:16:45 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac m4/ac_nullzero.m4: add test for portability
++
++Tue Jul 25 10:10:22 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/paramcore.c: updated
++
++Mon Jul 24 11:39:13 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/prepclose.c:
++	- test with SQLExecDirect
++
++Mon Jul 17 15:18:48 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/build_dsw.pl(removed):
++	* win32/build_dsw.pl(added) src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/Makefile.am:
++	- add a Makefile target to build projects for msvc6
++
++Thu Jul 13 10:20:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/unittests/moreandcount.c:
++	- remove next_row_count, now useless... rpc.c works the same
++
++Wed Jul 12 13:23:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/odbc/odbc.c src/tds/token.c:
++	- use TDS_NO_COUNT instead of bad rows_affected for next_row_count. 
++	- src/odbc/unittests/rpc.c now works
++
++Wed Jul 12 16:15:14 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/test-other.sh: add file log
++	* src/odbc/unittests/rpc.c: fix uninitialized error
++
++Tue Jul 11 17:52:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/odbc/odbc.c src/odbc/unittests/rpc.c:
++	- Better logging
++
++Tue Jul 11 17:28:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/done_handling.c: improve
++
++Tue Jul 11 17:27:26 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/paramcore.c:
++	- fix compatibility with sybase
++
++Tue Jul 11 11:56:53 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/online.pl: generate more friendly names
++
++Mon Jul 10 17:07:00 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/tds/token.c src/dblib/dblib.c src/dblib/unittests/rpc.c
++	- dbresults does not return on DONEPROC
++
++Sun Jul 09 12:52:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* doc/Makefile.am: fix compatibility problem
++	* src/odbc/unittests/rpc.c: fix warning
++
++Fri Jul  7 19:08:44 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* include/sybdb.h src/dblib/dblib.c src/tds/token.c:
++	- Better logging
++
++Wed Jul 05 14:45:08 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/bcp.c:
++	* src/dblib/unittests/common.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/dbmorecmds.c:
++	* src/dblib/unittests/done_handling.c:
++	* src/dblib/unittests/rpc.c src/dblib/unittests/t0001.c:
++	* src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c:
++	* src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c:
++	* src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c:
++	* src/dblib/unittests/t0008.c src/dblib/unittests/t0009.c:
++	* src/dblib/unittests/t0011.c src/dblib/unittests/t0012.c:
++	* src/dblib/unittests/t0013.c src/dblib/unittests/t0014.c:
++	* src/dblib/unittests/t0015.c src/dblib/unittests/t0016.c:
++	* src/dblib/unittests/t0017.c src/dblib/unittests/t0018.c:
++	* src/dblib/unittests/t0019.c src/dblib/unittests/t0020.c:
++	* src/dblib/unittests/t0021.c src/dblib/unittests/t0022.c:
++	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c:
++	* src/dblib/unittests/thread.c:
++	* src/dblib/unittests/build_dsw.pl(added):
++	- put include stuff in common.h
++	- fix compile with ms dblib
++	- simplify testing under windows creating project files
++
++Wed Jul  5 18:29:21 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/dblib.c src/dblib/rpc.c:
++	- removed nonprintable characters from TDSDUMP log
++
++Wed Jul  5 15:43:24 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/unittests/rpc.c src/odbc/unittests/rpc.c:
++	- more thorough tests, currently fail
++
++Tue Jul 04 17:13:08 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/paramcore.c(added):
++	* src/odbc/unittests/.cvsignore src/odbc/sql2tds.c:
++	- test for core using SQLBindParameter, small fix
++
++Mon Jul 03 13:09:40 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c:
++	- assure there is always an error when SQL_ERROR is returned
++	- fix warning
++
++Fri Jun 30 10:31:49 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/odbc/sql2tds.c assert good pointer in case user passed NULL
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/rpc.c
++	- added new unit test, similar to that used in dblib.
++
++Thu Jun 29 17:05:35 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS src/tds/challenge.c:
++	- fix small buffer overflow
++	- reuse buffer
++
++Thu Jun 29 14:07:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/tds/Makefile.am src/tds/challenge.c:
++	* src/tds/login.c src/tds/token.c:
++	- add NTLM2 Session Response support
++
++Tue Jun 27 15:47:46 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/done_handling.c:
++	- improve
++	- update style
++	- fix typo
++
++Mon Jun 26 16:10:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* phptests/rpc2.php(added):
++	- test from Ellert van Koperen (cf "SP parameters" and 
++	  http://kb.vankoperen.nl/freetds-problems.html)
++
++Sun Jun 25 10:12:48 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/warning.c:
++	- tested
++	- fix portability problem with former Sybase db
++	- test returned warning
++
++Sun Jun 25 09:50:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/warning.c(added):
++	- added warning test from John K. Hohm (cf 
++	  "Warning return as copy of last result row" on ML)
++	* src/odbc/unittests/describecol.c: compile fix
++
++Wed Jun 21 17:03:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c:
++	* src/odbc/unittests/describecol.in(added):
++	- rewrote describecol test
++
++Wed Jun 21 09:26:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: improve column_length
++	* src/odbc/odbc_util.c: fix for odbc_sql_to_displaysize
++	* src/tds/iconv.c: invalid iconv_t is only -1, not NULL
++
++Tue Jun 20 17:52:19 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* src/odbc/unittests/array_out.c:
++	- rename variable to avoid libc	symbol conflict
++
++Tue Jun 20 14:38:03 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/convert.c: use macro in sprintf
++
++Tue Jun 20 14:34:03 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/mem.c: small macro to allocate columns
++
++Tue Jun 20 14:33:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c: improved a lot
++
++Tue Jun 20 11:15:16 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: catch error better
++
++Mon Jun 19 10:38:36 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* freetds.spec.in misc/test-other.sh src/apps/Makefile.am:
++	* src/ctlib/Makefile.am src/dblib/Makefile.am src/odbc/Makefile.am:
++	* src/server/Makefile.am src/tds/Makefile.am:
++	*  src/tds/unittests/Makefile.am:
++	- do not make libTDS shared library any more
++
++Mon Jun 19 09:57:23 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/ct.c src/odbc/sql2tds.c src/odbc/unittests/data.c:
++	* src/server/unittest.c:
++	- remove warning compiling with gcc4
++
++Thu Jun 15 14:15:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.ac src/ctlib/unittests/cancel.c:
++	* src/dblib/unittests/common.c src/odbc/Makefile.am:
++	* src/replacements/readpassphrase.c:
++	- finished cross mingw32
++
++Wed Jun 14 17:34:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/convert_tds2sql.c: fix for date format
++
++Wed Jun 14 17:29:13 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.ac: add function
++	* src/apps/Makefile.am src/dblib/unittests/Makefile.am:
++	* src/dblib/unittests/bcp.c src/odbc/unittests/Makefile.am:
++	* src/replacements/Makefile.am src/replacements/gettimeofday.c:
++	* src/tds/unittests/Makefile.am:
++	- more fixes for cross mingw32
++
++Wed Jun 14 13:26:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds_sysdep_private.h src/apps/Makefile.am:
++	- fix for cross mingw32
++	* src/odbc/unittests/describecol.c: report more clearly problems
++
++Tue Jun 13 20:17:16 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/common.h src/server/unittest.c:
++	- small fixes for cross mingw
++
++Tue Jun 13 14:38:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/prepclose.c(added) configure.ac:
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	- add test to test error closing connection on SQLPrepare
++
++Mon Jun 12 22:02:57 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* m4/sprintf_i64_format.m4: fix for cross mingw32
++
++Mon Jun 12 21:52:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/sql2tds.c: fix for possible uninitialized variable
++
++Mon Jun 12 21:48:15 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/apps/datacopy.c src/apps/freebcp.c src/apps/freebcp.h:
++	* src/pool/main.c src/pool/pool.h:
++	- fix some issues cross compiling for mingw32
++
++Mon Jun 12 16:55:59 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/data.c: add test for date to char
++
++Fri Jun  9 14:33:31 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* src/apps/tsql.c: inhibit readline tab completion in tsql
++
++Fri Jun 09 11:50:55 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* locales.conf: use same date format as Sybase in default and en_US
++
++Thu Jun 08 10:18:50 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/unittests/t0007.c:
++	- improved to detect possible date problems
++
++Wed Jun 07 14:37:56 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* src/tds/convert.c: correctly convert dates in January
++
++Tue Jun 06 12:02:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.ac src/tds/config.c:
++	- fix tsql -C for sybase compatibility
++
++Tue Jun 06 11:32:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/mem.c: use calloc instead of malloc/memset
++
++Mon Jun 05 13:42:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/ct.c src/tds/token.c:
++	- style and cleanup
++
++Mon May 29 13:38:05 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* m4/sprintf_i64_format.m4: fix quoting
++
++Mon May 29 12:58:38 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS include/tds.h src/tds/token.c:
++	- make tds_alloc_get_string static
++
++Mon May 15 17:11:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c:
++	- applied fixes from Charlene Herring (cf. "Problems when
++	  using odbc : SQLPutData, SQLExecDirect,Decimals" 2006/05/14
++
++Sun May 14 14:34:04 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/descriptor.c: fix memory error
++
++Sat May 13 10:49:40 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/copydesc.c: improve
++
++Mon May 08 11:38:30 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/descriptor.c src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/copydesc.c(added): add test for SQLCopyDesc
++
++Fri Apr 21 17:10:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/sql2tds.c: use new tds_convert types
++
++Fri Apr 21 09:45:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* doc/htdoc/faq.html: fix html compatibility
++
++Thu Apr 20 12:10:28 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/unittests/ct_dynamic.c: remove leak in test
++
++Tue Apr 17 19:47:57 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/ct.c: fix double free
++
++Mon Apr 17 10:51:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/prepare_query.c:
++	- use new conversion style in ODBC
++
++Sun Apr 16 10:11:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/tds/locale.c src/tds/mem.c:
++	- TDSLOCALE changes to keep ABI
++
++Sat Apr 15 10:18:29 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsconvert.h 	* src/tds/convert.c:
++	- add new type of conversion for copy optimizations
++
++Sat Apr 15 10:02:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c: fix for older Sybase versions
++	* src/tds/config.c: optimize option read
++
++Sat Apr 15 09:03:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c: remove warning
++
++Fri Apr 14 15:22:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c:
++	- improved
++
++Fri Apr 14 13:55:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c:
++	- add test for precision returned by SQLDescribeCol
++
++Wed Apr 12 21:41:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* locales.conf: fix charset typo
++	* doc/userguide.sgml: fix attributes for locales.conf
++
++Wed Apr 12 15:53:18 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h include/tds_sysdep_private.h:
++	* include/tds_sysdep_public.h.in include/tdsconvert.h:
++	* include/tdsver.h.in:
++	- avoid ident strings in all objects
++	* m4/sprintf_i64_format.m4: add Ld format
++
++Tue Apr 11 16:33:41 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds_sysdep_public.h.in include/tdsver.h.in:
++	- small constification
++
++Tue Apr 11 13:51:43 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/connect.c: do not fail if not FreeTDS
++	* src/odbc/unittests/raiserror.c: more verbose
++
++Mon Apr 10 18:14:17 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* include/tds.h src/apps/tsql.c src/tds/config.c
++	- report sysconfdir with tsql -C
++
++Mon Apr 10 11:59:53 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: cleanup
++
++Fri Apr 07 09:38:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/test-other.sh: update to php 5.1
++	* phptests/nextres.php: a bit more verbose
++
++Thu Apr 06 11:37:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/coverage.sh: less verbose 
++	* src/dblib/bcp.c: small change
++
++Wed Apr 05 08:42:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test.sh: cleanup
++	* misc/test-auto.sh: allow configuration
++	* misc/test-other.sh: make output suitable for online.pl
++	* src/apps/tsql.c:
++	- improve documentation
++	- fix problem for multiple options
++	* src/odbc/odbc.c src/tds/token.c: avoid void message to application
++
++Wed Apr 05 07:09:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: remove some warnings
++
++Wed Mar 29 18:25:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* m4/ac_caolan_func_which_gethostbyname_r.m4:
++	* m4/ac_have_inaddr_none.m4 m4/ac_have_malloc_options.m4:
++	* m4/ac_raf_func_which_getservbyname_r.m4:
++	* m4/ac_tds_func_which_gethostbyaddr_r.m4:
++	* m4/ac_tds_func_which_getpwuid_r.m4:
++	* m4/ac_tds_func_which_localtime_r.m4:
++	* m4/ax_cflags_gcc_option.m4 m4/lib-link.m4:
++	* m4/sprintf_i64_format.m4 m4/type_socklen_t.m4:
++	- quote as necessary
++
++Mon Mar 27 19:01:05 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* configure.ac
++	* m4/ac_caolan_func_which_gethostbyname_r.m4
++	* m4/ac_have_inaddr_none.m4
++	* m4/ac_have_malloc_options.m4
++	* m4/ac_raf_func_which_getservbyname_r.m4
++	* m4/ac_tds_func_which_gethostbyaddr_r.m4
++	* m4/ac_tds_func_which_getpwuid_r.m4
++	* m4/ac_tds_func_which_localtime_r.m4
++	* m4/ax_cflags_gcc_option.m4
++	* m4/sprintf_i64_format.m4
++	* m4/type_socklen_t.m4
++	* src/ctlib/unittests/Makefile.am
++	* src/dblib/unittests/Makefile.am
++	* src/odbc/unittests/Makefile.am
++	* src/tds/unittests/Makefile.am
++	- removed/updated obsolete autoconf macros
++	* m4/am_iconv.m4 removed 
++	* m4/README.iconv
++	* m4/iconv.m4 m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4
++	- added from GNU libiconv
++
++Mon Mar 27 09:48:56 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/index.html corrected nightly test link
++
++Mon Mar 27 10:17:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/rpc.c: allow again null for fixed types
++
++Mon Mar 27 02:20:16 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* configure.ac m4/am_iconv.m4 m4/check_openssl.m4
++	* src/apps/Makefile.am src/ctlib/Makefile.am src/dblib/Makefile.am
++	* src/odbc/Makefile.am src/pool/Makefile.am src/replacements/Makefile.am
++	* src/server/Makefile.am src/tds/Makefile.am
++	- modernized autotool contructs
++	* configure.in removed 
++
++Sun Mar 26 19:01:43 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/prepare_query.c:
++	- fixed constant parameters after mssql 2005 patch
++
++Fri Mar 24 16:47:26 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* configure.in removed, is now configure.ac 
++	* acinclude.m4 removed, added m4 directory
++	* Makefile.am include m4 directory
++	* m4/ac_caolan_func_which_gethostbyname_r.m4 m4/ac_have_inaddr_none.m4
++	* m4/ac_have_malloc_options.m4 m4/ac_raf_func_which_getservbyname_r.m4
++	* m4/ac_tds_func_which_gethostbyaddr_r.m4 
++	* m4/ac_tds_func_which_getpwuid_r.m4 
++	* m4/ac_tds_func_which_localtime_r.m4 m4/am_iconv.m4 
++	* m4/check_openssl.m4 m4/sprintf_i64_format.m4 m4/type_socklen_t.m4
++	- Split acinclude.m4 into one macro defintion per file.
++	* m4/ax_cflags_gcc_option.m4 
++	- Check for gcc features e.g. the declaration-after-statement warning.
++
++Fri Mar 24 13:03:36 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/docs.html doc/htdoc/index.html updated
++
++Fri Mar 24 12:36:02 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/software.html fixed broken links added link to RC
++
++Fri Mar 24 16:27:27 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test.sh misc/test-auto.sh misc/full-test-ol.sh(removed):
++	- use an "online" version for test
++
++Thu Mar 23 15:53:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/earlybind.c:
++	* src/odbc/unittests/norowset.c src/odbc/unittests/t0004.c:
++	* src/odbc/unittests/tables.c src/tds/data.c src/tds/tds_checks.c:
++	- fixes for mssql 2005
++
++Thu Mar 23 13:48:23 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/query.c: partially fix problem with mssql2k5
++
++Thu Mar 23 11:44:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test-ol.sh misc/online.pl misc/test-auto.sh:
++	- changed online.pl with James hints
++	- enable Valgrind tests using online check
++
++Tue Mar 21 15:24:04 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/cursor2.c(aded) src/odbc/unittests/Makefile.am:
++	- added test to check errors using cursor on no row statement
++
++Tue Mar 21 13:22:07 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/native.c:
++	- applied patch from Richard Krehbiel (cf "ODBC datetime literal issue")
++
++Tue Mar 21 08:49:44 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.in src/dblib/dblib.c:
++	- fix declaration after statements
++
++Mon Mar 20 15:28:25 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c: fix error in bcp_colfmt
++
++Mon Mar 20 15:00:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
++	- remove some double checks
++	- return correct values from CHECK_PARAMETER
++	- fix some possible core if dbproc == NULL
++
++Mon Mar 20 09:42:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test.sh: added timeout
++
++Sun Mar 19 18:34:47 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/test-auto.sh: fix typo in header
++	* src/dblib/dblib.c: remove double checks
++
++Sun Mar 19 18:33:14 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/genparams.c src/odbc/unittests/transaction.c:
++	- remove warnings on 64bit int
++
++Sun Mar 19 09:27:09 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/bcp.c src/dblib/dblib.c more logging repairs
++
++Sat Mar 18 12:34:02 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* include/dblib.h src/dblib/bcp.c
++	- validate parameters.  Unable to run unittest due to down server.
++
++Sat Mar 18 01:27:32 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* include/dblib.h src/dblib/dblib.c src/dblib/rpc.c
++	- test parameters for all public functions (except bcp)
++
++Fri Mar 17 01:35:17 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/dblib.c src/dblib/rpc.c
++	- added a TDSDUMP log entry for every public function
++
++Thu Mar 16 09:59:25 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* TODO add rpc error messages
++	* src/apps/bsqldb.c exit if severity > 10
++
++Wed Mar 15 00:41:11 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/freebcp.txt The freebcp manpage was seriously out of date.
++	* src/apps/freebcp.c give better error message.
++
++Thu Mar  9 14:33:37 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- add cursor_type to connection attributes (required for DBD::ODBC)
++	- removed small TODO on error report
++
++Mon Mar  6 12:55:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/ctlib/ct.c src/odbc/connectparams.c:
++	* src/pool/util.c src/server/login.c src/server/unittest.c:
++	* src/tds/config.c src/tds/login.c src/tds/mem.c:
++	- renamed host_name field to client_host_name
++	- optimize way strings are allocated
++
++Fri Feb 24 15:04:35 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/tds/config.c src/tds/login.c:
++	- nicer TDSDUMPCONFIG output, including a recap
++
++Sun Feb 19 14:56:15 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: fix wrong declaration
++
++Thu Feb 16 08:30:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/scroll.c src/odbc/unittests/raiserror.c:
++	* src/odbc/unittests/cursor1.c:
++	- remove warning compiling with gcc4
++	* misc/test-other.sh: fix problem with DBD:ODBC test
++
++Mon Feb 13 17:11:30 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/genparams.c: add BIGINT type to test
++
++Wed Feb  8 10:48:36 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
++	* vms/odbc_driver_axp.opt win32/FreeTDS.def:
++	- start cursor stuff for odbc
++	- added SQLSetScrollOptions
++	* src/odbc/unittests/scroll.c: support more fetch types
++
++Tue Feb  7 15:42:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/tds/query.c src/ctlib/ct.c NEWS:
++	- improve cursor support
++
++Tue Feb  7 14:22:50 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/scroll.c(added):
++	* src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/cursor1.c:
++	- add scroll test for cursor
++	- build msvc project for odbc unittests
++	* src/dblib/unittests/Makefile.am: add done_handling test
++
++Mon Feb  6 16:50:05 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/sybdb.h src/apps/freebcp.c src/dblib/bcp.c:
++	- implemented BCPKEEPIDENTITY for bcp_control
++	- make freebcp do not depend on dblib internals
++
++Mon Feb  6 16:44:27 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/cursor1.c:
++	- update cursor1 test
++
++Thu Feb  2 15:33:21 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS: updated
++	* src/odbc/odbc.c vms/odbc_driver_axp.opt win32/FreeTDS.def:
++	- compile SQLSetPos function
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/cursor1.c(added):
++	- added a test for cursors (do not work...)
++
++Tue Jan 31 14:27:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/apps/freebcp.c src/dblib/bcp.c:
++	- fix broken charcater conversion
++	- use calloc instead of malloc/memset
++	- support 64bit file on win32
++
++Tue Jan 31 09:59:28 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/dblib.c: do more argument check
++
++Mon Jan 30 16:29:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/unittests/blk_out.c src/ctlib/unittests/ct_cursor.c:
++	* src/ctlib/unittests/ct_cursors.c src/ctlib/unittests/ct_dynamic.c:
++	* src/dblib/unittests/t0005.c src/dblib/unittests/t0014.c:
++	* src/dblib/unittests/t0022.c src/dblib/unittests/thread.c:
++	- reduce false errors
++
++Sat Jan 28 15:49:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c:
++	- update row allocation using new row_free
++	- fix native format
++	- correctly check and handle EOF
++	- change _bcp_build_bcp_record to direct send row (renamed to 
++	  _bcp_send_bcp_record)
++	- write error file only if needed
++	* src/dblib/unittests/t0016.c: improved
++	* src/dblib/unittests/t0016.in:
++	- make input same of output
++	* src/dblib/unittests/t0017.c: get all data
++	* src/tds/mem.c: reset pointer just freed
++
++Sat Jan 28 09:39:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/t0017.c: reformat output
++
++Fri Jan 27 14:34:09 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/bcp.c recognize EOF errors from _bcp_read_hostfile
++
++Fri Jan 27 10:43:54 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/unittests/t0017.c better feedback
++
++Thu Jan 26 13:58:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/apps/freebcp.c src/apps/freebcp.h:
++	- support for NUL in terminators
++
++Wed Jan 25 15:33:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c: fix return test for fseeko
++
++Wed Jan 25 15:01:51 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* acinclude.m4 configure.in src/tds/numeric.c:
++	- use 64bit sprintf format if available
++	* misc/test-other.sh: redirect odbc to compiled driver
++
++Tue Jan 24 16:01:41 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS include/tds.h src/apps/tsql.c src/ctlib/blk.c:
++	* src/ctlib/ct.c src/dblib/bcp.c src/dblib/buffering.h:
++	* src/dblib/dblib.c src/dblib/rpc.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c src/odbc/prepare_query.c:
++	* src/odbc/sql2tds.c src/pool/stream.c src/server/server.c:
++	* src/tds/mem.c src/tds/query.c src/tds/tds_checks.c:
++	* src/tds/token.c src/tds/unittests/dataread.c:
++	* src/tds/unittests/dynamic1.c src/tds/unittests/t0002.c:
++	* src/tds/unittests/t0004.c src/tds/unittests/t0005.c:
++	* src/tds/unittests/t0006.c src/tds/unittests/utf8_1.c:
++	* src/tds/unittests/utf8_2.c:
++	- use direct pointer column_data instead of old column_offset
++
++Mon Jan 23 17:30:38 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/apps/bsqldb.c bind to printable width, not column size
++
++Mon Jan 23 14:04:44 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.in: start developing 0.65 version
++$Id: ChangeLog-0.82,v 1.1.2.2 2008/01/10 20:58:43 jklowden Exp $
+diff --git b/INSTALL.CVS a/INSTALL.CVS
+new file mode 100644
+index 0000000..c23f6b7
+--- /dev/null
++++ a/INSTALL.CVS
+@@ -0,0 +1,65 @@
++Building FreeTDS from CVS
++James Cameron <james.cameron@compaq.com>
++
++The CVS archive is maintained on Source Forge.  See the User Guide or 
++start at http://sourceforge.net/projects/freetds/ for information on 
++connecting to the CVS server.  Then follow these steps:
++
++1) satisfy build dependencies, ensure that the following packages are
++   installed:
++
++	automake	(GNU Automake, generates Makefile.in from Makefile.am)
++	autoconf	(GNU Autoconf, generates configure from configure.in)
++	libtool		(GNU Libtool, library creation support scripts)
++	make		(GNU or BSD Make.)
++	gcc		(GNU Compiler Collection, for C code compilation)
++	
++	Autotool versions that work:
++	$ (autoconf --version; automake --version; libtool --version) |grep GNU
++	autoconf (GNU Autoconf) 2.60
++	automake (GNU automake) 1.9.6
++	ltmain.sh (GNU libtool) 1.5.18 (1.1220.2.245 2005/05/16 08:55:27)
++	
++	The above are used to generate the distributions.  
++	You may get away with older versions, as far back as 2.53 for autoconf.
++
++2) execute autogen.sh to run automake, autoconf and configure,
++
++	./autogen.sh
++
++   Any switches provided to autogen.sh will be passed to the configure script.   
++
++3) compile the source using make, 
++
++	make
++
++5) switch to a user that can write to the target installation
++   directory, usually root,
++
++	su root
++
++4) install the package,
++
++	make install
++	
+++++
++
++You are not required to rely on SourceForge's anonymous CVS server, which at
++the present time (July 2004) runs up to 1 hour behind the development server. 
++You can fetch the CVS tarball (the basis for a CVS server, not a snapshot) from
++SourceForge at:
++
++http://cvs.sourceforge.net/cvstarballs/freetds-cvsroot.tar.bz2
++
++We have a backup location, too, via anonymous ftp:
++	
++	ftp://rt.fm/pub/freetds/ (thanks to Joshua Stein <jcs@rt.fm>)
++	
++Nightly tarballs have been discontinued or deprecated, depending on which 
++Sourceforge document you believe.  Either way, you can now fetch 
++the CVS tree via rsync:
++
++$ rsync -av rsync://freetds.cvs.sourceforge.net/cvsroot/freetds/* .
++	
++--
++$Id: INSTALL.CVS,v 1.7.2.1 2008/01/10 20:58:43 jklowden Exp $
+diff --git b/TODO.freddy a/TODO.freddy
+new file mode 100644
+index 0000000..521a55a
+--- /dev/null
++++ a/TODO.freddy
+@@ -0,0 +1,66 @@
++Well.. I don't know how to put these information so I'll put here
++Probably I'm the only person who can fully understand these notes...
++
++Fixes
++-----
++IMPORTANT fix done_handling
++ODBC RPC check (+chained rpcs?? see below)
++
++Cursor and dynamic
++------------------
++libTDS should handle real cursor/dynamic memory deallocation
++search for tds_alloc_cursor, tds_free_cursor and similar for dynamic
++cursor too complicate... reduce all states, handle more in libTDS
++Tests:
++ - multiple RPCs check returns (possible??)
++   (see odbc_set_return_status, odbc_set_return_params and odbc_get_param_len
++   calls)
++   add multiple chained RPCs for odbc and mssql7+...
++ - cursor update and multiple tables (using view)
++ODBC cursor check (cfr "Progress on CVS")
++  search "TODO read results, set row count, check type and scroll returned"
++http://support.microsoft.com/kb/246265/en-us
++http://support.microsoft.com/kb/290413/en-us
++http://support.microsoft.com/kb/238336/en-us
++
++Row handling
++------------
++Upper layer should be able to read data from network and handle rows
++Possibility to stop sending/receiving data for SQLPutData and similar
++Allow upper layer to get if libTDS is sending a request (add new state??)
++tds_process_tokens should "return" any row/done/other informations,
++not only done_flags
++libTDS should handle multiple reply from server (cursors and so on)
++
++Token handling
++--------------
++Split token.c to one base token handling and another with higher
++level (callbacks, state and so on)
++See James propos about tds_read_results
++
++Done handling
++-------------
++Callback when state goes to IDLE
++Free unused cursors and dynamic and/or reuse them
++
++Other
++-----
++Implement some sort of fast write to network writing directly to 
++wire buffer. It would be helpful to have "lock" length size, write to
++wire, write length, "unlock". Also a function to get current position (to
++compute lengths).
++
++build an array of "flags" to translate type -> flag like SYBCHAR ->
++char, variable and so on
++
++Possibility to lock TDSSOCKET (see odbc, multiple RPCs)
++
++Support Unicode under ODBC, use iso8859-1 by default and large characters
++
++
++Tests
++-----
++Rebuild all test support (virtual machines, chroot, msde+mssql2005)
++Add a test for rpm (redhat, suse?)
++disabling thread safety don't check for thread-safe functions
++check cross compiled odbc driver, exports, resource version (test-dist)
+diff --git b/doc/.cvsignore a/doc/.cvsignore
+new file mode 100644
+index 0000000..1138025
+--- /dev/null
++++ a/doc/.cvsignore
+@@ -0,0 +1,19 @@
++Makefile
++Makefile.in
++freebcp.1
++html
++tsql.1
++bsqldb.1
++defncopy.1
++datacopy.1
++osql.1
++fisql.1
++libtds
++reference
++userguide.dsl
++doc
++ctlib.api.sgml
++dblib.api.sgml
++doxy.log
++odbc.api.sgml
++bsqlodbc.1
+diff --git b/doc/README.releasing a/doc/README.releasing
+new file mode 100644
+index 0000000..cae6dc0
+--- /dev/null
++++ a/doc/README.releasing
+@@ -0,0 +1,53 @@
++It's pretty simple, basically:
++
++0) Form a branch in cvs:
++
++	$ cvs tag -b BRANCH0_xx	
++   
++   Use the form BRANCH0_xx, where xx is the release number.  This affects only
++   the repository, not the working directory.  
++   
++1) Change the version number in configure.ac and UG.  
++2) Update web pages regarding purpose and status of rc.  
++3) Put out a release candidates until everyone's happy.  
++   jkl has a "make dist" script on /etc/nightly.freetds that works well.  
++4) ftp tarball to 
++	ftp://login.ibiblio.org/pub/linux/ALPHA/freetds/current
++5) ftp user guide to www.freetds.org/userguide/.  
++   repeat 3-4 as necessary.
++6) Log into ibiblio.  Trim rc# from tarball.  Update web site.  
++7) Create rpm with 'rpmbuild -ta freetds-0.61.tar.gz', post these to 
++   ibiblio as well.
++   
++Announcements to:
++
++	freshmeat.net
++	comp.os.linux.announce
++	comp.databases.sybase
++	comp.databases.ms-sqlserver
++	linuxpr.com
++	
++
++We received this bit of advice on the mailing list on 
++Wed Oct 15 14:51:06 EDT 2003.  
++
++Please, please, *please* follow the common rules of good release
++engineering (in descending order of importance - two orders of magnitude
++less important per step ;-)
++
++(A) (Priority 100) A release is STATIC.  You NEVER EVER change the
++    contents of a release after the fact, such as replacing the
++    freetds-0.61.tgz archive with a DIFFERENT ARCHIVE containing
++    freetds-0.61.2.  This breaks everybody that has a system in place
++    for using the tarballs - and I know of at least eight public open
++    source systems that do this, as well as a bunch of proprietary systems.
++
++(B) (Priority 1) Release engineering needs to include procedures to
++    make sure that the documentation in the release is up to date.
++    FreeTDS 0.61.2 refers to itself as FreeTDS 0.61.1.
++
++(C) (Priority 0.01) It'd be nice if the archive name followed the normal
++    convention for naming - .tar.gz for tar and gzip, rather than .tgz.
++
++--
++$Id: README.releasing,v 1.10 2008/01/08 13:29:40 freddy77 Exp $
+diff --git b/doc/htdoc/contrib.html a/doc/htdoc/contrib.html
+new file mode 100644
+index 0000000..284f3e1
+--- /dev/null
++++ a/doc/htdoc/contrib.html
+@@ -0,0 +1,71 @@
++<?xml version="1.0" encoding="iso-8859-1" ?>
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
++<html xmlns="http://www.w3.org/1999/xhtml">
++<!-- $Id: contrib.html,v 1.5 2007/08/09 07:52:07 freddy77 Exp $ -->
++<head>
++<title>FreeTDS.org</title>
++</head>
++<body bgcolor="#f9f9f9">
++
++<!-- generic header -->
++<table summary="" width="100%">
++<tr>
++<td><img src="freetdslogo3.gif" alt="FreeTDS.org" /></td>
++<td align="right" valign="bottom">
++<a href="index.html">Home</a>&nbsp;&nbsp;|&nbsp;
++<a href="news.html">News</a>&nbsp;&nbsp;|&nbsp;
++<a href="software.html">Software</a>&nbsp;&nbsp;|&nbsp;
++<a href="docs.html">Documentation</a>&nbsp;&nbsp;|&nbsp;
++<a href="support.html">Support</a>&nbsp;&nbsp;|&nbsp;
++Contribute
++</td>
++</tr>
++</table>
++<hr size="1" noshade="noshade" />
++
++
++<!-- page specific content -->
++<p align="center">
++<font size="+3"><b>C</b></font>ontribute
++<br />
++<br />
++</p>
++
++<table summary="layout" width="80%" align="center">
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++So you want to help out the FreeTDS Project? We greatly appreciate all offers. There are a number of ways to help and this page will let you know about them.
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++If you are a programmer and wish to contribute code, please join our <a href="http://lists.ibiblio.org/mailman/listinfo/freetds">Mailing List</a>.  Preferred form for patches is a context diffs against the current CVS tree.  If you have submitted patches in the past and want to get a CVS account for direct checkin ask <a href="mailto:jklowden@freetds.org">James</a>.
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++If your C skills aren't up to snuff, but you still want to help, consider pitching in on the <a href="docs.html">FreeTDS documentation</a>.  If something didn't make sense when you read it, let us know.  Or if you want to detail how you got a specific configuration working, send it in and we'll include it in the <a href="/userguide/">User Guide</a>, so those that come after you will have an easier time.
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++If on the other hand you simply want to donate money to the FreeTDS Project, we also graciously accept donations via <a href="http://www.paypal.com">PayPal</a>.  Just click on the button below.  These funds will be used for purchases of software and hardware specifically needed by those who work on FreeTDS.  In particular, our current needs include VMWare, Win2K Server (to complete domain login support), and SQL Server 2000 (for TDS 8.0 support).  We will provide a detailed accounting of how these funds are spent to any contributor who requests it.
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++</table>
++
++<!-- Begin PayPal Logo -->
++<form action="https://www.paypal.com/cgi-bin/webscr" method="post">
++<p align="center">
++<input type="hidden" name="cmd" value="_xclick" />
++<input type="hidden" name="business" value="camber@ais.org" />
++<input type="hidden" name="item_name" value="freetds" />
++<input type="hidden" name="item_number" value="1" />
++<input type="hidden" name="image_url" value="http://www.freetds.org/logo_small.gif" />
++<input type="hidden" name="no_shipping" value="1" />
++<input type="hidden" name="return" value="http://www.freetds.org/contrib.html" />
++<input type="hidden" name="cancel_return" value="http://www.freetds.org/contrib.html" />
++<input type="image" src="http://images.paypal.com/images/x-click-but04.gif" name="submit" alt="Make payments with PayPal - it's fast, free and secure!" />
++</p>
++</form>
++<!-- End PayPal Logo -->
++
++</body>
++</html>
+diff --git b/doc/htdoc/faq.html a/doc/htdoc/faq.html
+new file mode 100644
+index 0000000..76126b3
+--- /dev/null
++++ a/doc/htdoc/faq.html
+@@ -0,0 +1,864 @@
++<?xml version="1.0" encoding="iso-8859-1"?>
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
++    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
++
++<html xmlns="http://www.w3.org/1999/xhtml">
++<!-- $Id: faq.html,v 1.18 2006/12/10 21:07:47 jklowden Exp $ -->
++
++<head>
++  <meta name="generator" content=
++  "HTML Tidy for NetBSD (vers 1st August 2004), see www.w3.org" />
++
++  <title>FreeTDS Frequently Asked Questions</title>
++</head>
++
++<body bgcolor="#F9F9F9">
++  <!-- generic header -->
++
++  <table summary="table of contents">
++    <tr>
++      <td><img src="freetdslogo3.gif" alt="FreeTDS.org" /></td>
++
++      <td align="right" valign="bottom">Home&nbsp;&nbsp;|&nbsp;
++      <a href="news.html">News</a>&nbsp;&nbsp;|&nbsp; <a href=
++      "software.html">Software</a>&nbsp;&nbsp;|&nbsp; <a href=
++      "docs.html">Documentation</a>&nbsp;&nbsp;|&nbsp; <a href=
++      "support.html">Support</a>&nbsp;&nbsp;|&nbsp; <a href=
++      "contrib.html">Contribute</a></td>
++    </tr>
++  </table>
++  <hr size="1" noshade="noshade" />
++  <!-- page specific content -->
++
++  <h1>FAQ</h1>
++
++  <p><font size="-1">The <a href="userguide/">FreeTDS User Guide</a>,
++  included in each release, is the appropriate place for new users
++  to start.</font></p>
++
++  <p>This list of frequently asked questions and answers about
++  FreeTDS is updated between releases to cover problems since the
++  last release, and to answer perennial questions (there are
++  some).</p>
++
++  <div align="right">
++    <i>$Id: faq.html,v 1.18 2006/12/10 21:07:47 jklowden Exp $</i>
++  </div>
++
++  <ol>
++    <li>General Questions
++
++      <ul>
++        <li><a href="#What.is.FreeTDS">What is FreeTDS?</a></li>
++
++        <li><a href="#Where.do.I.get.FreeTDS">Where do I get
++        FreeTDS?</a></li>
++
++        <li><a href="#Does.FreeTDS.support.Microsoft.servers">Does
++        FreeTDS support Microsoft servers?</a></li>
++
++        <li><a href="#How.can.I.get.help">How can I get help (or
++        support)?</a></li>
++
++        <li><a href="#Who.is.responsible.for.FreeTDS">Who is
++        responsible for FreeTDS?</a></li>
++
++        <li><a href="#license">Why LGPL license?</a></li>
++      </ul>
++    </li>
++
++    <li>Documentation
++
++      <ul>
++        <li><a href="#documentation">What sort of documentation is
++        available?</a></li>
++
++        <li><a href="#refman">What about a Programmer's Reference
++        Manual?</a></li>
++
++        <li><a href="#protocol">Is there any documentation for the
++        TDS protocol?</a></li>
++      </ul>
++    </li>
++
++    <li>Implementation
++
++      <ul>
++        <li><a href="#SYBASE">What's this SYBASE environment
++        variable for?</a></li>
++
++        <li><a href="#RPM">How do I install the RPM?</a></li>
++      </ul>
++    </li>
++
++    <li>Programming: C++, Sybperl, SQSH, &amp; PHP
++
++      <ul>
++        <li><a href="#compiling">How do
++        I compile Sybperl with FreeTDS?</a></li>
++
++        <li><a href="#compiling">How do I
++        compile SQSH with FreeTDS?</a></li>
++
++        <li><a href="#compiling">How do I
++        compile PHP 3 with FreeTDS?</a></li>
++
++        <li><a href="#Which.API">How should I choose among
++        <tt>db-lib</tt>, <tt>ct-lib</tt>, and
++        <tt>ODBC</tt>?</a></li>
++
++        <li><a href="#Which.Perl.library.should.I.use">Which Perl
++        library should I use?</a></li>
++
++        <li><a href="#Are.there.any.known.issues">Are there any
++        known issues?</a></li>
++
++        <li><a href="#pending">Why does each connection support
++        only one query at a time?</a></li>
++
++        <li><a href="#thread.safe">Is FreeTDS be thread
++        safe?</a></li>
++
++        <li><a href=
++        "#Are.there.plans.to.implement.the.OpenServer.protocol.library">
++        Are there plans to implement the OpenServer
++        protocol/library?</a></li>
++      </ul>
++    </li>
++
++    <li>Problems Running
++
++      <ul>
++        <li><a href="#syb.result.type">With <tt>DBD::Sybase</tt>,
++        why do I sometimes get an unexpected 1-column result
++        set?</a></li>
++
++         <li><a href="#ms.output.parameters">
++         I'm not getting my output parameters returned</a>, but I seem
++         to be doing everything right!</li>
++
++       <li><a href="#unknownmarker">What does this <tt>unknown
++        marker</tt> message mean?</a></li>
++
++        <li><a href="#connectionrefused">What if I get a
++        'connection refused' message?</a></li>
++
++        <li><a href="#integratedsecurity">The server is listening,
++        but logins fail? (MS SQL only)</a></li>
++
++        <li><a href="#textdata">My <tt>text</tt> data are being
++        truncated or are causing my client to break.</a></li>
++
++        <li><a href="#dateformat">My dates aren't formatted
++        right!</a></li>
++      </ul>
++    </li>
++  </ol>
++  <!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
++  <hr size="1" />
++
++  <h2>General Questions</h2>
++
++  <h3>What is FreeTDS?</h3>
++  	<a name="What.is.FreeTDS" id="What.is.FreeTDS"></a>
++
++  <p>FreeTDS is a free implementation of the TDS (Tabular Data
++  Stream) protocol that is used by Sybase and Microsoft for their
++  database products. It implements TDS 4.2, 5.0, 7.0 and
++  8.0, and can communicate with any Sybase or Microsoft SQL
++  Server.</p>
++
++  <p>FreeTDS comes with a low level library (the TDS layer) along
++  with a number of APIs (Application Programming Interfaces). The
++  APIs are DB-Lib, CT-Lib, and ODBC.</p>
++
++  <p>A JDBC driver has also been contributed under a BSDish license
++  and is available from the download page. It does not require the
++  FreeTDS C libraries.</p>
++
++  <h3>Where do I get FreeTDS?</h3>
++  	<a name="Where.do.I.get.FreeTDS" id="Where.do.I.get.FreeTDS"></a>
++
++  <p>You can get the latest FreeTDS from <a href=
++  "ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz">
++  Ibiblio</a> or its mirrors. See "Quick Links" on the <a href=
++  "/">FreeTDS</a> home page. You may also use
++  the <a href="http://sourceforge.net/cvs/?group.id=33106">CVS
++  repository</a> (on sourceforge.net); see the 
++  <a href="userguide/">User Guide</a> for details.</p>
++
++  <p>Your favorite operating system may have a package of some kind
++  available. You might want to check there. Occasionally someone
++  contributes a package here, which we keep around. Post a message
++  to the list if you're looking for one and don't find one in the
++  usual places.</p>
++
++  <h3>Does FreeTDS support Microsoft servers?</h3>
++  	<a name="Does.FreeTDS.support.Microsoft.servers"></a>
++
++  <p>Yes. Microsoft servers don't usually accept TDS 5.0
++  connections. Use one of versions 4.2, 7.0 or 8.0 of the protocol.
++  See the <a href=
++  "userguide/choosingtdsprotocol.htm">User
++  Guide</a> for details.</p>
++
++  <h3>How can I get help (or support)?</h3>
++	<a name="How.can.I.get.help" id="How.can.I.get.help"></a>
++	
++  <p>After reading this FAQ and the User Guide, you might want to
++  look at the mailing list <a href=
++  "http://lists.ibiblio.org/pipermail/freetds/">archives</a>. If
++  you don't see your question answered there (or, if you'd just
++  like to learn more about what's going on with FreeTDS), please
++  subscribe to the <a href=
++  "contact.html">mailing list</a>. Questions
++  new and old are cheerfully answered there. Traffic is not high,
++  normally around 10 messages a day.</p>
++
++  <p><i>Netiquette note</i>: It's considered poor form to mail
++  "help me" questions directly to the developers of <i>any</i> free
++  software project, this one included. Please direct your question
++  to the list, where someone with the available time and expertise
++  can help you.</p>
++
++  <h3>Who is responsible for FreeTDS?</h3>
++  	<a name="Who.is.responsible.for.FreeTDS" 
++	     id="Who.is.responsible.for.FreeTDS"></a>
++  <!-- table is due for an update, see AUTHORS file -->
++  <!-- table generated by /usr/pkgsrc/databases/freetds/work/freetds/./authors2html ("nospam." added later by hand)-->
++
++  <table summary="Who is responsible for FreeTDS">
++    <tr>
++      <td><a href="mailto:camber@nospam.ais.org">Brian
++      Bruns</a></td>
++
++      <td>Started this crazy thing</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:greggj@nospam.savvis.com">Gregg
++      Jensen</a></td>
++
++      <td>Message handlers and extra datatype support and some
++      sybperl stuff?</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:psaar@nospam.fenar.ee">Arno
++      Pedusaar</a></td>
++
++      <td>Donated his TDS4.2 code to the cause</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:misa@nospam.dntis.ro">Mihai
++      Ibanescu</a></td>
++
++      <td>GNUified the packet</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:cts@nospam.internetcds.com">Craig
++      Spannring</a></td>
++
++      <td>JDBC driver and CVS repository.</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:mark@nospam.champ.tstonramp.com">Mark
++      Schaal</a></td>
++
++      <td>Cleaned up message handling, bug fixes, ctlib
++      unittests</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:kevin@nospam.nol.org">Kevin
++      Lyons</a></td>
++
++      <td>Various TDS bug fixes</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:tetherow@nospam.nol.org">Sam
++      Tetherow</a></td>
++
++      <td>Various TDS bug fixes</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:geoff@nospam.farmline.com">Geoff
++      Winkless</a></td>
++
++      <td>Lost connection stuff</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:KenASeymour@nospam.yahoo.com">Ken
++      Seymour</a></td>
++
++      <td>ODBC Driver Fixes</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:gray@nospam.voicenet.com">Scott
++      Gray</a></td>
++
++      <td>TDS 7.0 numeric support and bug fixes</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:bkline@nospam.rksystems.com">Bob
++      Kline</a></td>
++
++      <td>NTEXT support</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:andrey@nospam.eller.cz">Koscheev
++      Andrey</a></td>
++
++      <td>negative money patch</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:nicklaus@nospam.crusher.fnal.gov">Dennis
++      Nicklaus</a></td>
++
++      <td>vxWorks port and fixes for dbdata() and SYBVARBINARY</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:breynolds@nospam.comtime.com">Brandon M.
++      Reynolds</a></td>
++
++      <td>fix for arbitrarily large queries under dblib.</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:vorlon@nospam.netexpress.net">Steve
++      Langasek</a></td>
++
++      <td>off by one fixes and autoconf byte size thing.</td>
++    </tr>
++
++    <tr>
++      <td><a href="mailto:mark@nospam.lilback.com">Mark J.
++      Lilback</a></td>
++
++      <td>implementation of dbstrlen and dbstrcpy</td>
++    </tr>
++
++    <tr>
++      <td colspan="2">Thanks go to the folks at A2i, Inc. <a href=
++      "http://www.a2i.com">http://www.a2i.com</a> for funding the
++      development of dblib host file bulk copy and writetext
++      support, and to Dave Poyourow there for helping with the
++      debugging.</td>
++    </tr>
++  </table><!-- end generated table -->
++
++  <p>(These addresses have been mangled to defy "spamaton" programs
++  that mindlessly collect email addresses from the web. To send
++  email to anyone listed above, delete the "nospam." part of the
++  address.)</p>
++
++  <h3>Why LGPL license?</h3>
++  	<a name="license" id="license"></a>
++
++  <p>Brian Bruns started the project, and that's the choice he
++  made. LGPL was chosen because if you want a commercial client,
++  you can buy them from Sybase, Microsoft or others. "I do believe
++  BSDish licenses are better in some cases, but not for something
++  like this," he said.</p>
++  <hr />
++  <!-- documentation -->
++
++  <h2>Documentation</h2>
++  	<a name="documentation" id="documentation"></a>
++
++  <h3>What sort of documentation is available?</h3>
++
++  <ul>
++    <li>The FreeTDS <a href="userguide/">User Guide</a> 
++    	is the best place to start.</li>
++
++    <li>FreeTDS , on <a href=
++    "reference/">Reference Manual</a> is a
++    beginning at an independent description of the client APIs and
++    the TDS layer.</li>
++  </ul><a name="refman" id="refman"></a>
++
++  <h3>What about a Programmer's Reference Manual?</h3>
++
++  <p>The best information is available from the vendors. FreeTDS
++  means to conform to the documented (and, in some cases,
++  undocumented) behavior of the vendors' offerings.</p>
++
++  <ul>
++    <li><a href=
++    "http://www.microsoft.com/sql/productdoc/">Microsoft's Books
++    Online</a>.</li>
++    <!-- goes to http://www.microsoft.com/sql/techinfo/productdoc/2000/default.asp -->
++    <!-- valid as at 12th november 2001 -->
++
++    <li><a href=
++    "http://www.SchemaMania.org/jkl/booksonline/SQLBOL70/">Microsoft
++    Documentation</a> converted to HTML.</li>
++
++    <li><a href="http://www.sybase.com/support/manuals">Sybase's
++    Product Manuals</a>.</li>
++    <!-- valid as at 12th november 2001 -->
++  </ul>
++
++  <h3>Is there any documentation on the TDS protocol?</h3>
++  	<a name="protocol" id="protocol"></a>
++
++  <p>Yes, there is some <a href="tds.html">preliminary
++  documentation</a> available. The most up to date version is in
++  the User Guide.</p>
++
++  <p>Sybase publishes its <a href="http://www.sybase.com/content/1040983/Sybase-tds38-102306.pdf" >TDS 5.0 Functional Specification</a>.</p>
++  <hr />
++  <!-- Implementation -->
++
++  <h2>Implementation</h2>
++  	<a name="SYBASE" id="SYBASE"></a>
++
++  <h3>What is this <code>SYBASE</code> environment variable?</h3>
++
++  <p>Many programs look for the <var>SYBASE</var> environment
++  variable in order to find the library's home. You will want to
++  set this to the main FreeTDS directory. For example, if
++  <code>FreeTDS</code> is installed in <tt>/usr/local/freetds</tt>
++  (meaning the libraries were installed in
++  <tt>/usr/local/freetds/lib</tt>), then your <var>SYBASE</var>
++  variable would be set to <tt>/usr/local/freetds</tt>.</p>
++
++  <h3>How do I install the RPM?</h3>
++  	<a name="RPM" id="RPM"></a>
++
++  <p><tt>rpm -ivh freetds-0.52-1.i386.rpm</tt> (as root) will
++  install the libraries.</p>
++
++  <p><tt>rpm -ivh freetds-devel-0.52-1.i386.rpm</tt> (as root) will
++  install the headers and other stuff needed to build other
++  stuff.</p>
++  <hr />
++  <!-- Programming -->
++
++  <h2>Programming: C++, Sybperl, SQSH, &amp; PHP</h2>
++  	<a name="compiling" id="compiling"></a>
++  
++  <h3>How do I compile Sybperl with FreeTDS?</h3>
++  <h3>How do I compile SQSH with FreeTDS?</h3>
++  <h3>How do I compile PHP 3 with FreeTDS?</h3>
++
++  <p>Please refer to the <a href="userguide/">User Guide</a>.</p>
++
++  <p>One small PHP hint, mailed to the FAQ master in May 2001:</p>
++
++  <p>In the mailing list archives I noticed a few people discussing
++  a problem I just had.</p>
++
++  <blockquote>
++    <p>An attempt to make a connection to a MS SQL server from PHP
++    would fail, leaving a message in the Apache error log:</p>
++    <pre>
++        "connect: Network is unreachable
++         DB-Library: Login incorrect"
++</pre>
++
++    <p>The problem turned out to be a very simple one to fix. In
++    the php.ini file under the sybase section, there is a directive
++    that sets the path to the sybase interfaces file
++    "sybase.interface_file = "</p>
++
++    <p>After uncommenting this and setting it to a reasonable value
++    (ie. /usr/local/freetds/interfaces), things started
++    working.</p>
++  </blockquote><a name="Which.API" id="Which.API"></a>
++
++  <h3>How should I choose among <tt>db-lib</tt>, <tt>ct-lib</tt>,
++  and <tt>ODBC</tt></h3>
++
++  <p><tt>FreeTDS</tt> offers three client libraries and one
++  internal one (<tt>libtds</tt>). We generally encourage people to
++  use one of the client libraries, and discourage writing to
++  <tt>libtds</tt>, because the latter is evolving, more subject to
++  change, less well documented, and harder to use. In choosing
++  which client API to write to, you might want to peruse our
++  <a href="which_api.html">brief discussion</a>. </p>
++
++  <h3>Which Perl library should I use?</h3>
++	<a name="Which.Perl.library.should.I.use" 
++	     id="Which.Perl.library.should.I.use"></a>
++
++  <p>There are four options for using TDS and Perl to connect to a
++  Sybase or MSSQL database, DBD::Sybase, DBD::ODBC, DBD::FreeTDS,
++  and Sybperl.</p>
++
++  <p>From Mark Schaal:<br /></p>
++
++  <p>DBD::Sybase is the recommended option, and yes it does work
++  with MSSQL. You will need to install the perl DBI module and the
++  FreeTDS package, particularly the CTLib portion. Set your SYBASE
++  environment variable to /usr/local/freetds and install
++  DBD::Sybase. Don't worry too much if some of the tests fail. Do
++  worry if the module doesn't compile. Make sure you have the most
++  recent version of FreeTDS installed. You can check the <a href=
++  "http://lists.ibiblio.org/pipermail/freetds/">mailing list
++  archives</a> or ask the mailing list for help.</p>
++
++  <p>DBD::FreeTDS does not depend on the FreeTDS libraries. It is
++  minimally functional but it is considered alpha software and is
++  not being actively developed.</p>
++
++  <p>From <a href="mailto:mpeppler@peppler.org">Michael
++  Peppler</a>:<br />
++  Sybperl is a thin wrapper around the Sybase C APIs. It's a lot
++  more mature than DBI/DBD::Sybase (I've been working on it for 9
++  years :-) and it's maybe more natural to use for someone who
++  already knows the Sybase APIs (or MS's DBlibrary). It's a little
++  more powerful/flexible than DBI, though obviously less portable.
++  It's still actively maintained and developed (by yours truly)</p>
++
++  <p>From Brian:<br />
++  DBD::ODBC is the newest option available. Its primary advantage
++  is not having to load another DBI driver if you already have
++  DBI::ODBC load for other systems. On the downside, it may be a
++  little less robust than DBD::Sybase.</p>
++
++  <h3>Are there any known issues?</h3>
++  	<a name="Are.there.any.known.issues" 
++	     id="Are.there.any.known.issues"></a>
++  <ul>
++    <li>ODBC can be confusing to set up. See the <tt>samples</tt>
++    directory for example <tt>.ini</tt> files, and follow the User
++    Guide's instructions carefully.</li>
++
++    <li>BCP of text and image types is broken for
++    Microsoft servers.</li>
++
++    <li>BCP does not support TDS 4.2. You must use a more modern
++    protocol version.</li>
++
++    <li>Server-side cursors work only in ct-lib.</li>
++
++    <li>ODBC lacks a client-side cursor implementation.</li>
++
++    <li>DBD::Sybase dynamic SQL placeholders don't work, pending a client-side SQL parser.  (The ODBC ones do.)</li>
++
++    <li>There are no plans to implement db-lib's browse mode.</li>
++  </ul>
++
++  <p>Errors can sometimes be confusing. When an application uses
++  the library incorrectly, or when there are problems in a data
++  file being uploaded with BCP, the message returned by FreeTDS can
++  sometimes be misleading. In the latter case, it's often necessary
++  to examine the log file to understand what went wrong. </p>
++
++  <h3>Why does each connection support only one query at a time?</h3>
++	<a name="pending" id="pending"></a>
++
++  <p>If you are accustomed to programming with other database
++  servers, you may be surprised when you first encounter this
++  aspect of the TDS protocol. When a TDS server&mdash;be it by
++  Microsoft or Sybase&mdash;responds to a query, it may send a result
++  set to the client. The server does not construct a complete
++  result set first, unless it needs to (say, to execute an
++  <tt>ORDER BY</tt> clause). Instead, it sends the rows as they're
++  selected/formed, in real time (if you will). Likewise, the client
++  libraries do <i>not</i> read all the rows from the server before
++  making them available to the client application.</p>
++
++  <p>The client library is tightly coupled to the server; they are
++  synchronized, share state information. The server requires the
++  client either to read all the results from a query, or to
++  indicate that no further rows are desired i.e., to issue a
++  cancellation. Until one of those two things happens, the server
++  will not accept new queries on that connection. It will complain
++  about "pending results".</p>
++
++  <p>How do mortal programmers cope with this strict
++  one-query-at-a-time limitation? For one thing, they become better
++  programmers.</p>
++
++  <ul>
++    <li>The solution often involves doing more SQL work, which
++    often results in less interaction with the server, which is
++    almost always faster.</li>
++
++    <li>Even when that's not true, there's nothing to prevent the
++    application from caching the whole results set in its own
++    collection object.</li>
++
++    <li>Sometimes, the best answer is to open a new connection.
++    That's not as bad as it sounds, and it certainly not unheard of
++    to have 4 or more simultaneous connections supporting an
++    application.</li>
++  </ul>It's important to realize that the selection of rows and
++  their accumulation into a container of some sort are two
++  different functions. A TDS server issues its results a row at a
++  time, which the client library dutifully makes available to the
++  application on arrival. It's up to the application&mdash;or a
++  higher-level library&mdash;to form a "rowset" of some kind if
++  desired.
++
++  <h4>PHP note</h4>If you use PHP, you will still run into this
++  problem even if you create a new connection. The reason is that
++  PHP is so nice that it will re-use the first connection if you
++  connect again with the same parameters. You my wish to refer to
++  <a href=
++  "http://lists.ibiblio.org/pipermail/freetds/2003q3/013915.html">this
++  post</a> by Daniel Fazekas in the mailing list archives. 
++
++  <h3>Is FreeTDS thread safe?</h3>
++	<a name="thread.safe" id="thread.safe"></a>
++
++  <p>Different threads may all use separate connections without
++  interfering with each other. Threads may not share a DBPROCESS or
++  CS_CONNECTION without controlling access via a mutex.</p>
++
++  <h3>Are there plans to implement the OpenServer protocol/library?</h3>
++  	<a name="Are.there.plans.to.implement.the.OpenServer.protocol.library"></a>
++
++  <p>Not at this point, there is still much work to do on the
++  client protocol. But, <tt>libtdssrv</tt> will do the trick for
++  some applications.</p>
++  <hr />
++  <!-- RUNNING -->
++
++  <h2>Problems Running</h2>
++
++  <h3>With <tt>DBD::Sybase</tt>, why do I sometimes get an
++  unexpected 1-column result set?</h3>
++  	<a name="syb.result.type" id="syb.result.type"></a>
++
++  <p>Use a more recent release of FreeTDS. This problem was
++  corrected with version 0.63.</p>
++
++  <h3>Output Parameters</h3>
++	<a name="ms.output.parameters" id="ms.output.parameters"></a>
++	
++  <p><i>I'm not getting my output parameters returned, but I seem
++         to be doing everything right!</i> </p> 
++  <p>That's not a question!</p>
++  <p>Microsoft SQL Server 7 with SP3, and later versions, quietly changed (which is to say, broke) how they respond to queries that execute stored procedures with output parameters.  Earlier servers let you send a query like <font size="-1"><code>EXECUTE A @P OUTPUT</code></font> and fetch the output parameter as a special result row (technique varying by library).  Newer servers simply don't send back that data.  To elicit output parameters from them, you have to use the RPC protocols such as the db-lib <a href="reference/a00336.html#a129">dbrpcparam</a>.  
++  </p>
++         
++  <h3>What does this <tt>unknown marker</tt> message mean?</h3>
++	<a name="unknownmarker" id="unknownmarker"></a>  
++
++  <p>Most of the time, it means you're not using the right protocol
++  version. That <i>can</i> happen even if your <tt>./configure</tt>
++  was done correctly. Try setting the <tt>TDSVER</tt> variable to a
++  value appropriate for your server: normally <code>5.0</code> for
++  Sybase and <code>7.0</code> for Microsoft. If that works, double
++  check your work. If your <kbd>freetds.conf</kbd> file and
++  <kbd><strong>configure</strong></kbd> options were right, but you
++  needed the environment variable anyway, please post a message to
++  the list and help us track it down.</p>
++
++  <h3>What if I get a <tt><font size="+1">connection
++      refused</font></tt> message?</h3>
++	<a name="connectionrefused" id="connectionrefused"></a>
++
++  <p>You want to make sure:</p>
++
++  <ul>
++    <li>your server is running,</li>
++
++    <li>you can connect to it,</li>
++
++    <li>your account has permissions in the database to execute
++    your query.</li>
++  </ul>
++
++  <p>Steps:</p>
++
++  <ol>
++    <li>Try <tt><b>telnet <i>hostmachine port</i></b></tt> and
++    see if it's listening. You should get some form of response
++    from the server (actual text varies by vendor &amp;
++    version).<br /></li>
++
++    <li>
++      <p>Try <kbd><b>tsql -H <i>hostmachine</i> -p <i>port</i> -U
++      <i>username</i> -P <i>password</i></b></kbd></p>
++
++      <p>That will connect to the server, bypassing the
++      freetds.conf file. If it doesn't work, the problem lies
++      upstream.</p></li>
++
++    <li>
++      <p>Try <kbd><b>tsql -S <i>servername</i> -p <i>port</i> -U
++      <i>username</i> -P <i>password</i></b></kbd></p>
++
++      <p>That will connect to the server using freetds.conf. This
++      allows you to isolate freetds.conf mistakes. <kbd>man
++      tsql</kbd> for more.</p></li>
++
++    <li>Check your ./configure and environment variables. The
++    <tt>--with-tdsver</tt> determines what flavor of the TDS
++    protocol your runs by default; the $TDSVER variable overrides
++    that default. The following combinations are reasonable; see
++    the <a href="userguide/">User Guide</a>
++    for details:</li>
++
++    <li style="list-style: none">
++      <table summary="TDS Protocol Versions">
++        <tr>
++          <td><b>Vendor</b></td>
++
++          <td><b>Version</b></td>
++
++          <td><b>TDS Version</b></td>
++        </tr>
++
++        <tr>
++          <td>Sybase</td>
++
++          <td>4.92+&nbsp;</td>
++
++          <td>5.0</td>
++        </tr>
++
++        <tr>
++          <td>Microsoft</td>
++
++          <td>6.0, 6.5</td>
++
++          <td>4.2</td>
++        </tr>
++
++        <tr>
++          <td>Microsoft</td>
++
++          <td>7.0/2000</td>
++
++          <td>7.0</td>
++        </tr>
++      </table>
++    </li>
++
++    <li>
++      <p>Edit the <b><tt>PWD</tt></b> file and try <tt>make
++      check</tt>. It will call unittests for libtds, ctlib, dblib
++      and odbc in that order</p>
++    </li>
++
++    <li>
++      <p>Compile <font size="+1"><tt><a href=
++      "http://www.sqsh.org">sqsh</a></tt></font> and try that
++      before the more complicated stuff (PHP/Perl). If you can
++      connect with <tt>sqsh</tt>, you don't have a FreeTDS
++      problem.</p>
++    </li>
++  </ol>
++
++  <h3>The Microsoft SQL Server is listening, my configuration and
++      environment are set up per question 6.1, but logins still
++      fail.</h3>
++	<a name="integratedsecurity" id="integratedsecurity"></a>
++
++  <p>Microsoft supports two security models in three
++  permutations:</p>
++
++  <ol>
++    <li>Windows NT Authentication Mode (Windows NT
++    Authentication)</li>
++
++    <li>Standard Mode (SQL Server Authentication)</li>
++
++    <li>Mixed Mode (Windows NT Authentication and SQL Server
++    Authentication)</li>
++  </ol>
++
++  <p>"Windows NT Authentication", often called "integrated
++  security", relies on Microsoft's domain logins, which establish a
++  user's network security attributes at network login time. When
++  connecting to the database server, SQL Server accepts an
++  encrypted password in the login packet, and uses Windows NT
++  facilities authenticate it, usually via the Primary Domain
++  Controller (PDC). The server then permits or denies login access
++  based on the response.</p>
++
++  <p>With traditional "Standard Mode" authentication, usernames and
++  passwords are stored within SQL Server. They are passed in the
++  login packet as plaintext, and connection requests are
++  authenticated without consulting the operating system.</p>
++
++  <p>FreeTDS supports both security models. Domain logins are
++  recognized by the presence of a backslash (\) character in the
++  username. See the <a href=
++  "userguide/domains.htm">User Guide</a> for
++  details. <a name="textdata" id="textdata"></a></p>
++
++  <h3>My <tt>text</tt> data are being truncated or are causing my
++  client to break.</h3>
++
++  <p>The <tt>text</tt> data type is different from <tt>char</tt>
++  and <tt>varchar</tt> types. The maximum data length of a
++  <tt>text</tt> column is governed by the <tt>textsize</tt>
++  variable on the server. Microsoft <i>claims</i> in their
++  documentation to use a default <tt>textsize</tt> of 4000
++  characters, but in fact their implementation is inconsistent.
++  Sometimes <tt>text</tt> columns are returned with a size of 4
++  GB!</p>
++
++  <p>The best solution is to make sure you set <tt>textsize</tt> to
++  a reasonable value when establishing a connection. For
++  example:</p><!-- example set textsize 1000 (see UG) -->
++  <pre class="screen">
++<tt class="userinput">
++<b>set <tt class="envar">textsize</tt> 10000</b></tt>
++</pre>
++
++  <h3>My dates aren't formatted right!</h3>
++  	<a name="dateformat" id="dateformat"></a>
++
++  <p>Some dates turn out better than others.</p>
++
++  <p>If you think your dates should look like <em>2001-12-13
++  17:58:55.000</em>, but you're seeing something like <em>Dec 13
++  2001 05:58PM</em> instead (or vice versa), you've bumped into
++  driver behavior. There's no standard governing the default
++  character string representation of a <code>datetime</code>
++  datatype. Different drivers make different choices, and your
++  driver has chosen a representation for you.</p>Microsoft's ODBC
++  driver (which is used by among other things the Query Analyzer
++  tool) converts <tt>datetime</tt> to an ISO format. That format
++  has the advantages of being all numeric: sortable, unambiguous,
++  and locale-independent. The vendors' <code>db-lib</code> and
++  <code>ct-lib</code>, in contrast, use the <code>MMM DD YYYY
++  hh:mm</code> format.
++
++  <p>If you want to be sure your queries always return dates in a
++  particular format, don't leave the formatting up to the driver!
++  Use the <code>convert</code> function. For example:</p>
++  <!-- example convert  -->
++  <pre class="screen">
++<tt class="userinput">
++1&gt; <b>select convert( varchar(30), getdate(), 120 ) as Now</b>
++2&gt; <b>go</b>
++ Now
++ ------------------------------
++ 2002-07-02 12:36:31
++</tt>
++</pre>
++
++  <p>As of version 0.60, the default datetime-&gt;string conversion
++  is controlled by the <code>locale.conf</code> file. See the User
++  Guide for details.</p><!-- footer -->
++  <hr size="1" />
++  <font size="-1">Updates and comments <a href=
++  "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a></font>
++<hr/>
++  <p>
++    <a href="http://validator.w3.org/check?uri=referer"><img
++        src="http://www.w3.org/Icons/valid-xhtml10"
++        alt="Valid XHTML 1.0 Transitional" height="31" width="88" /></a>
++  </p>
++</body>
++</html>
+diff --git b/doc/htdoc/news.html a/doc/htdoc/news.html
+new file mode 100644
+index 0000000..ed0a8a9
+--- /dev/null
++++ a/doc/htdoc/news.html
+@@ -0,0 +1,239 @@
++<?xml version="1.0" encoding="iso-8859-1" ?>
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
++<html xmlns="http://www.w3.org/1999/xhtml">
++<!-- $Id: news.html,v 1.10 2007/08/09 07:52:08 freddy77 Exp $ -->
++<head>
++<title>FreeTDS.org</title>
++</head>
++<body bgcolor="#f9f9f9">
++
++<!-- generic header -->
++<table summary="table of contents" width="100%">
++<tr>
++<td><img src="freetdslogo3.gif" alt="FreeTDS.org" /></td>
++<td align="right" valign="bottom">
++<a href="index.html">Home</a>&nbsp;&nbsp;|&nbsp;
++News&nbsp;&nbsp;|&nbsp;
++<a href="software.html">Software</a>&nbsp;&nbsp;|&nbsp;
++<a href="docs.html">Documentation</a>&nbsp;&nbsp;|&nbsp;
++<a href="support.html">Support</a>&nbsp;&nbsp;|&nbsp;
++<a href="contrib.html">Contribute</a>
++</td>
++</tr>
++</table>
++<hr size="1" noshade="noshade" />
++
++
++<!-- page specific content -->
++<p align="center">
++<font size="+3"><b>N</b></font>ews and <font size="+3"><b>P</b></font>ress
++</p>
++<table summary="layout" width="80%" align="center">
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.63</td></tr>
++<tr>
++<td>
++<br />
++Version 0.63 is now available.  The source tarball is <tt><a href="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-0.63.tar.gz">freetds-0.63.tar.gz</a></tt> on Ibiblio.  You may wish to read the <a href="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/ANNOUNCEMENT">announcement</a>.  (30 April 2005)   
++<br />
++<br />
++</td>
++</tr>
++
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.63 branch </td></tr>
++<tr>
++<td>
++<br />
++Version 0.63RC1 is now available in the <tt><a href="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/">stable</a></tt> directory on Ibiblio.  Enjoy,and please test on your favorite architecture.  
++(27 November 2004)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.62.1 </td></tr>
++<tr>
++<td>
++<br />
++Includes a small but significant fix to token.c.  <a href="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz">Version 0.62.1</a> 
++(15 Jan  2004)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.62 </td></tr>
++<tr>
++<td>
++<br />
++In the year since the last release, FreeTDS has seen many improvements.  <a href="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-0.62.tar.gz">Version 0.62</a> includes:
++<ul>
++<li>UTF-8 support, as well as most other client-side character sets</li>
++<li>ODBC 3.0 compliance</li>
++<li>many new ODBC functions</li>
++<li>cursors, array binding, dynamic SQL, and RPC support in ct-lib</li>
++<li>improved network performance through better socket and packet handling.</li>
++<li>more Win32 development choices; VMS support</li>
++</ul>
++(11 Jan  2004)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Release Candidate 2 for Version 0.62 </td></tr>
++<tr>
++<td>
++<br />
++We are in the process of releasing version 0.62.  See <a href="index.html">main page</a> for the latest release candidate (5 Jan  2004)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.61.2 </td></tr>
++<tr>
++<td>
++<br />
++This point release fixes some memory leaks.  (3 August 2003)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.61.1 </td></tr>
++<tr>
++<td>
++<br />
++This point release offers bugfixes:
++	<ul>
++		<li>Segmentation fault with iODBC</li>
++		<li>Segmentation fault opening log file in append mode</li>
++		<li>binding parameters with NULL indicator</li>
++	</ul>
++	(20 May 2003)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.61 </td></tr>
++<tr>
++<td>
++<br />
++This release supersedes version 0.60 in all respects.  It addresses all known
++bugs except one, see README for details.  Read the <a href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/stable/announcement">announcement</a> and try out the new features.  (1 March 2003)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.61 Release Candidate </td></tr>
++<tr>
++<td>
++<br />
++Try out the new features.  (20 February 2003)   
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS and PHP in Linux Journal</td></tr>
++<tr>
++<td>
++<br />
++A recent <a href="http://www.linuxjournal.com/article.php?sid=6636&amp;mode=thread&amp;order=0&amp;thold=0">online article</a> by David Perrin in the <a href="http://www.linuxjournal.com">Linux Journal</a> describes his good fortune using FreeTDS to connect his PHP-based web server to a Microsoft SQL Server. 
++<br />
++<br />
++</td>
++</tr>
++
++<tr bgcolor="#c9c9ff"><td>FreeTDS proudly announces Version 0.60</td></tr>
++<tr>
++<td>
++<br />
++The new version has better datatype handling and conversion capabilities, better BCP, better compatibility with Microsoft SQL Server 2000.  It's just way better.  More people have joined the project, and more better things are still in store.  Read the <a href="README.0.60">announcement</a> and try out the new features.  (11 September 2002)   
++<br />
++<br />
++</td>
++</tr>
++
++
++
++<tr bgcolor="#c9c9ff"><td>FreeTDS and DBD::Sybase in Linux Journal</td></tr>
++<tr>
++<td>
++<br />
++This month's (April 2002) <a href="http://www.linuxjournal.com">Linux Journal</a> has an article about using DBD::Sybase and FreeTDS to talk to Microsoft SQL Server by Andrew Trice. 
++<br />
++<br />
++</td>
++</tr>
++<tr bgcolor="#c9c9ff"><td>FreeTDS.org gets a new look</td></tr>
++<tr>
++<td>
++<br />
++FreeTDS.org has been redesigned to provide new users an easier time of finding the resources they need to use FreeTDS successfully.  Any comments (good or bad) should be directed to the <a href="http://franklin.oit.unc.edu/cgi-bin/lyris.pl?enter=freetds">Mailing List</a>.
++<br />
++<br />
++</td>
++</tr>
++<tr bgcolor="#c9c9ff"><td>CVS moves to SourceForge</td></tr>
++<tr>
++<td>
++<br />
++The CVS repository has been moved to the FreeTDS project on <a href="http://sourceforge.net/projects/freetds/">SourceForge</a>.  The old repository will stay active indefinately for tracking historical changes as the new repository starts with 0.53pre1.  Consult the <a href="faq.html">FAQ</a> for details on using the new repository.
++<br />
++<br />
++</td>
++</tr>
++<tr bgcolor="#c9c9ff"><td>FreeTDS version 0.53pre1</td></tr>
++<tr>
++<td>
++<br />
++FreeTDS 0.53pre1 is now available at iBiblio.org  and it's mirrors. This release fixes some nasty host lookup bugs with 0.52 and it is recommend for those having troubles connecting with 0.52.  This is a tarball-only release;  RPM packages will be available with the full 0.53 release.
++<br />
++<br />
++</td>
++</tr>
++<tr bgcolor="#c9c9ff"><td>FreeTDS version 0.52</td></tr>
++<tr>
++<td>
++<br />
++FreeTDS 0.52 is now available at iBiblio.org and it's mirrors. Both the source distribution and RPMs for Linux (i386) are available. Major features include a new configuration file format, much better ODBC support, and bug fixes. An announcement and some release notes are also available.
++<br />
++<br />
++</td>
++</tr>
++<tr bgcolor="#c9c9ff"><td>The FreeTDS User Guide</td></tr>
++<tr>
++<td>
++<br />
++The FreeTDS Users Guide is an effort to provide better documentation for the FreeTDS user community, if it doesn't answer all your questions please submit your solutions so they may be included for the next person.
++<br />
++<br />
++</td>
++</tr>
++<tr bgcolor="#c9c9ff"><td>FreeTDS Article on PHPBuilder</td></tr>
++<tr>
++<td>
++<br />
++<a href="http://www.phpbuilder.com">PHPBuilder</a> has an <a href="http://www.phpbuilder.com/columns/alberto20000919.php3">article</a> on accessing SQL Server from Linux in which FreeTDS figures prominently.  And it even points out some areas for us to improve in. ;-)
++<br />
++<br />
++</td>
++</tr>
++</table>
++
++</body>
++</html>
+diff --git b/doc/htdoc/support.html a/doc/htdoc/support.html
+new file mode 100644
+index 0000000..0f67f31
+--- /dev/null
++++ a/doc/htdoc/support.html
+@@ -0,0 +1,53 @@
++<?xml version="1.0" encoding="iso-8859-1" ?>
++<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
++<html xmlns="http://www.w3.org/1999/xhtml">
++<!-- $Id: support.html,v 1.3 2007/08/09 07:52:08 freddy77 Exp $ -->
++<head>
++<title>FreeTDS.org</title>
++</head>
++<body bgcolor="#f9f9f9">
++
++<!-- generic header -->
++<table summary="table of contents" width="100%">
++<tr>
++<td><img src="freetdslogo3.gif" alt="FreeTDS.org" /></td>
++<td align="right" valign="bottom">
++<a href="index.html">Home</a>&nbsp;&nbsp;|&nbsp;
++<a href="news.html">News</a>&nbsp;&nbsp;|&nbsp;
++<a href="software.html">Software</a>&nbsp;&nbsp;|&nbsp;
++<a href="docs.html">Documentation</a>&nbsp;&nbsp;|&nbsp;
++Support&nbsp;&nbsp;|&nbsp;
++<a href="contrib.html">Contribute</a>
++</td>
++</tr>
++</table>
++<hr size="1" noshade="noshade" />
++
++
++<!-- page specific content -->
++<p align="center">
++<font size="+3"><b>S</b></font>upport
++</p>
++<table summary="layout" width="80%" align="center">
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++The first place you should look to resolve your problem is the <a href="docs.html">documentation</a>
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++The next step is to subscribe and post a question to the <a href="http://lists.ibiblio.org/pipermail/freetds/">Mailing List </a>.  Please read the <a href="http://www.freetds.org/userguide/help.html">Getting Help</a> section of the User Guide to ensure that the folks on the list can isolate and fix your problem.
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++<i>Note:</i> I often see people post what are really FreeTDS questions in a variety of forums such as the PHP list, LUG lists, and Usenet groups.  Many times these queries go unanswered because no one in those forums knows FreeTDS. Your best bet for getting answers will generally be the FreeTDS mailing list. (I know this seems obvious, but you'd be surprised).
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++<tr><td>
++<font color="red">Blatant commercial plug!</font>
++If you are interested in having someone install and configure FreeTDS for you, you can contact <a href="mailto:camber@ais.org">Brian Bruns (camber@ais.org)</a>, the original author of FreeTDS, who offers consulting, custom programming, and support contracts for FreeTDS.
++</td></tr>
++<tr><td>&nbsp;</td></tr>
++</table>
++
++</body>
++</html>
+diff --git b/doc/txt2man a/doc/txt2man
+new file mode 100755
+index 0000000..ed5a6a4
+--- /dev/null
++++ a/doc/txt2man
+@@ -0,0 +1,314 @@
++#!/bin/sh
++test "$HOME" = ~ || exec ksh $0 "$@"    # try ksh if sh too old (not yet POSIX)
++
++# Copyright (C) 2001, 2002, 2003 Marc Vertes
++
++# This program is free software; you can redistribute it and/or modify
++# it under the terms of the GNU General Public License as published by
++# the Free Software Foundation; either version 2, or (at your option)
++# any later version.
++
++# This program is distributed in the hope that it will be useful,
++# but WITHOUT ANY WARRANTY; without even the implied warranty of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++# GNU General Public License for more details.
++
++# You should have received a copy of the GNU General Public License
++# along with this program; if not, write to the Free Software
++# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
++# 02111-1307, USA.
++
++# txt2man-1.4.8
++
++usage()
++{
++cat << EOT
++NAME
++  txt2man - convert flat ASCII text to man page format
++SYNOPSIS
++  txt2man [-hpTX] [-t mytitle] [-P pname] [-r rel] [-s sect] 
++          [-v vol] [-I txt] [-B txt] [ifile] 
++DESCRIPTION
++  txt2man converts the input text into nroff/troff standard man(7)
++  macros used to format Unix manual pages. Nice pages can be generated
++  specially for commands (section 1 or 8) or for C functions reference
++  (sections 2, 3), with the ability to recognize and format command and
++  function names, flags, types and arguments.
++
++  txt2man is also able to recognize and format sections, paragraphs,
++  lists (standard, numbered, description, nested), cross references and
++  literal display blocks.
++
++  If input file ifile is omitted, standard input is used. Result is
++  displayed on standard output.
++
++  Here is how text patterns are recognized and processed:
++  Sections    These headers are defined by a line in upper case, starting
++              column 1. If there is one or more leading spaces, a
++	      sub-section will be generated instead.
++  Paragraphs  They must be separated by a blank line, and left aligned.
++  Tag list    The item definition is separated from the item description 
++              by at least 2 blank spaces, even before a new line, if
++              definition is too long. Definition will be emphasized
++              by default.
++  Bullet list  
++              Bullet list items are defined by the first word being "-"
++	      or "*" or "o".
++  Enumerated list  
++	      The first word must be a number followed by a dot.
++  Literal display blocks  
++	      This paragraph type is used to display unmodified text,
++	      for example source code. It must be separated by a blank
++	      line, and be indented. It is primarily used to format
++	      unmodified source code. It will be printed using fixed font
++	      whenever possible (troff).
++  Cross references  
++	      A cross reference (another man page) is defined by a word
++	      followed by a number in parenthesis.
++
++  Special sections:
++  NAME      The function or command name and short description are set in 
++            this section.
++  SYNOPSIS  This section receives a special treatment to identify command
++            name, flags and arguments, and propagate corresponding
++            attributes later in the text. If a C like function is recognized
++	    (word immediately followed by an open parenthesis), txt2man will 
++	    print function name in bold font, types in normal font, and 
++	    variables in italic font. The whole section will be printed using
++	    a fixed font family (courier) whenever possible (troff).
++
++  It is a good practice to embed documentation into source code, by using 
++  comments or constant text variables. txt2man allows to do that, keeping
++  the document source readable, usable even without further formatting
++  (i.e. for online help) and easy to write. The result is high quality 
++  and standard complying document.
++OPTIONS
++  -h          The option -h displays help.
++  -P pname    Set pname as project name in header. Default to uname -s.
++  -p          Probe title, section name and volume.
++  -t mytitle  Set mytitle as title of generated man page.
++  -r rel      Set rel as project name and release.
++  -s sect     Set sect as section in heading, ususally a value from 1 to 8.
++  -v vol      Set vol as volume name, i.e. "Unix user 's manual".
++  -I txt      Italicize txt in output. Can be specified more than once.
++  -B txt      Emphasize (bold) txt in output. Can be specified more than once.
++  -T          Text result previewing using PAGER, usually more(1).
++  -X          X11 result previewing using gxditview(1).
++ENVIRONMENT
++  PAGER    name of paging command, usually more(1), or less(1). If not set
++           falls back to more(1).
++EXAMPLE
++  Try this command to format this text itself:
++
++      $ txt2man -h 2>&1 | txt2man -T
++HINTS
++  To obtain an overall good formating of output document, keep paragraphs
++  indented correctly. If you have unwanted bold sections, search for
++  multiple spaces between words, which are used to identify a tag list
++  (term followed by a description). Choose also carefully the name of
++  command line or function parameters, as they will be emphasized each
++  time they are encountered in the document.
++SEE ALSO
++  man(1), mandoc(7), rman(1), groff(1), more(1), gxditview(1), troff(1).
++BUGS
++  - Automatic probe (-p option) works only if input is a regular file (i.e.
++  not stdin).
++AUTHOR
++  Marc Vertes <mvertes@free.fr>
++EOT
++}
++
++sys=$(uname -s)
++rel=
++volume=
++section=
++title=untitled
++doprobe=
++itxt=
++btxt=
++post=cat
++while getopts :hpTXr:s:t:v:P:I:B: opt
++do
++	case $opt in
++	r) rel=$OPTARG;;
++	t) title=$OPTARG;;
++	s) section=$OPTARG;;
++	v) volume=$OPTARG;;
++	P) sys=$OPTARG;;
++	p) doprobe=1;;
++	I) itxt="$OPTARG§$itxt";;
++	B) btxt=$OPTARG;;
++	T) post="groff -mandoc -Tlatin1 | ${PAGER:-more}";;
++	X) post="groff -mandoc -X";;
++	*) usage; exit;;
++	esac
++done
++shift $(($OPTIND - 1))
++
++if test "$doprobe"
++then
++	title=${1##*/}; title=${title%.txt}
++	grep -q '#include ' $1 && 
++		{ section=${section:-3}; 
++		  volume=${volume:-"$sys Programmer's Manual"}; } || 
++		{ section=${section:-1}; 
++		  volume=${volume:-"$sys Reference Manual"}; }
++	# get release from path
++	rel=$(pwd | sed 's:/.*[^0-9]/::g
++	s:/.*::g')
++fi
++
++head=".\\\" Text automatically generated by txt2man-1.4.7
++.TH $title $section \"$(date +'%B %d, %Y')\" \"$rel\" \"$volume\""
++
++# All tabs converted to spaces
++expand $* | 		
++# gawk is needed because use of non standard regexp
++gawk --re-interval -v head="$head" -v itxt="$itxt" -v btxt="$btxt"  '
++BEGIN {
++	print head
++	avar[1] = btxt; avar[2] = itxt
++	for (k in avar) {
++		mark = (k == 1 ? "\\fB" : "\\fI")
++		split(avar[k], tt, "§")
++		for (i in tt)
++			if (tt[i] != "")
++				subwords["\\<" tt[i] "\\>"] = mark tt[i] "\\fP"
++		for (i in tt) delete tt[i]
++	}
++	for (k in avar) delete avar[k]
++}
++{ 
++	sub(/\.\.\./, "\\.\\.\\.")	# to avoid some side effects in regexp
++	sub(/^ +$/,"") 			# remove spaces in empty lines
++}
++/^[[:upper:][:space:]]+$/ {		# Section header
++	if ((in_bd + 0) == 1) {
++		in_bd = 0
++		print ".fam T\n.fi"
++	}
++	if (section == "SYNOPSIS") { 
++		print ".fam T\n.fi"
++		type["SYNOPSIS"] = ""
++	}
++	if ($0 ~/^[^[:space:]]/) print ".SH " $0
++	else print ".SS" $0
++	sub(/^ +/, "")
++	section = $0
++	if (section == "SYNOPSIS") print ".nf\n.fam C"
++	ls = 0		# line start index
++	pls = 0		# previous line start index
++	pnzls = 0	# previous non zero line start index
++	ni = 0		# indent level
++	ind[0] = 0	# indent offset table
++	prevblankline = 0
++	next
++}
++{	# compute line start index, handle start of example display block
++	pls = ls
++	if (ls != 0) pnzls = ls
++	match($0, /[^ ]/)
++	ls = RSTART
++	if (pls == 0 && pnzls > 0 && ls > pnzls && $1 !~ /^[0-9\-\*\o]\.*$/) {
++		# example display block
++		if (prevblankline == 1) { print ".PP"; prevblankline = 0 }
++		print ".nf\n.fam C"
++		in_bd = 1
++		eoff = ls
++	}
++	if (ls > 0 && ind[0] == 0) ind[0] = ls
++}
++(in_bd + 0) == 1 {				# In example display block
++	if (ls != 0 && ls < eoff) { 	# End of litteral display block
++		in_bd = 0
++		print ".fam T\n.fi"
++	} else { print; next }
++}
++section == "NAME" { $1 = "\\fB" $1; sub(/ \- /, " \\fP- ") }
++section == "SYNOPSIS" {			# Identify arguments of fcts and cmds
++	if (type["SYNOPSIS"] == "") {
++		if (index($0, "(") == 0 && index($0, ")") == 0 &&
++		    index($0, "#include") == 0)
++			type["SYNOPSIS"] = "cmd"
++		else
++			type["SYNOPSIS"] = "fct"
++	}
++	if (type["SYNOPSIS"] == "cmd") {	# Line is a command line
++		if ($1 !~ /^\[/) {
++			b = $1
++			sub(/^\*/, "", b)
++			subwords["\\<" b "\\>"] = "\\fB" b "\\fP"
++		}
++		for (i = 2; i <= NF; i++) {
++			a = $i
++			gsub(/[\[\]\|]/, "", a)
++			if (a ~ /^[^\-]/) subwords["\\<" a "\\>"] = "\\fI" a "\\fP"
++		}
++	} else {			# Line is a C function definition
++		if ($1 == "typedef") subwords["\\<" $2 "\\>"] = "\\fI" $2 "\\fP"
++		else if ($1 == "#define") subwords["\\<" $2 "\\>"] = "\\fI" $2 "\\fP"
++		for (i = 1; i <= NF; i++) 
++			if ($i ~ /[\,\)]/) {
++				a = $i
++				sub(/.*\(/, "", a)
++				gsub(/\W/, "", a)
++				if (a !~ /^void$/) subwords["\\<" a "\\>"] = "\\fI" a "\\fP"
++			} 
++	}
++}
++{
++	while ($0  ~ /\w\.\w/) sub(/\./, "_dOt_")	# protect dots inside words
++	for (i = 1; i <= NF; i++) {	# identify func calls and cross refs
++		b = $i
++		sub(/^\*/, "", b)
++		if ((a = index(b, ")(")) > 3) {
++			w = substr(b, 3, a - 3)
++			subwords["\\<" w "\\>"] = "\\fI" w "\\fP"
++		}
++		if ((a = index(b, "(")) > 1) {
++			w = substr(b, 1, a - 1)
++			subwords["\\<" w "\\("] = "\\fB" w "\\fP("
++		}
++	}
++	for (i in subwords) gsub(i, subwords[i])	# word attributes
++	gsub(/\B\-+\w+(\-\w+)*/, "\\fB&\\fP")		# shell options
++	gsub(/_dOt_/, ".") 				# unprotect dots inside words
++
++	if (match($0, /[^ ]  +/) > 0) {			# tag list item
++		adjust_indent()
++		tag = substr($0, 1, RSTART)
++		sub(/^ */, "", tag)
++		if (RSTART+RLENGTH < length()) $0 = substr($0, RSTART + RLENGTH)
++		else $0 = ""
++		print ".TP\n.B"
++		print tag
++		prevblankline = 0
++		if (NF == 0) next
++	} else if ($1 == "-"||$1 == "o"||$1 == "*") {	# bullet list item
++		adjust_indent()
++		print ".IP \\(bu 3"
++		prevblankline = 0
++		$1 = ""
++	} else if ($1 ~ /^[0-9]+[\).]$/) {		# enum list item
++		adjust_indent()
++		print ".IP " $1 " 4"
++		prevblankline = 0
++		$1 = ""
++	} else if (pls == 0) {				# new paragraph
++		adjust_indent()
++	} else if (NF == 0) { 				# blank line
++		prevblankline = 1; next 
++	} else prevblankline = 0			# other
++	if (prevblankline == 1) { 			# flush vertical space
++		print ".PP"; prevblankline = 0 
++	}
++	if (section != "SYNOPSIS" || $0 ~ /^ {1,4}/) sub(/ */,"")
++	print
++}
++function adjust_indent()
++{
++	if (ls > ind[ni]) { ind[++ni] = ls; print ".RS" }
++	else if (ls < ind[ni])
++		while (ls < ind[ni]) { ni--; print ".RE" }
++}
++' | eval $post
+diff --git b/include/.cvsignore a/include/.cvsignore
+new file mode 100644
+index 0000000..0781079
+--- /dev/null
++++ a/include/.cvsignore
+@@ -0,0 +1,10 @@
++Makefile
++Makefile.in
++tdsver.h
++config.h
++stamp-h.in
++config.h.in
++stamp-h
++stamp-h1
++tds_sysdep_public.h
++freetds_sysconfdir.h
+diff --git b/misc/freetds_autobuild a/misc/freetds_autobuild
+new file mode 100755
+index 0000000..a78d6f4
+--- /dev/null
++++ a/misc/freetds_autobuild
+@@ -0,0 +1,245 @@
++#!/bin/bash
++
++export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/lib/jre/bin:$HOME/bin:$HOME/install/bin"
++
++. $HOME/.bashrc
++
++# do not use ccache, not work well woth profile informations
++export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:$HOME/bin:$HOME/install/bin"
++
++GROUPDIR=/home/groups/f/fr/freetds/htdocs
++# directory to compile
++FTDSDIR=freetds82
++# output directory on server
++OUTDIR=out
++# additional flags for Autogen (current version)
++#FLAGS_ADD=--enable-developing
++FLAGS_ADD=
++# additional flags for Autogen (old version)
++FLAGS_ADD_OLD=
++WORKDIR=ftds_comp
++
++upload()
++{
++	mkdir -p "$HOME/cpp/freetds/html/$1"
++	rm -rf "$HOME/cpp/freetds/html/$1"
++	mkdir -p "$HOME/cpp/freetds/html/$1"
++	cp -r $2 "$HOME/cpp/freetds/html/$1"
++#	tar zcf - $2 | ssh -p 443 freddy77@shell-ssh.sourceforge.net "cd $GROUPDIR/$1 && rm -rf * && { tar zxf -; find . -type d -print0 | xargs -0 chmod 2775; find . -type f -print0 | xargs -0 chmod 0664; }"
++}
++
++upload_file()
++{
++	mkdir -p `dirname "$HOME/cpp/freetds/html/$1"`
++	cp $2 "$HOME/cpp/freetds/html/$1"
++#	ssh -p 443 freddy77@shell-ssh.sourceforge.net "cd $GROUPDIR && cat - > $1 && chmod 0664 $1" < $2
++}
++
++save_coverage()
++{
++	find include/ src/ -name \*.da -o -name \*.gc\* | tar zcf -  -T - > covsave.tgz
++}
++
++restore_coverage()
++{
++	find include/ src/ -name \*.da -o -name \*.gc\* -exec rm {} \;
++	tar zxf covsave.tgz
++	rm -f covsave.tgz
++}
++
++handle_exit()
++{
++	echo Exiting...
++	cd $HOME/cpp/freetds
++	rm -f freetds
++	ln -s "$FTDSDIR" freetds
++	rm -rf $WORKDIR
++}
++
++read_pwd_fields()
++{
++	tUID=`grep '^UID=' < PWD | sed 's,^....,,'`
++	tPWD=`grep '^PWD=' < PWD | sed 's,^....,,'`
++	tSRV=`grep '^SRV=' < PWD | sed 's,^....,,'`
++	tDB=`grep '^DB=' < PWD | sed 's,^...,,'`
++}
++
++rm ~/freetds.log /tmp/sql.log
++
++for param
++do
++	case $param in
++	--previous)
++		OUTDIR=out0
++		FTDSDIR=freetds64
++		FLAGS_ADD="$FLAGS_ADD_OLD"
++		WORKDIR=ftds_comp_old
++		;;
++	*)
++		echo 'Option not supported!' 1>&2
++		exit 1
++		;;
++	esac
++done
++
++set -e
++
++DOMAIN_UID=
++DOMAIN_PWD=
++MSSQL_PORT=
++MSSQL_INSTANCE=
++if test -r "$HOME/freetds_autobuild.sh"; then
++	. "$HOME/freetds_autobuild.sh"
++fi
++
++cd $HOME/cpp/freetds/$FTDSDIR
++# cvs up || { sleep 5; cvs up; } || { sleep 5; cvs up; }
++cd ..
++rm -rf $WORKDIR
++trap handle_exit EXIT
++cp -rp $FTDSDIR $WORKDIR
++rm -f freetds
++ln -s $WORKDIR freetds
++cd $WORKDIR
++find . \( -name \*.bb -o -name \*.bbg -o -name \*.da -o -name \*.gc\* \) -exec rm -f {} \;
++rm -rf autom4te.cache doc/doc covtmp coverage DBD-*
++cvsclean || true
++if test "$(uname -m)" = "x86_64"; then
++	cp ../DBD-ODBC-1.15_2.tar.gz .
++else
++	cp ../DBD-ODBC-1.13.tar.gz .
++fi
++cp ../php5.2-latest.tar.bz2 .
++
++LDFLAGS='-lgcov' CFLAGS='-O0 -pipe -g -fprofile-arcs -ftest-coverage' sh autogen.sh --enable-extra-checks --prefix=$HOME/install --with-odbc-nodm=/usr --with-gnutls $FLAGS_ADD
++
++# compile, test with mssql server
++cp -f ../PWD PWD
++read_pwd_fields
++make clean
++export LD_LIBRARY_PATH=$PWD/src/odbc/.libs/
++rm -rf logs
++mkdir logs
++./misc/test-auto.sh > logs/log.txt
++
++if test "$OUTDIR" = "out" -a -r doc/doxy.log; then
++	fixdoxyres < doc/doxy.log > doc/doxy.html
++	upload_file "doxy.html" "doc/doxy.html"
++	if test -d doc/doc/freetds-*/reference; then
++		(cd doc/doc/freetds-*/reference; upload doxy '*')
++	fi 
++fi
++
++# save logs for debug
++rm -f $HOME/log_tds.txt
++ln logs/log.txt $HOME/log_tds.txt
++
++# test Perl
++save_coverage
++RES=0
++# setting LANG avoid strange characters
++LANG=en_US ./misc/test-other.sh --perl-only --verbose >> logs/log.txt || RES=$?
++if test $RES != 0; then
++	echo "Perl test failed"
++	restore_coverage
++fi
++
++./misc/test-other.sh --php-only >> logs/log.txt || true
++
++# upload our test results
++cd logs
++perl -pe "\$_ = '' if \$_ =~ /^2:bcp.c: In function 'bcp_colfmt'|^2:bcp.c:\\d+: warning: suggest parentheses around && within \\|\\|/" < log.txt | ../misc/online.pl
++upload "$OUTDIR/test" '*.html'
++cd ..
++
++# test domain password and TDSPORT with service name
++if test "$DOMAIN_UID" != ""; then
++	save_coverage
++	# using tsql directly with grep do not update coverage informations
++	echo -e 'select @@version\ngo\nbye' | TDSPORT=ms-sql-s TDSDUMP=stdout ./src/apps/tsql -S $tSRV -U "$DOMAIN_UID" -P "$DOMAIN_PWD" > out.txt || true
++	if grep -q 'Microsoft Corporation' out.txt; then
++		echo "domain password ok"
++	else
++		echo "domain password failed!"
++		restore_coverage
++	fi
++	rm -f out.txt
++fi
++
++if test "$MSSQL_PORT" != ""; then
++	save_coverage
++	# using tsql directly with grep do not update coverage informations
++	echo -e 'select @@version\ngo\nbye' | ./src/apps/tsql -S "$tSRV:$MSSQL_PORT" -U "$tUID" -P "$tPWD" > out.txt || true
++	if grep -q 'Microsoft Corporation' out.txt; then
++		echo "override port ok"
++	else
++		echo "override port failed!"
++		restore_coverage
++	fi
++	rm -f out.txt
++fi
++
++if test "$MSSQL_INSTANCE" != ""; then
++	save_coverage
++	# using tsql directly with grep do not update coverage informations
++	echo -e 'select @@version\ngo\nbye' | ./src/apps/tsql -S "$tSRV\\$MSSQL_INSTANCE" -U "$tUID" -P "$tPWD" > out.txt || true
++	if grep -q 'Microsoft Corporation' out.txt; then
++		echo "override instance ok"
++	else
++		echo "override instance failed!"
++		restore_coverage
++	fi
++	rm -f out.txt
++fi
++
++# do tests with sybase server
++cp -f ../PWD.sybase PWD
++read_pwd_fields
++rm -rf logs
++mkdir logs
++./misc/test-auto.sh --no-build > logs/log.txt
++cd logs
++../misc/online.pl < log.txt
++upload "$OUTDIR/test2" '*.html'
++cd ..
++
++# do tests with sybase 15 server
++if test "$OUTDIR" = "out"; then
++	cp -f ../PWD.sybase15 PWD
++	read_pwd_fields
++	rm -rf logs
++	mkdir logs
++	./misc/test-auto.sh --no-build > logs/log.txt
++	cd logs
++	../misc/online.pl < log.txt
++	upload "$OUTDIR/test3" '*.html'
++	cd ..
++fi
++
++# test autodiscovery
++if test "$OUTDIR" = "out"; then
++	save_coverage
++	# using tsql directly with grep do not update coverage informations
++	echo -e 'select @@version\ngo\nbye' | TDSVER=0.0 ./src/apps/tsql -S "$tSRV" -U "$tUID" -P "$tPWD" > out.txt || true
++	if grep -q 'Adaptive Server Enterprise' out.txt; then
++		echo "autodiscovery ok"
++	else
++		echo "autodiscovery failed!"
++		restore_coverage
++	fi
++	rm -f out.txt
++fi
++
++# restore PWD file
++cp -f ../PWD PWD
++
++# build coverage and upload it
++rm -rf coverage
++./misc/coverage.sh
++cd coverage
++upload "$OUTDIR/coverage" '*'
++cd ..
++
++# cleanup
++rm -f ~/freetds.log /tmp/sql.log covsave.tgz
++rm -rf logs
+diff --git b/misc/test-auto.sh a/misc/test-auto.sh
+new file mode 100755
+index 0000000..14d54e6
+--- /dev/null
++++ a/misc/test-auto.sh
+@@ -0,0 +1,103 @@
++#!/bin/sh
++
++# automatic test and report
++
++# set -e
++
++BUILD=1
++CONFIGURE=0
++for param
++do
++	case $param in
++	--help)
++		echo $0 [--help] [--no-build] [--configure]
++		exit 0
++		;;
++	--no-build)
++		BUILD=0
++		;;
++	--configure)
++		CONFIGURE=1
++		;;
++	esac
++done
++
++# go to main distro dir
++DIR=`dirname $0`
++cd "$DIR/.."
++
++DIR="$PWD/misc"
++LANG=C
++export LANG
++
++log () {
++	echo "@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@- $1 -@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@"
++}
++
++# function to save output
++output_save () {
++	COMMENT=$1
++	shift
++	OUT=$1
++	shift
++	log "START $OUT"
++	classifier "$@"
++	RES=$?
++	log "RESULT $RES"
++	log "END $OUT"
++}
++
++# output informations
++XXX=`hostname`
++log "INFO HOSTNAME `echo $XXX`"
++VER=`gcc --version 2> /dev/null | grep 'GCC'`
++log "INFO GCC $VER"
++XXX=`uname -a`
++log "INFO UNAME `echo $XXX`"
++log "INFO DATE `date '+%Y-%m-%d'`"
++
++MAKE=make
++if gmake --help 2> /dev/null > /dev/null; then
++	MAKE=gmake
++fi
++
++# execute configure
++if test $CONFIGURE = 1; then
++	BUILD=1
++	output_save "configuration" conf ./configure --enable-extra-checks $TDS_AUTO_CONFIG
++	if test $RES != 0; then
++		echo "error during configure"
++		exit 1
++	fi
++fi
++
++if test $BUILD = 1; then
++
++	echo Making ...
++	$MAKE clean > /dev/null 2> /dev/null
++	output_save "make" make $MAKE
++	if test $RES != 0; then
++		echo "error during make"
++		exit 1
++	fi
++
++	echo Making tests ...
++	TESTS_ENVIRONMENT=true
++	export TESTS_ENVIRONMENT
++	output_save "make tests" maketest $MAKE check 
++	if  test $RES != 0; then
++		echo "error during make test"
++		exit 1;
++	fi
++fi
++
++echo Testing ...
++TESTS_ENVIRONMENT="$DIR/full-test.sh"
++export TESTS_ENVIRONMENT
++$MAKE check 2> /dev/null
++if  test $? != 0; then
++	echo "error during make check"
++	exit 1;
++fi
++
++exit 0
+diff --git b/misc/test-dist.sh a/misc/test-dist.sh
+new file mode 100755
+index 0000000..73cbf7f
+--- /dev/null
++++ a/misc/test-dist.sh
+@@ -0,0 +1,150 @@
++#!/bin/sh
++
++# This script test that Makefiles are able to produre a good 
++# distribution
++#
++# It create a test-dist.log file in the mail directory, you
++# can tail this file to see the progress
++
++# stop on errors
++set -e
++
++for param
++do
++	case $param in
++	--no-unittests)
++		TESTS_ENVIRONMENT=true
++		export TESTS_ENVIRONMENT
++		;;
++	--help)
++		echo "Usage: $0 [OPTION]..."
++		echo '  --help          this help'
++		echo '  --no-unittests  do not execute unittests'
++		exit 0
++		;;
++	*)
++		echo 'Option not supported!' 1>&2
++		exit 1
++		;;
++	esac
++done
++
++# do not create logs so diskcheck test do not fails
++unset TDSDUMP || true
++
++# set correct directory
++DIR=`dirname $0`
++cd "$DIR/.."
++
++# remove old distributions
++touch freetds-dummy
++find freetds-* -type d ! -perm -200 -exec chmod u+w {} ';'
++rm -rf freetds-*
++
++# save directory
++ORIGDIR="$PWD"
++
++# init log
++LOG="$PWD/test-dist.log"
++rm -f "$LOG"
++echo "log started" >> "$LOG"
++
++# make distribution
++test -f Makefile || sh autogen.sh
++make dist
++echo "make distribution ok" >> "$LOG"
++
++# untar to test it, should already contains documentation
++DIR=`echo freetds-* | sed s,.tar.gz$,,g`
++gunzip -dc freetds-*.tar.gz | tar xf -
++test -d "$DIR"
++cd "$DIR"
++echo "untar ok" >> "$LOG"
++
++# assure you do not compile documentation again
++mkdir fakebin
++PATH="$PWD/fakebin:$PATH"
++export PATH
++cd fakebin
++echo "#!/bin/sh
++exit 1" > openjade
++cp openjade doxygen
++# gawk it's used by txt2man
++cp openjade gawk
++cp openjade autoheader
++# perl is used by some perl rules
++cp openjade perl
++chmod +x openjade doxygen gawk autoheader perl
++cd ..
++if ! openjade --help; then true; else echo 'succedeed ?'; false; fi
++if ! doxygen --help; then true; else echo 'succeeded ?'; false; fi
++if ! gawk --help; then true; else echo 'succeeded ?'; false; fi
++if ! autoheader --help; then true; else echo 'succeeded ?'; false; fi
++if ! perl --help; then true; else echo 'succeeded ?'; false; fi
++echo "fakebin ok" >> "$LOG"
++
++# direct make install (without make all)
++mkdir install
++INSTALLDIR="$PWD/install"
++mkdir build
++cd build
++# --enable-msdblib --enable-sybase-compat can cause also problems, try to compile with both
++../configure --prefix="$INSTALLDIR" --enable-msdblib --enable-sybase-compat --disable-libiconv
++# make clean should not cause problems here
++make clean
++make install
++cd ..
++echo "direct make install ok" >> "$LOG"
++
++# cleanup
++rm -rf install build
++
++# again with dist and autogen
++mkdir build
++cd build
++../autogen.sh
++make dist
++cd ..
++rm -rf build
++echo "make dist ok" >> "$LOG"
++
++# test if make clean clean too much
++mkdir install
++./configure --prefix="$PWD/install"
++make clean
++make dist
++
++# finally big test. I hope you have a fast machine :)
++cd ..
++rm -rf "$DIR"
++gunzip -dc freetds-*.tar.gz | tar xf -
++cd "$DIR"
++./configure
++if test ! -e PWD -a -e "$ORIGDIR/../PWD"; then
++	cp "$ORIGDIR/../PWD" .
++fi
++if test ! -e PWD -a -e "$ORIGDIR/PWD"; then
++	cp "$ORIGDIR/PWD" .
++fi
++make distcheck
++echo "make distcheck ok" >> "$LOG"
++
++# cleanup
++cd "$ORIGDIR"
++chmod -R 777 "$DIR"
++rm -rf "$DIR"
++
++# check rpm
++RPMCMD=rpm
++if rpmbuild --help > /dev/null 2>&1; then
++	RPMCMD=rpmbuild
++fi
++if $RPMCMD --help > /dev/null 2>&1; then
++	$RPMCMD -ta freetds-*.tar.gz || exit 1
++	echo "rpm test ok" >> "$LOG"
++else
++	echo "rpm test skipped, no rpm detected" >> "$LOG"
++fi
++
++echo "all tests ok!!!" >> "$LOG"
++
+diff --git b/misc/test-other.sh a/misc/test-other.sh
+new file mode 100755
+index 0000000..d20591a
+--- /dev/null
++++ a/misc/test-other.sh
+@@ -0,0 +1,223 @@
++#!/bin/sh
++
++# Additional make check test
++# check other tools (like Perl and PHP)
++# odbc MUST be configured to point to source driver
++
++# stop on errors
++set -e
++
++verbose=no
++do_perl=no
++do_php=yes
++
++# check for perl existence
++if perl -e 'exit 0' > /dev/null 2>&1; then
++	do_perl=yes
++fi
++
++for param
++do
++	case $param in
++	--verbose)
++		verbose=yes ;;
++	--no-perl)
++		do_perl=no ;;
++	--no-php)
++		do_php=no ;;
++	--perl-only)
++		do_perl=yes
++		do_php=no
++		;;
++	--php-only)
++		do_perl=no
++		do_php=yes
++		;;
++	*)
++		echo 'Option not supported!' 1>&2
++		exit 1
++		;;
++	esac
++done
++
++log () {
++        echo "@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@- $1 -@!@!@!@!@!@!@!@!@!@!@!@!@!@!@!@"
++}
++
++# set correct directory
++DIR=`dirname $0`
++cd "$DIR/.."
++
++# save directory
++ORIGDIR="$PWD"
++
++# init log
++LOG="$PWD/test-other.log"
++rm -f "$LOG"
++echo "log started" >> "$LOG"
++
++## assure make
++#make all
++#echo "make all ok" >> "$LOG"
++
++tUID=`cat PWD | grep '^UID=' | sed 's,^....,,g'`
++tPWD=`cat PWD | grep '^PWD=' | sed 's,^....,,g'`
++tSRV=`cat PWD | grep '^SRV=' | sed 's,^....,,g'`
++tDB=`cat PWD | grep '^DB=' | sed 's,^...,,g'`
++
++# prepare odbc.ini redirection
++rm -f odbc.ini
++for f in .libs/libtdsodbc.so .libs/libtdsodbc.sl .libs/libtdsodbc.dll .libs/libtdsodbc.dylib; do
++	if test -r "$PWD/src/odbc/$f"; then
++		echo "[$tSRV]
++Driver = $PWD/src/odbc/$f
++Database = $tDB
++Servername = $tSRV
++
++[xx_$tSRV]
++Driver = $PWD/src/odbc/$f
++Database = $tDB
++Servername = $tSRV" > odbc.ini
++		ODBCINI="$PWD/odbc.ini"
++		SYSODBCINI="$PWD/odbc.ini"
++		export ODBCINI SYSODBCINI
++		break;
++	fi
++done
++
++# Perl
++if test $do_perl = yes; then
++	DBI_DSN="dbi:ODBC:$tSRV"
++	DBI_USER="$tUID"
++	DBI_PASS="$tPWD"
++	export DBI_DSN DBI_USER DBI_PASS
++	# TODO better way
++	ODBCHOME=/usr
++	export ODBCHOME
++	for f in DBD-ODBC-*.tar.gz; do
++		DIR=`echo "$f" | sed s,.tar.gz$,,g`
++		echo Testing $DIR
++		if ! test -d "$DIR"; then
++			tar zxvf "$DIR.tar.gz"
++			# try to apply patch for Sybase
++			cd "$DIR"
++			{ patch -p1 || true ; } <<EOF
++diff -ru DBD-ODBC-1.13/t/07bind.t DBD-ODBC-1.13my/t/07bind.t
++--- DBD-ODBC-1.13/t/07bind.t	2005-02-20 10:09:17.039561424 +0100
+++++ DBD-ODBC-1.13my/t/07bind.t	2004-12-18 15:19:11.000000000 +0100
++@@ -133,7 +133,7 @@
++ 		  # expect!
++ 		  \$row[2] = "";
++ 	       }
++-	       if (\$row[2] ne \$_->[2]) {
+++	       if (\$row[2] ne \$_->[2] && (\$dbname ne "sql server" || \$row[2] ne " ") ) {
++ 		  print "Column C value failed! bind value = \$bind_val, returned values = \$row[0]|\$row[1]|\$row[2]|\$row[3]\\n";
++ 		  return undef;
++ 	       }
++EOF
++			# fix for DBD::ODBC and Perl 5.8.8
++			echo "--- DBD-ODBC-1.13.orig/dbdimp.c	2004-11-05 04:19:36.000000000 +0100
+++++ DBD-ODBC-1.13/dbdimp.c	2007-01-16 09:38:20.477774620 +0100
++@@ -2921,11 +2921,11 @@
++     * */
++    else if (is_inout != phs->is_inout) {
++       croak(\"Can't rebind or change param %s in/out mode after first bind (%d => %d)\",
++ 	    phs->name, phs->is_inout, is_inout);
++    }
++-   else if (maxlen && maxlen != phs->maxlen) {
+++   else if (maxlen && maxlen > phs->maxlen) {
++       croak(\"Can't change param %s maxlen (%ld->%ld) after first bind\",
++ 	    phs->name, phs->maxlen, maxlen);
++    }
++ 
++    if (!is_inout) {    /* normal bind to take a (new) copy of current value    */
++" | patch -p1 || true
++			cd t
++			{ patch -p0 || true ; }  <<EOF
++--- 20SqlServer.t.orig  2005-08-09 13:33:30.000000000 +0200
+++++ 20SqlServer.t       2005-08-09 13:37:36.000000000 +0200
++@@ -419,7 +419,7 @@
++
++    \$dbh->{odbc_async_exec} = 1;
++    # print "odbc_async_exec is: \$dbh->{odbc_async_exec}\\n";
++-   is(\$dbh->{odbc_async_exec}, 1, "test odbc_async_exec attribute set");
+++   is(\$dbh->{odbc_async_exec}, 0, "test odbc_async_exec attribute NOT set");
++
++    # not sure if this should be a test.  May have permissions problems, but it's the only sample
++    # of the error handler stuff I have.
++EOF
++			cd ../..
++		fi
++		test -d "$DIR"
++		cd "$DIR"
++		grep -v 'prompt(' Makefile.PL > Makefile.PL.tmp
++		cat Makefile.PL.tmp > Makefile.PL
++		test -r Makefile || LANG=C perl Makefile.PL
++		LANG=C make clean
++		RES=0
++		log "START DBD::ODBC make"
++		test -r Makefile || LANG=C classifier perl Makefile.PL || RES=$?
++		if test $RES = 0; then
++			LANG=C classifier make || RES=$?
++		fi
++		log "RESULT $RES"
++		log "END DBD::ODBC make"
++		if test $RES = 0; then
++			log "START DBD::ODBC test"
++			if test $verbose = yes; then
++				LANG=C classifier make test TEST_VERBOSE=1 || RES=$?
++			else
++				LANG=C classifier make test || RES=$?
++			fi
++			log "RESULT $RES"
++			log "END DBD::ODBC test"
++		fi
++		if test $RES != 0; then
++			exit $RES
++		fi
++	done
++fi
++
++# PHP
++cd "$ORIGDIR"
++FILE='php5.2-latest.tar.bz2'
++if test $do_php = yes -a -f "$FILE"; then
++	# need to recompile ??
++	if test ! -x phpinst/bin/php -o "$FILE" -nt phpinst/bin/php; then
++		rm -rf php5.2-200* phpinst lib
++		bunzip2 -c "$FILE" | tar xvf -
++		DIR=`echo php5.2-200*`
++		MAINDIR=$PWD
++		mkdir lib
++		cp src/dblib/.libs/lib*.s[ol]* lib
++		cp src/tds/.libs/libtds.a lib
++#		cp src/tds/.libs/lib*.s[ol]* lib
++		cd $DIR
++		CFLAGS='-O0 -pipe' ./configure --prefix=$MAINDIR/phpinst --disable-all --with-mssql=$MAINDIR  --with-unixODBC=/usr
++		make -j4
++		make install
++		cd ..
++	fi
++
++	cd phptests
++	echo "<?php \$server = \"$tSRV\"; \$user = \"$tUID\"; \$pass = \"$tPWD\"; ?>" > pwd.inc
++
++	ERR=""
++	for f in *.php; do
++		echo Testing PHP script $f
++		log "START PHP test $f"
++		RES=0
++		../phpinst/bin/php -q $f 2>&1 || { RES=$?; ERR="$ERR $f"; }
++		log "RESULT $RES"
++		log "FILE $PWD/$f"
++		log "END PHP test $f"
++	done
++	if test "$ERR" != ""; then
++		echo "Some script failed:$ERR"
++		exit 1
++	fi
++fi
++
++echo "all tests ok!!!" >> "$LOG"
++exit 0
++
+diff --git b/mkinstalldirs a/mkinstalldirs
+index ce6c2d3..4d8662b 100755
+--- b/mkinstalldirs
++++ a/mkinstalldirs
+@@ -4,7 +4,7 @@
+ # Created: 1993-05-16
+ # Public domain
+ 
+-# $Id: mkinstalldirs,v 1.1.1.1 2001/10/12 23:28:53 brianb Exp $
++# $Id: mkinstalldirs,v 1.1 2001/10/12 23:28:53 brianb Exp $
+ 
+ errstatus=0
+ 
+diff --git b/phptests/.cvsignore a/phptests/.cvsignore
+new file mode 100644
+index 0000000..03a7a33
+--- /dev/null
++++ a/phptests/.cvsignore
+@@ -0,0 +1 @@
++pwd.inc
+diff --git b/samples/.cvsignore a/samples/.cvsignore
+new file mode 100644
+index 0000000..f24dd77
+--- /dev/null
++++ a/samples/.cvsignore
+@@ -0,0 +1,3 @@
++Makefile
++Makefile.in
++unixodbc.freetds.driver.template
+diff --git b/samples/odbc_rpc.pl a/samples/odbc_rpc.pl
+new file mode 100755
+index 0000000..cc93942
+--- /dev/null
++++ a/samples/odbc_rpc.pl
+@@ -0,0 +1,123 @@
++#!/usr/local/bin/perl
++# $Id: odbc_rpc.pl,v 1.7 2006/07/27 19:24:42 jklowden Exp $
++#
++# Contributed by James K. Lowden and is hereby placed in 
++# the public domain.  No rights reserved.  
++#
++# This program demonstrates calling the ODBC "dynamic" functions, using
++# placeholders and prepared statements.  
++#
++# By default, arguments are bound to type SQL_VARCHAR.  If the stored procedure 
++# uses other types, they may be specified in the form :TYPE:data, where TYPE is one
++# of the DBI symbolic constants.  If your data happen to begin with a colon, 
++# prefix the string with ':SQL_VARCHAR:'.  
++#
++# Example: a datetime parameter:  ':SQL_DATETIME:2005-04-01 16:46:00' 
++# (Unfortunately, it appears DBD::ODBC has difficulty with SQL_DATETIME:
++# http://www.opensubscriber.com/message/perl-win32-users@listserv.ActiveState.com/108164.html
++#	
++#
++# To find the symbolic constants for DBI, perldoc DBI recommends:
++#  	use DBI;         
++#  	foreach (@{ $DBI::EXPORT_TAGS{sql_types} }) {
++#             printf "%s=%d\n", $_, &{"DBI::$_"};
++#  	}
++# 
++
++use DBI qw(:sql_types);
++use Getopt::Std;
++use File::Basename;
++
++# Stolen shamelessly from DBI: testerrhandler.pl
++
++sub err_handler {
++   my ($state, $msg) = @_;
++   # Strip out all of the driver ID stuff
++   $msg =~ s/^(\[[\w\s]*\])+//;
++   print "===> state: $state msg: $msg\n";
++   return 0;
++}
++
++sub setup_error_handler($)
++{ my ($dbh) = @_;
++
++	$dbh->{odbc_err_handler} = \&err_handler;
++	$dbh->{odbc_async_exec} = 1;
++	print "odbc_async_exec is: $dbh->{odbc_async_exec}\n";
++}
++
++$program = basename($0);
++
++Getopt::Std::getopts('U:P:D:d:h', \%opts);
++
++my ($dsn, $user, $pass, $database);
++$dsn  = $opts{D}? $opts{D} : "dbi:ODBC:JDBC";
++$user = $opts{U}? $opts{U} : 'guest';
++$pass = $opts{P}? $opts{P} : 'sybase';
++
++die qq(Syntax: \t$program [-D dsn] [-U username] [-P password] procedure [arg1[, argn]]\n) 
++	if( $opts{h} || 0 == @ARGV );
++
++# Connect
++my $dbh = DBI->connect($dsn, $user, $pass, {RaiseError => 0, PrintError => 1, AutoCommit => 1})
++	or die "Unable for connect to $dsn $DBI::errstr";
++
++setup_error_handler($dbh);
++
++# Construct an odbc placeholder list like (?, ?, ?)
++# for any arguments after $ARGV[0]. 
++my $placeholders = '';
++if( @ARGV > 1 ) {
++	my @placeholders = ('?') x (@ARGV - 1); 
++	$placeholders = '(' . join( q(, ),  @placeholders ) . ')';
++	printf STDERR qq(%d arguments found for procedure "$ARGV[0]"\n), scalar(@placeholders);
++}
++
++# Ready the odbc call
++my $sql = "{? = call $ARGV[0] $placeholders}";
++my $sth = $dbh->prepare( $sql );
++
++# Bind the return code as "inout".
++my $rc;
++print STDERR qq(Binding parameter #1, the return code\n);
++$sth->bind_param_inout(1, \$rc, SQL_INTEGER);
++
++# Bind the input parameters (we don't do outputs in this example).
++# Placeholder numbers are 1-based; the first "parameter" 
++# is the return code, $rc, above.
++for( my $i=1; $i < @ARGV; $i++ ) {
++    my $type = SQL_VARCHAR;
++    my $typename = 'SQL_VARCHAR';
++    my $data = $ARGV[$i];
++    if( $data =~ /^:([[:upper:]_]+):(.+)/ ) { # parse out the datatype, if any
++	$typename = $1;
++	$data = $2;
++        $type = eval($typename);
++	warn qq("$typename" will probably cause a "can't rebind parameter" message\n) 
++		if $type == SQL_DATETIME;
++    }
++    printf STDERR qq(Binding parameter #%d (%s): "$data"\n), ($i+1), $typename;
++    $sth->bind_param( 1 + $i, $data, $type );
++}
++
++print STDERR qq(\nExecuting: "$sth->{Statement}" with parameters '), 
++	     join(q(', '), @ARGV[1..$#ARGV]), qq('\n);
++
++# Execute the SQL and print the (possibly several) results
++$rc = $sth->execute;
++print STDERR qq(execute returned: '$rc'\n) if $rc;
++
++$i = 1;
++while ( $sth->{Active} ) { 
++	printf "Result #%d:\n", $i++;
++        my @names = @{$sth->{NAME}};	# print column names for each result set
++	print '[', join("], [", @{$sth->{NAME}}), "]\n" if @names;
++	while(@dat = $sth->fetchrow_array) {
++		print q('), join(q(', '), @dat), qq('\n);
++	}
++}
++
++$dbh->disconnect();
++
++exit 0;
++
+diff --git b/src/.cvsignore a/src/.cvsignore
+new file mode 100644
+index 0000000..282522d
+--- /dev/null
++++ a/src/.cvsignore
+@@ -0,0 +1,2 @@
++Makefile
++Makefile.in
+diff --git b/src/apps/.cvsignore a/src/apps/.cvsignore
+new file mode 100644
+index 0000000..36f7973
+--- /dev/null
++++ a/src/apps/.cvsignore
+@@ -0,0 +1,11 @@
++Makefile
++Makefile.in
++tsql
++freebcp
++bsqldb
++defncopy
++.libs
++.deps
++datacopy
++bsqlodbc
++
+diff --git b/src/apps/fisql/.cvsignore a/src/apps/fisql/.cvsignore
+new file mode 100644
+index 0000000..ecef2f6
+--- /dev/null
++++ a/src/apps/fisql/.cvsignore
+@@ -0,0 +1,5 @@
++Makefile
++Makefile.in
++.libs
++.deps
++fisql
+diff --git b/src/ctlib/.cvsignore a/src/ctlib/.cvsignore
+new file mode 100644
+index 0000000..aee705c
+--- /dev/null
++++ a/src/ctlib/.cvsignore
+@@ -0,0 +1,6 @@
++Makefile
++Makefile.in
++.libs
++*.lo
++*.la
++.deps
+diff --git b/src/ctlib/unittests/.cvsignore a/src/ctlib/unittests/.cvsignore
+new file mode 100644
+index 0000000..4682152
+--- /dev/null
++++ a/src/ctlib/unittests/.cvsignore
+@@ -0,0 +1,34 @@
++Makefile
++Makefile.in
++.deps
++.libs
++t0001
++t0002
++t0003
++t0004
++t0005
++t0006
++t0007
++t0008
++t0009
++connect_fail
++tdsdump.out
++ct_options
++rpc_ct_setparam
++rpc_ct_param
++lang_ct_param
++get_send_data
++cs_diag
++array_bind
++ct_diagall
++ct_diagclient
++ct_diagserver
++cs_config
++cancel
++blk_in
++blk_out
++ct_cursor
++ct_cursors
++ct_dynamic
++blk_in2
++
+diff --git b/src/dblib/.cvsignore a/src/dblib/.cvsignore
+new file mode 100644
+index 0000000..aee705c
+--- /dev/null
++++ a/src/dblib/.cvsignore
+@@ -0,0 +1,6 @@
++Makefile
++Makefile.in
++.libs
++*.lo
++*.la
++.deps
+diff --git b/src/dblib/unittests/.cvsignore a/src/dblib/unittests/.cvsignore
+new file mode 100644
+index 0000000..691f42b
+--- /dev/null
++++ a/src/dblib/unittests/.cvsignore
+@@ -0,0 +1,48 @@
++Makefile
++Makefile.in
++.deps
++.libs
++t0001
++t0002
++t0003
++t0004
++t0005
++t0006
++t0007
++t0008
++t0009
++t0011
++t0012
++t0013
++t0013.out
++t0014
++t0014.out
++t0015
++t0016
++t0016.out
++t0017
++t0018
++t0019
++t0020
++t0021
++t0022
++tdsdump.out
++t0023
++t0016.err
++t0017.err
++t0017.out
++rpc
++dbmorecmds
++bcp
++thread
++text_buffer
++done_handling
++timeout
++dblib.dsw
++dblib.mak
++vc6
++hang
++null
++null2
++setnull
++
+diff --git b/src/odbc/.cvsignore a/src/odbc/.cvsignore
+new file mode 100644
+index 0000000..c9a04fd
+--- /dev/null
++++ a/src/odbc/.cvsignore
+@@ -0,0 +1,7 @@
++Makefile
++Makefile.in
++.libs
++.deps
++*.lo
++*.la
++
+diff --git b/src/odbc/checkexport.sh a/src/odbc/checkexport.sh
+new file mode 100755
+index 0000000..142cd4e
+--- /dev/null
++++ a/src/odbc/checkexport.sh
+@@ -0,0 +1,10 @@
++#!/bin/sh
++echo Function not exported by VMS driver
++(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^\(SQL\|ODBC\)'; cat ../../vms/odbc_driver_axp.opt | grep -v '^!' | grep 'SQL' | sed 's,.*SQL\(.*\)=PROCEDURE.*,SQL\1,g') | sort | uniq -u | grep -v ODBCINSTGetProperties
++
++echo Function not exported by windows driver
++(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^\(SQL\|ODBC\)'; cat ../../win32/FreeTDS.def | grep -v '^;' | grep 'SQL' | sed 's,.*SQL,SQL,g' | perl -pe 's,\r,,g') | sort | uniq -u | grep -v ODBCINSTGetProperties
++
++echo Function not declared as implemented
++(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^SQL' | perl -pe 'tr/a-z/A-Z/'; cat odbc.c | grep 'X(SQL_API_' | sed 's,.*SQL_API_SQL,SQL,g; s,).*,,g' | sort | uniq) | sort | uniq -u
++(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^SQL' | perl -pe 'tr/a-z/A-Z/'; cat odbc.c | grep '_(SQL_API_' | sed 's,.*SQL_API_SQL,SQL,g; s,).*,,g' | sort | uniq) | sort | uniq -d
+diff --git b/src/odbc/unittests/.cvsignore a/src/odbc/unittests/.cvsignore
+new file mode 100644
+index 0000000..2da9b2c
+--- /dev/null
++++ a/src/odbc/unittests/.cvsignore
+@@ -0,0 +1,67 @@
++.libs
++Makefile
++Makefile.in
++t0001
++t0002
++t0003
++t0004
++tdsdump.out
++.deps
++connect
++print
++date
++norowset
++funccall
++lang_error
++tables
++binary_test
++moreandcount
++earlybind
++putdata
++params
++raiserror
++getdata
++type
++genparams
++transaction
++preperror
++odbc.ini
++odbcinst.ini
++prepare_results
++data
++testodbc
++error
++rebindpar
++convert_error
++typeinfo
++const_params
++compute
++insert_speed
++timeout
++array
++array_out
++cursor1
++cursor2
++scroll
++describecol
++copydesc
++msvc.mak
++prepclose
++warning
++paramcore
++rpc
++timeout2
++timeout3
++odbc.dsw
++odbc.mak
++vc6
++connect2
++timeout4
++freeclose
++cursor3
++cursor4
++cursor5
++attributes
++hidden
++blob1
++rowset
+diff --git b/src/odbc/unittests/rownumber.c a/src/odbc/unittests/rownumber.c
+new file mode 100644
+index 0000000..d2c213f
+--- /dev/null
++++ a/src/odbc/unittests/rownumber.c
+@@ -0,0 +1,110 @@
++#include "common.h"
++
++/* Test for SQL_ATTR_ROW_NUMBER */
++
++/*
++ * This works under MS ODBC however I don't know if it's correct... 
++ * TODO make it work and add to Makefile.am
++ */
++
++static char software_version[] = "$Id: rownumber.c,v 1.2 2005/01/14 15:03:12 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static void
++CheckRowNum(int n, int line)
++{
++	SQLRETURN res;
++	SQLUINTEGER value;
++
++	res = SQLGetStmtAttr(Statement, SQL_ATTR_ROW_NUMBER, &value, sizeof(value), NULL);
++	if (res != SQL_SUCCESS) {
++		if (res == SQL_ERROR && n < 0)
++			return;
++		ODBC_REPORT_ERROR("SQLGetStmtAttr failed");
++	}
++	if (value != n) {
++		fprintf(stderr, "Expected %d rows returned %d line %d\n", n, (int) value, line);
++		exit(1);
++	}
++}
++
++#undef CHECK_ROWS
++#define CHECK_ROWS(n) CheckRowNum(n,__LINE__)
++
++static void
++NextResults(SQLRETURN expected)
++{
++	if (SQLMoreResults(Statement) != expected) {
++		if (expected == SQL_SUCCESS)
++			fprintf(stderr, "Expected another recordset\n");
++		else
++			fprintf(stderr, "Not expected another recordset\n");
++		exit(1);
++	}
++}
++
++static void
++Fetch(SQLRETURN expected)
++{
++	if (SQLFetch(Statement) != expected) {
++		if (expected == SQL_SUCCESS)
++			fprintf(stderr, "Expected another record\n");
++		else
++			fprintf(stderr, "Not expected another record\n");
++		exit(1);
++	}
++}
++
++static void
++DoTest()
++{
++	int n = 0;
++	static const char query[] = "SELECT * FROM #tmp1 ORDER BY i SELECT * FROM #tmp1 WHERE i < 3 ORDER BY i";
++
++	/* execute a batch command and check row number */
++	if (SQLExecDirect(Statement, (SQLCHAR *) query, SQL_NTS) != SQL_SUCCESS)
++		ODBC_REPORT_ERROR("Unable to execute direct statement");
++	CHECK_ROWS(-1);
++	printf("Result %d\n", ++n);
++	Fetch(SQL_SUCCESS);
++	CHECK_ROWS(0);
++	Fetch(SQL_SUCCESS);
++	CHECK_ROWS(0);
++	Fetch(SQL_SUCCESS);
++	CHECK_ROWS(0);
++	Fetch(SQL_NO_DATA);
++	CHECK_ROWS(-1);
++	NextResults(SQL_SUCCESS);
++	CHECK_ROWS(-1);
++
++	printf("Result %d\n", ++n);
++	Fetch(SQL_SUCCESS);
++	CHECK_ROWS(0);
++	Fetch(SQL_SUCCESS);
++	CHECK_ROWS(0);
++	Fetch(SQL_NO_DATA);
++	CHECK_ROWS(-1);
++	NextResults(SQL_NO_DATA);
++	CHECK_ROWS(-1);
++}
++
++int
++main(int argc, char *argv[])
++{
++	use_odbc_version3 = 1;
++
++	Connect();
++
++	Command(Statement, "create table #tmp1 (i int)");
++	Command(Statement, "create table #tmp2 (i int)");
++	Command(Statement, "insert into #tmp1 values(1)");
++	Command(Statement, "insert into #tmp1 values(2)");
++	Command(Statement, "insert into #tmp1 values(5)");
++
++	DoTest();
++
++	Disconnect();
++
++	printf("Done.\n");
++	return 0;
++}
+diff --git b/src/pool/.cvsignore a/src/pool/.cvsignore
+new file mode 100644
+index 0000000..7cdd226
+--- /dev/null
++++ a/src/pool/.cvsignore
+@@ -0,0 +1,5 @@
++Makefile
++Makefile.in
++.deps
++.libs
++tdspool
+diff --git b/src/pool/stream.c a/src/pool/stream.c
+new file mode 100644
+index 0000000..8823cd9
+--- /dev/null
++++ a/src/pool/stream.c
+@@ -0,0 +1,455 @@
++/* TDSPool - Connection pooling for TDS based databases
++ * Copyright (C) 2001, 2002, 2003, 2004, 2005  Brian Bruns
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
++ * GNU General Public License for more details.
++ *
++ * You should have received a copy of the GNU General Public License
++ * along with this program; if not, write to the Free Software
++ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
++ *
++ */
++
++/*
++ * Name: stream.c
++ * Description: Controls the result stream processing.
++ */
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif /* HAVE_CONFIG_H */
++
++#include <stdarg.h>
++#include <stdio.h>
++
++#if HAVE_STDLIB_H
++#include <stdlib.h>
++#endif /* HAVE_STDLIB_H */
++
++#if HAVE_STRING_H
++#include <string.h>
++#endif /* HAVE_STDLIB_H */
++
++#include "pool.h"
++#include "tds.h"
++
++TDS_RCSID(var, "$Id: stream.c,v 1.25 2007/06/19 13:31:34 freddy77 Exp $");
++
++int pool_find_end_token(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int len);
++
++struct tmp_col_struct
++{
++	char *column_name;
++	struct tmp_col_struct *next;
++};
++
++/*
++ *  returns 1 if this end token has the final bit set
++ */
++static int
++is_final_token(const unsigned char *buf)
++{
++	return buf[1] & 0x01 ? 0 : 1;
++}
++
++/*
++ *  computes the number of bytes left to be read from the input stream 
++ *  after this packet is completely processed.
++ *  returns 1 if token overruns the current packet, 0 otherwise.
++ */
++static int
++bytes_left(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int pos, int maxlen, int need)
++{
++	if (pos + need > maxlen) {
++		return 1;
++	} else
++		return 0;
++}
++
++/*
++ * attempts to read a fixed length token, returns 1 if successful
++ * bytes_read is set to the number of bytes read fromt the input stream.
++ */
++static int
++read_fixed_token(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDS_SMALLINT sz;
++	int marker;
++	int pos = 0;
++
++	if (bytes_left(pmbr, buf, pos, maxlen, 1)) {
++		*bytes_read = maxlen;
++		return 0;
++	}
++	marker = buf[pos++];
++	sz = tds_get_token_size(marker);
++	if (bytes_left(pmbr, buf, pos, maxlen, sz)) {
++		*bytes_read = maxlen;
++		return 0;
++	} else {
++		*bytes_read = sz + 1;
++		return 1;
++	}
++}
++
++static int
++read_variable_token(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDS_SMALLINT sz;
++	int pos = 0;
++
++	if (bytes_left(pmbr, buf, pos, maxlen, 3)) {
++		*bytes_read = maxlen;
++		return 0;
++	}
++
++	/* memcpy(&sz,&buf[1],2); */
++	/* FIX ME -- works only in emul little endian mode on bigend boxen */
++	sz = buf[1] + buf[2] * 256;
++	pos += 3;
++	if (bytes_left(pmbr, buf, pos, maxlen, sz)) {
++		*bytes_read = maxlen;
++		return 0;
++	} else {
++		*bytes_read = sz + 3;
++		return 1;
++	}
++}
++
++static int
++read_row(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDSCOLUMN *curcol;
++	TDSRESULTINFO *info;
++	int i, colsize;
++	int pos = 1;		/* skip marker */
++
++	info = pmbr->tds->res_info;
++
++	die_if((!info), "Entered read_row() without a res_info structure.");
++
++	for (i = 0; i < info->num_cols; i++) {
++		curcol = info->columns[i];
++		if (!is_fixed_type(curcol->column_type)) {
++			if (bytes_left(pmbr, buf, pos, maxlen, 1)) {
++				*bytes_read = maxlen;
++				return 0;
++			}
++			colsize = buf[pos++];
++		} else {
++			colsize = tds_get_size_by_type(curcol->column_type);
++		}
++		if (bytes_left(pmbr, buf, pos, maxlen, colsize)) {
++			*bytes_read = maxlen;
++			return 0;
++		}
++		pos += colsize;
++	}
++
++	*bytes_read = pos;
++
++	return 1;
++}
++
++static int
++read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDS_SMALLINT hdrsize;
++	int pos = 0;
++	int stop = 0, num_cols = 0;
++	int namelen;
++	struct tmp_col_struct *head = NULL, *cur = NULL, *prev;
++	int col;
++	TDSCOLUMN *curcol;
++	TDSRESULTINFO *info;
++
++	/* header size */
++	if (bytes_left(pmbr, buf, pos, maxlen, 3)) {
++		*bytes_read = maxlen;
++		return 0;
++	}
++	/* FIX ME -- endian */
++	hdrsize = buf[1] + buf[2] * 256;
++	pos += 3;
++
++	while (!stop) {
++		prev = cur;
++		cur = (struct tmp_col_struct *)
++			malloc(sizeof(struct tmp_col_struct));
++		if (prev)
++			prev->next = cur;
++		if (!head)
++			head = cur;
++
++		if (bytes_left(pmbr, buf, pos, maxlen, 1)) {
++			*bytes_read = maxlen;
++			return 0;
++		}
++		namelen = buf[pos++];
++
++
++		if (bytes_left(pmbr, buf, pos, maxlen, namelen)) {
++			*bytes_read = maxlen;
++			return 0;
++		}
++		cur->column_name = (char *) malloc(namelen + 1);
++		strncpy(cur->column_name, (char *) &buf[pos], namelen);
++		cur->column_name[namelen] = '\0';
++		cur->next = NULL;
++
++		pos += namelen;
++
++		num_cols++;
++
++		if (pos >= hdrsize)
++			stop = 1;
++	}
++
++	tds_free_all_results(pmbr->tds);
++	pmbr->tds->res_info = tds_alloc_results(num_cols);
++	info = pmbr->tds->res_info;
++
++	cur = head;
++
++	for (col = 0; col < info->num_cols; col++) {
++		curcol = info->columns[col];
++		strncpy(curcol->column_name, cur->column_name, sizeof(curcol->column_name));
++		/* FIXME ucs2 client and others */
++		curcol->column_name[sizeof(curcol->column_name) - 1] = 0;
++		curcol->column_namelen = strlen(curcol->column_name);
++		prev = cur;
++		cur = cur->next;
++		free(prev->column_name);
++		free(prev);
++	}
++
++
++	*bytes_read = pos;
++	return 1;
++}
++
++static int
++read_col_info(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDS_SMALLINT hdrsize;
++	int pos = 0;
++	int col, rest;
++	TDSCOLUMN *curcol;
++	TDSRESULTINFO *info;
++	TDSSOCKET *tds = pmbr->tds;
++
++	/* header size */
++	if (bytes_left(pmbr, buf, pos, maxlen, 3)) {
++		*bytes_read = maxlen;
++		return 0;
++	}
++	/* FIX ME -- endian */
++	hdrsize = buf[1] + buf[2] * 256;
++	pos += 3;
++
++	info = tds->res_info;
++	for (col = 0; col < info->num_cols; col++) {
++		curcol = info->columns[col];
++		if (bytes_left(pmbr, buf, pos, maxlen, 5)) {
++			*bytes_read = maxlen;
++			return 0;
++		}
++		pos += 4;
++		curcol->column_type = buf[pos++];
++
++		/* FIX ME -- blob types */
++		if (!is_fixed_type(curcol->column_type)) {
++			if (bytes_left(pmbr, buf, pos, maxlen, 1)) {
++				*bytes_read = maxlen;
++				return 0;
++			}
++			curcol->column_size = buf[pos++];
++		} else {
++			curcol->column_size = tds_get_size_by_type(curcol->column_type);
++		}
++	}
++
++	rest = hdrsize + 3 - pos;
++	if (rest > 0) {
++		if (bytes_left(pmbr, buf, pos, maxlen, rest)) {
++			*bytes_read = maxlen;
++			return 0;
++		}
++		fprintf(stderr, "read_col_info: draining %d bytes\n", rest);
++		pos += rest;
++	}
++	*bytes_read = pos;
++
++	return 1;
++}
++
++/*
++ * TDS 5 style result sets
++ */
++static int
++read_result(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDS_SMALLINT hdrsize;
++	int pos = 0;
++	int namelen;
++	int col;
++	TDSSOCKET *tds = pmbr->tds;
++	int num_cols;
++	TDSCOLUMN *curcol;
++	TDSRESULTINFO *info;
++
++	if (bytes_left(pmbr, buf, pos, maxlen, 3)) {
++		*bytes_read = maxlen;
++		return 0;
++	}
++	/* FIX ME -- endian */
++	hdrsize = buf[1] + buf[2] * 256;
++	pos += 3;
++
++	/* read number of columns and allocate the columns structure */
++	num_cols = buf[pos] + buf[pos+1] * 256;
++	pos += 2;
++
++	tds_free_all_results(tds);
++
++	tds->res_info = tds_alloc_results(num_cols);
++	info = pmbr->tds->res_info;
++
++	/*
++	 * loop through the columns populating COLINFO struct from
++ 	 * server response
++	 */
++
++	for (col = 0; col < info->num_cols; col++) {
++		curcol = info->columns[col];
++
++		namelen = buf[pos++];
++
++		strncpy(curcol->column_name, (char *) &buf[pos], namelen);
++		curcol->column_name[namelen] = '\0';
++		pos += namelen;
++
++		curcol->column_namelen = namelen;
++
++		pos++;     /* flags */
++		pos += 4;  /* user type */
++
++		tds_set_column_type(tds, curcol, (int)buf[pos]);
++		switch(curcol->column_varint_size) {
++			/* FIX ME - endian */
++			case 2: curcol->column_size = buf[pos] + buf[pos+1]*256; break;
++			case 1: curcol->column_size = buf[pos]; break;
++			case 0: break;
++		}
++		pos+=curcol->column_varint_size;
++		if (is_numeric_type(curcol->column_type))
++			pos+=2;
++
++		/* skip locale information */
++		pos += buf[pos];
++	}
++	return tds_alloc_row(info);
++}
++
++/* 
++ * is_end_token processes one token and returns 0 for an incomplete token
++ * or -1 if this is the END token, and 1 for successful processing of token.  
++ * The number of bytes read from the stream is returned in 'bytes_read'.
++ */
++static int
++pool_is_end_token(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
++{
++	TDS_SMALLINT sz;
++	int marker;
++	int ret;
++
++	if (maxlen == 0)
++		return 0;
++
++	marker = buf[0];
++	sz = tds_get_token_size(marker);
++
++	if (sz) {
++		ret = read_fixed_token(pmbr, buf, maxlen, bytes_read);
++	} else if (marker == TDS_ROW_TOKEN) {
++		ret = read_row(pmbr, buf, maxlen, bytes_read);
++	} else if (marker == TDS_COLNAME_TOKEN) {
++		ret = read_col_name(pmbr, buf, maxlen, bytes_read);
++	} else if (marker == TDS_COLFMT_TOKEN) {
++		ret = read_col_info(pmbr, buf, maxlen, bytes_read);
++	} else if (marker == TDS_RESULT_TOKEN) {
++		ret = read_result(pmbr, buf, maxlen, bytes_read);
++	} else {
++		ret = read_variable_token(pmbr, buf, maxlen, bytes_read);
++	}
++
++	/* fprintf(stderr,"bytes_read = %d\n",*bytes_read); */
++	if (!ret) {
++		return 0;
++	}
++
++	if (is_end_token(marker)) {
++		if (is_final_token(buf)) {
++			/* clean up */
++			return -1;
++		}
++	}
++
++	return 1;
++}
++
++int
++pool_find_end_token(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int len)
++{
++	int pos = 0, startpos, ret;
++	int bytes_read;
++	int stop = 0;
++	const unsigned char *curbuf;
++	unsigned char tmpbuf[PGSIZ + BLOCKSIZ];
++	int totlen;
++	static int last_mark;
++
++	/*
++	 * if we had part of a token left over, copy to tmpbuf
++	 */
++	if (pmbr->num_bytes_left) {
++		/* fprintf(stderr,"%d bytes left from last packet\n",pmbr->num_bytes_left); */
++		if (pmbr->num_bytes_left > 2000) {
++			fprintf(stderr, "marker is %d last mark was %d\n", pmbr->fragment[0], last_mark);
++		}
++		memcpy(tmpbuf, pmbr->fragment, pmbr->num_bytes_left);
++		memcpy(&tmpbuf[pmbr->num_bytes_left], buf, len);
++		curbuf = tmpbuf;
++		totlen = len + pmbr->num_bytes_left;
++	} else {
++		curbuf = buf;
++		totlen = len;
++	}
++
++	do {
++		startpos = pos;
++
++		ret = pool_is_end_token(pmbr, &curbuf[pos], totlen - pos, &bytes_read);
++		if (ret <= 0)
++			stop = 1;
++
++		pos += bytes_read;
++	} while (!stop);
++
++	if (ret == -1) {
++		pmbr->num_bytes_left = 0;
++		return 1;	/* found end token */
++	} else {
++		last_mark = buf[0];
++		pmbr->num_bytes_left = totlen - startpos;
++		memcpy(pmbr->fragment, &curbuf[startpos], pmbr->num_bytes_left);
++		return 0;	/* exhausted the stream */
++	}
++}
+diff --git b/src/replacements/.cvsignore a/src/replacements/.cvsignore
+new file mode 100644
+index 0000000..aee705c
+--- /dev/null
++++ a/src/replacements/.cvsignore
+@@ -0,0 +1,6 @@
++Makefile
++Makefile.in
++.libs
++*.lo
++*.la
++.deps
+diff --git b/src/server/.cvsignore a/src/server/.cvsignore
+new file mode 100644
+index 0000000..276eddd
+--- /dev/null
++++ a/src/server/.cvsignore
+@@ -0,0 +1,7 @@
++Makefile
++Makefile.in
++.libs
++*.lo
++*.la
++.deps
++tdssrv
+diff --git b/src/tds/.cvsignore a/src/tds/.cvsignore
+new file mode 100644
+index 0000000..f9b4f83
+--- /dev/null
++++ a/src/tds/.cvsignore
+@@ -0,0 +1,11 @@
++Makefile
++Makefile.in
++.libs
++*.lo
++*.la
++.deps
++num_limits.h
++sybase_character_sets.h
++tds_willconvert.h
++encodings.h
++
+diff --git b/src/tds/alternative_character_sets.h a/src/tds/alternative_character_sets.h
+new file mode 100644
+index 0000000..662abd4
+--- /dev/null
++++ a/src/tds/alternative_character_sets.h
+@@ -0,0 +1,428 @@
++/*
++ * Copyright 2003 James K. Lowden <jklowden@schemamania.org>
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted, provided that redistributions of source 
++ * code retain the above copyright notice.  
++ */
++ 
++ /* 
++  * The purpose of this file is to help look up character set names.  
++  * 
++  * Any given encoding may be known by several (usually similar) aliases.  
++  * For example, a system using ASCII encoding may report the character set as 
++  * "ASCII", "US-ASCII", or "ISO646-US", among others.  For details on what your system 
++  * uses, you may wish to consult the nl_langinfo(3) manual page.  
++  *
++  * GNU iconv converts a byte sequence from one encoding to another, but before it can do 
++  * so, it must be told which is which.  In the list below, the preferred GNU iconv(3) name 
++  * is on the left and an alias is on the right.  It is a simple exercise, left to the reader, 
++  * to write a function that uses these data to look up the canonical name when provided 
++  * an alias.  
++  */
++
++#ifndef _ALTERNATIVE_CHARACTER_SETS_H_
++#define _ALTERNATIVE_CHARACTER_SETS_H_
++
++/*
++ * $Id: alternative_character_sets.h,v 1.10 2005/02/26 13:08:32 freddy77 Exp $
++ */
++ 
++/* 
++ * This list is sorted alphabetically, except that the most
++ * commonly used character sets are first.
++ */
++ 	 /* ASCII */
++	  {         "US-ASCII", "US-ASCII"               }
++	, {         "US-ASCII", "ANSI_X3.4-1968"         }
++	, {         "US-ASCII", "ANSI_X3.4-1986"         }
++	, {         "US-ASCII", "ASCII"                  }
++	, {         "US-ASCII", "CP367"                  }
++	, {         "US-ASCII", "CSASCII"                }
++	, {         "US-ASCII", "IBM367"                 }
++	, {         "US-ASCII", "ISO-IR-6"               }
++	, {         "US-ASCII", "ISO646-US"              }
++	, {         "US-ASCII", "ISO_646.IRV:1991"       }
++	, {         "US-ASCII", "US"                     }
++	, {         "US-ASCII", "646"                    }	/* NetBSD default */
++ 	 /* ISO_8859-1 */
++	, {       "ISO-8859-1", "ISO-8859-1"             }
++	, {       "ISO-8859-1", "CP819"                  }
++	, {       "ISO-8859-1", "CSISOLATIN1"            }
++	, {       "ISO-8859-1", "IBM819"                 }
++	, {       "ISO-8859-1", "ISO-IR-100"             }
++	, {       "ISO-8859-1", "ISO8859-1"              }
++	, {       "ISO-8859-1", "ISO_8859-1"             }
++	, {       "ISO-8859-1", "ISO_8859-1:1987"        }
++	, {       "ISO-8859-1", "L1"                     }
++	, {       "ISO-8859-1", "LATIN1"                 }
++	, {       "ISO-8859-1", "iso81"                  }
++	, {       "ISO-8859-1", "iso88591"               }
++ 	 /* UCS-2 */
++	, {            "UCS-2", "UCS-2"                  }
++	, {            "UCS-2", "CSUNICODE"              }
++	, {            "UCS-2", "ISO-10646-UCS-2"        }
++	, {            "UCS-2", "UCS2"                   }
++	, {            "UCS-2", "ucs2"                   }
++	, {   "UCS-2-INTERNAL", "UCS-2-INTERNAL"         }
++	, {    "UCS-2-SWAPPED", "UCS-2-SWAPPED"          }
++	, {          "UCS-2BE", "UCS-2BE"                }
++	, {          "UCS-2BE", "CSUNICODE11"            }
++	, {          "UCS-2BE", "UNICODE-1-1"            }
++	, {          "UCS-2BE", "UNICODEBIG"             }
++	, {          "UCS-2LE", "UCS-2LE"                }
++	, {          "UCS-2LE", "UNICODELITTLE"          }
++ 	 /* UTF-8 */
++	, {            "UTF-8", "UTF-8"                  }
++	, {            "UTF-8", "UTF8"                   }
++	, {            "UTF-8", "utf8"                   }
++
++ 	 /* Basically alphabetical from here */
++	, {        "ARMSCII-8", "ARMSCII-8"              }
++	, {            "BIG-5", "BIG-5"                  }
++	, {            "BIG-5", "BIG-FIVE"               }
++	, {            "BIG-5", "BIG5"                   }
++	, {            "BIG-5", "BIGFIVE"                }
++	, {            "BIG-5", "CN-BIG5"                }
++	, {            "BIG-5", "CSBIG5"                 }
++	, {            "BIG-5", "big5"                   }
++	, {       "BIG5-HKSCS", "BIG5-HKSCS"             }
++	, {       "BIG5-HKSCS", "BIG5HKSCS"              }
++	, {              "C99", "C99"                    }
++	, {          "CHINESE", "CHINESE"                }
++	, {          "CHINESE", "CSISO58GB231280"        }
++	, {          "CHINESE", "GB_2312-80"             }
++	, {          "CHINESE", "ISO-IR-58"              }
++	, {          "CHINESE", "hp15CN"                 }
++	, {               "CN", "CN"                     }
++	, {               "CN", "CSISO57GB1988"          }
++	, {               "CN", "GB_1988-80"             }
++	, {               "CN", "ISO-IR-57"              }
++	, {               "CN", "ISO646-CN"              }
++	, {            "CN-GB", "CN-GB"                  }
++	, {            "CN-GB", "CSGB2312"               }
++	, {            "CN-GB", "EUC-CN"                 }
++	, {            "CN-GB", "EUCCN"                  }
++	, {            "CN-GB", "GB2312"                 }
++	, {   "CN-GB-ISOIR165", "CN-GB-ISOIR165"         }
++	, {   "CN-GB-ISOIR165", "ISO-IR-165"             }
++	, {           "CP1133", "CP1133"                 }
++	, {           "CP1133", "IBM-CP1133"             }
++	, {           "CP1250", "CP1250"                 }
++	, {           "CP1250", "MS-EE"                  }
++	, {           "CP1250", "WINDOWS-1250"           }
++	, {           "CP1250", "cp1250"                 }
++	, {           "CP1251", "CP1251"                 }
++	, {           "CP1251", "MS-CYRL"                }
++	, {           "CP1251", "WINDOWS-1251"           }
++	, {           "CP1251", "cp1251"                 }
++	, {           "CP1252", "CP1252"                 }
++	, {           "CP1252", "MS-ANSI"                }
++	, {           "CP1252", "WINDOWS-1252"           }
++	, {           "CP1252", "cp1252"                 }
++	, {           "CP1253", "CP1253"                 }
++	, {           "CP1253", "MS-GREEK"               }
++	, {           "CP1253", "WINDOWS-1253"           }
++	, {           "CP1253", "cp1253"                 }
++	, {           "CP1254", "CP1254"                 }
++	, {           "CP1254", "MS-TURK"                }
++	, {           "CP1254", "WINDOWS-1254"           }
++	, {           "CP1254", "cp1254"                 }
++	, {           "CP1255", "CP1255"                 }
++	, {           "CP1255", "MS-HEBR"                }
++	, {           "CP1255", "WINDOWS-1255"           }
++	, {           "CP1255", "cp1255"                 }
++	, {           "CP1256", "CP1256"                 }
++	, {           "CP1256", "MS-ARAB"                }
++	, {           "CP1256", "WINDOWS-1256"           }
++	, {           "CP1256", "cp1256"                 }
++	, {           "CP1257", "CP1257"                 }
++	, {           "CP1257", "WINBALTRIM"             }
++	, {           "CP1257", "WINDOWS-1257"           }
++	, {           "CP1257", "cp1257"                 }
++	, {           "CP1258", "CP1258"                 }
++	, {           "CP1258", "WINDOWS-1258"           }
++	, {           "CP1258", "cp1258"                 }
++	, {           "CP1361", "CP1361"                 }
++	, {           "CP1361", "JOHAB"                  }
++	, {            "CP850", "CP850"                  }
++	, {            "CP850", "850"                    }
++	, {            "CP850", "CSPC850MULTILINGUAL"    }
++	, {            "CP850", "IBM850"                 }
++	, {            "CP850", "cp850"                  }
++	, {            "CP862", "CP862"                  }
++	, {            "CP862", "862"                    }
++	, {            "CP862", "CSPC862LATINHEBREW"     }
++	, {            "CP862", "IBM862"                 }
++	, {            "CP862", "cp862"                  }
++	, {            "CP866", "CP866"                  }
++	, {            "CP866", "866"                    }
++	, {            "CP866", "CSIBM866"               }
++	, {            "CP866", "IBM866"                 }
++	, {            "CP866", "cp866"                  }
++	, {            "CP874", "CP874"                  }
++	, {            "CP874", "WINDOWS-874"            }
++	, {            "CP874", "cp874"                  }
++	, {            "CP932", "CP932"                  }
++	, {            "CP936", "CP936"                  }
++	, {            "CP936", "GBK"                    }
++	, {            "CP949", "CP949"                  }
++	, {            "CP949", "UHC"                    }
++	, {            "CP950", "CP950"                  }
++	, {            "CP437", "CP437"                  }
++	, {            "CP437", "cp437"                  }
++	, {            "CP437", "IBM437"                 }
++	, {           "EUC-JP", "EUC-JP"                 }
++	, {           "EUC-JP", "CSEUCPKDFMTJAPANESE"    }
++	, {           "EUC-JP", "EUCJP"                  }
++	, {           "EUC-JP", "EXTENDED_UNIX_CODE_PACKED_FORMAT_FOR_JAPANESE"}
++	, {           "EUC-JP", "eucJP"                  }
++	, {           "EUC-KR", "EUC-KR"                 }
++	, {           "EUC-KR", "CSEUCKR"                }
++	, {           "EUC-KR", "EUCKR"                  }
++	, {           "EUC-KR", "eucKR"                  }
++	, {           "EUC-TW", "CSEUCTW"                }
++	, {           "EUC-TW", "EUC-TW"                 }
++	, {           "EUC-TW", "EUCTW"                  }
++	, {           "EUC-TW", "eucTW"                  }
++	, {          "GB18030", "GB18030"                }
++	, { "GEORGIAN-ACADEMY", "GEORGIAN-ACADEMY"       }
++	, {      "GEORGIAN-PS", "GEORGIAN-PS"            }
++	, {               "HZ", "HZ"                     }
++	, {               "HZ", "HZ-GB-2312"             }
++	, {      "ISO-2022-CN", "ISO-2022-CN"            }
++	, {      "ISO-2022-CN", "CSISO2022CN"            }
++	, {  "ISO-2022-CN-EXT", "ISO-2022-CN-EXT"        }
++	, {      "ISO-2022-JP", "ISO-2022-JP"            }
++	, {      "ISO-2022-JP", "CSISO2022JP"            }
++	, {    "ISO-2022-JP-1", "ISO-2022-JP-1"          }
++	, {    "ISO-2022-JP-2", "ISO-2022-JP-2"          }
++	, {    "ISO-2022-JP-2", "CSISO2022JP2"           }
++	, {      "ISO-2022-KR", "ISO-2022-KR"            }
++	, {      "ISO-2022-KR", "CSISO2022KR"            }
++	, {      "ISO-8859-10", "ISO-8859-10"            }
++	, {      "ISO-8859-10", "CSISOLATIN6"            }
++	, {      "ISO-8859-10", "ISO-IR-157"             }
++	, {      "ISO-8859-10", "ISO8859-10"             }
++	, {      "ISO-8859-10", "ISO_8859-10"            }
++	, {      "ISO-8859-10", "ISO_8859-10:1992"       }
++	, {      "ISO-8859-10", "L6"                     }
++	, {      "ISO-8859-10", "LATIN6"                 }
++	, {      "ISO-8859-13", "ISO-8859-13"            }
++	, {      "ISO-8859-13", "ISO-IR-179"             }
++	, {      "ISO-8859-13", "ISO_8859-13"            }
++	, {      "ISO-8859-13", "L7"                     }
++	, {      "ISO-8859-13", "LATIN7"                 }
++	, {      "ISO-8859-14", "ISO-8859-14"            }
++	, {      "ISO-8859-14", "ISO-CELTIC"             }
++	, {      "ISO-8859-14", "ISO-IR-199"             }
++	, {      "ISO-8859-14", "ISO_8859-14"            }
++	, {      "ISO-8859-14", "ISO_8859-14:1998"       }
++	, {      "ISO-8859-14", "L8"                     }
++	, {      "ISO-8859-14", "LATIN8"                 }
++	, {      "ISO-8859-15", "ISO8859-15"             }
++	, {      "ISO-8859-15", "ISO-8859-15"            }
++	, {      "ISO-8859-15", "ISO-IR-203"             }
++	, {      "ISO-8859-15", "ISO_8859-15"            }
++	, {      "ISO-8859-15", "ISO_8859-15:1998"       }
++	, {      "ISO-8859-15", "iso815"                 }
++	, {      "ISO-8859-15", "iso885915"              }
++	, {      "ISO-8859-16", "ISO-8859-16"            }
++	, {      "ISO-8859-16", "ISO-IR-226"             }
++	, {      "ISO-8859-16", "ISO_8859-16"            }
++	, {      "ISO-8859-16", "ISO_8859-16:2000"       }
++	, {       "ISO-8859-2", "ISO-8859-2"             }
++	, {       "ISO-8859-2", "CSISOLATIN2"            }
++	, {       "ISO-8859-2", "ISO8859-2"              }
++	, {       "ISO-8859-2", "ISO-IR-101"             }
++	, {       "ISO-8859-2", "ISO_8859-2"             }
++	, {       "ISO-8859-2", "ISO_8859-2:1987"        }
++	, {       "ISO-8859-2", "L2"                     }
++	, {       "ISO-8859-2", "LATIN2"                 }
++	, {       "ISO-8859-2", "iso82"                  }
++	, {       "ISO-8859-2", "iso88592"               }
++	, {       "ISO-8859-3", "ISO-8859-3"             }
++	, {       "ISO-8859-3", "CSISOLATIN3"            }
++	, {       "ISO-8859-3", "ISO-IR-109"             }
++	, {       "ISO-8859-3", "ISO_8859-3"             }
++	, {       "ISO-8859-3", "ISO_8859-3:1988"        }
++	, {       "ISO-8859-3", "L3"                     }
++	, {       "ISO-8859-3", "LATIN3"                 }
++	, {       "ISO-8859-3", "iso83"                  }
++	, {       "ISO-8859-3", "iso88593"               }
++	, {       "ISO-8859-4", "ISO8859-4"              }
++	, {       "ISO-8859-4", "CSISOLATIN4"            }
++	, {       "ISO-8859-4", "ISO-8859-4"             }
++	, {       "ISO-8859-4", "ISO-IR-110"             }
++	, {       "ISO-8859-4", "ISO_8859-4"             }
++	, {       "ISO-8859-4", "ISO_8859-4:1988"        }
++	, {       "ISO-8859-4", "L4"                     }
++	, {       "ISO-8859-4", "LATIN4"                 }
++	, {       "ISO-8859-4", "iso84"                  }
++	, {       "ISO-8859-4", "iso88594"               }
++	, {       "ISO-8859-5", "ISO-8859-5"             }
++	, {       "ISO-8859-5", "CSISOLATINCYRILLIC"     }
++	, {       "ISO-8859-5", "CYRILLIC"               }
++	, {       "ISO-8859-5", "ISO8859-5"              }
++	, {       "ISO-8859-5", "ISO-IR-144"             }
++	, {       "ISO-8859-5", "ISO8859-5"              }
++	, {       "ISO-8859-5", "ISO_8859-5"             }
++	, {       "ISO-8859-5", "ISO_8859-5:1988"        }
++	, {       "ISO-8859-5", "iso85"                  }
++	, {       "ISO-8859-5", "iso88595"               }
++	, {       "ISO-8859-6", "ISO-8859-6"             }
++	, {       "ISO-8859-6", "ARABIC"                 }
++	, {       "ISO-8859-6", "ASMO-708"               }
++	, {       "ISO-8859-6", "CSISOLATINARABIC"       }
++	, {       "ISO-8859-6", "ECMA-114"               }
++	, {       "ISO-8859-6", "ISO-IR-127"             }
++	, {       "ISO-8859-6", "ISO8859-6"              }
++	, {       "ISO-8859-6", "ISO_8859-6"             }
++	, {       "ISO-8859-6", "ISO_8859-6:1987"        }
++	, {       "ISO-8859-6", "iso86"                  }
++	, {       "ISO-8859-6", "iso88596"               }
++	, {       "ISO-8859-7", "ISO-8859-7"             }
++	, {       "ISO-8859-7", "CSISOLATINGREEK"        }
++	, {       "ISO-8859-7", "ECMA-118"               }
++	, {       "ISO-8859-7", "ELOT_928"               }
++	, {       "ISO-8859-7", "GREEK"                  }
++	, {       "ISO-8859-7", "GREEK8"                 }
++	, {       "ISO-8859-7", "ISO-IR-126"             }
++	, {       "ISO-8859-7", "ISO8859-7"              }
++	, {       "ISO-8859-7", "ISO_8859-7"             }
++	, {       "ISO-8859-7", "ISO_8859-7:1987"        }
++	, {       "ISO-8859-7", "iso87"                  }
++	, {       "ISO-8859-7", "iso88597"               }
++	, {       "ISO-8859-8", "ISO-8859-8"             }
++	, {       "ISO-8859-8", "CSISOLATINHEBREW"       }
++	, {       "ISO-8859-8", "HEBREW"                 }
++	, {       "ISO-8859-8", "ISO8859-8"              }
++	, {       "ISO-8859-8", "ISO-IR-138"             }
++	, {       "ISO-8859-8", "ISO_8859-8"             }
++	, {       "ISO-8859-8", "ISO_8859-8:1988"        }
++	, {       "ISO-8859-8", "iso88"                  }
++	, {       "ISO-8859-8", "iso88598"               }
++	, {       "ISO-8859-9", "ISO-8859-9"             }
++	, {       "ISO-8859-9", "CSISOLATIN5"            }
++	, {       "ISO-8859-9", "ISO-IR-148"             }
++	, {       "ISO-8859-9", "ISO8859-9"              }
++	, {       "ISO-8859-9", "ISO_8859-9"             }
++	, {       "ISO-8859-9", "ISO_8859-9:1989"        }
++	, {       "ISO-8859-9", "L5"                     }
++	, {       "ISO-8859-9", "LATIN5"                 }
++	, {       "ISO-8859-9", "iso88599"               }
++	, {       "ISO-8859-9", "iso89"                  }
++	, {        "ISO-IR-14", "ISO-IR-14"              }
++	, {        "ISO-IR-14", "CSISO14JISC6220RO"      }
++	, {        "ISO-IR-14", "ISO646-JP"              }
++	, {        "ISO-IR-14", "JIS_C6220-1969-RO"      }
++	, {        "ISO-IR-14", "JP"                     }
++	, {       "ISO-IR-149", "ISO-IR-149"             }
++	, {       "ISO-IR-149", "CSKSC56011987"          }
++	, {       "ISO-IR-149", "KOREAN"                 }
++	, {       "ISO-IR-149", "KSC_5601"               }
++	, {       "ISO-IR-149", "KS_C_5601-1987"         }
++	, {       "ISO-IR-149", "KS_C_5601-1989"         }
++	, {       "ISO-IR-159", "ISO-IR-159"             }
++	, {       "ISO-IR-159", "CSISO159JISX02121990"   }
++	, {       "ISO-IR-159", "JIS_X0212"              }
++	, {       "ISO-IR-159", "JIS_X0212-1990"         }
++	, {       "ISO-IR-159", "JIS_X0212.1990-0"       }
++	, {       "ISO-IR-159", "X0212"                  }
++	, {       "ISO-IR-166", "ISO-IR-166"             }
++	, {       "ISO-IR-166", "TIS-620"                }
++	, {       "ISO-IR-166", "TIS620"                 }
++	, {       "ISO-IR-166", "TIS620-0"               }
++	, {       "ISO-IR-166", "TIS620.2529-1"          }
++	, {       "ISO-IR-166", "TIS620.2533-0"          }
++	, {       "ISO-IR-166", "TIS620.2533-1"          }
++	, {       "ISO-IR-166", "thai8"                  }
++	, {       "ISO-IR-166", "tis620"                 }
++	, {        "ISO-IR-87", "ISO-IR-87"              }
++	, {        "ISO-IR-87", "CSISO87JISX0208"        }
++	, {        "ISO-IR-87", "JIS0208"                }
++	, {        "ISO-IR-87", "JIS_C6226-1983"         }
++	, {        "ISO-IR-87", "JIS_X0208"              }
++	, {        "ISO-IR-87", "JIS_X0208-1983"         }
++	, {        "ISO-IR-87", "JIS_X0208-1990"         }
++	, {        "ISO-IR-87", "X0208"                  }
++	, {             "JAVA", "JAVA"                   }
++	, {    "JISX0201-1976", "JISX0201-1976"          }
++	, {    "JISX0201-1976", "CSHALFWIDTHKATAKANA"    }
++	, {    "JISX0201-1976", "JIS_X0201"              }
++	, {    "JISX0201-1976", "X0201"                  }
++	, {           "KOI8-R", "KOI8-R"                 }
++	, {           "KOI8-R", "CSKOI8R"                }
++	, {          "KOI8-RU", "KOI8-RU"                }
++	, {           "KOI8-T", "KOI8-T"                 }
++	, {           "KOI8-U", "KOI8-U"                 }
++	, {              "MAC", "MAC"                    }
++	, {              "MAC", "CSMACINTOSH"            }
++	, {              "MAC", "MACINTOSH"              }
++	, {              "MAC", "MACROMAN"               }
++	, {        "MACARABIC", "MACARABIC"              }
++	, { "MACCENTRALEUROPE", "MACCENTRALEUROPE"       }
++	, {      "MACCROATIAN", "MACCROATIAN"            }
++	, {      "MACCYRILLIC", "MACCYRILLIC"            }
++	, {         "MACGREEK", "MACGREEK"               }
++	, {        "MACHEBREW", "MACHEBREW"              }
++	, {       "MACICELAND", "MACICELAND"             }
++	, {       "MACROMANIA", "MACROMANIA"             }
++	, {          "MACTHAI", "MACTHAI"                }
++	, {       "MACTURKISH", "MACTURKISH"             }
++	, {       "MACUKRAINE", "MACUKRAINE"             }
++	, {        "MULELAO-1", "MULELAO-1"              }
++	, {         "NEXTSTEP", "NEXTSTEP"               }
++	, {           "ROMAN8", "ROMAN8"                 }
++	, {           "ROMAN8", "CSHPROMAN8"             }
++	, {           "ROMAN8", "HP-ROMAN8"              }
++	, {           "ROMAN8", "R8"                     }
++	, {           "ROMAN8", "roma8"                  }
++	, {           "ROMAN8", "roman8"                 }
++	, {             "SJIS", "SJIS"                   }
++	, {             "SJIS", "CSSHIFTJIS"             }
++	, {             "SJIS", "MS_KANJI"               }
++	, {             "SJIS", "SHIFT-JIS"              }
++	, {             "SJIS", "SHIFT_JIS"              }
++	, {             "SJIS", "sjis"                   }
++	, {             "TCVN", "TCVN"                   }
++	, {             "TCVN", "TCVN-5712"              }
++	, {             "TCVN", "TCVN5712-1"             }
++	, {             "TCVN", "TCVN5712-1:1993"        }
++	, {            "UCS-4", "UCS-4"                  }
++	, {            "UCS-4", "CSUCS4"                 }
++	, {            "UCS-4", "ISO-10646-UCS-4"        }
++	, {            "UCS-4", "UCS4"                   }
++	, {            "UCS-4", "ucs4"                   }
++	, {   "UCS-4-INTERNAL", "UCS-4-INTERNAL"         }
++	, {    "UCS-4-SWAPPED", "UCS-4-SWAPPED"          }
++	, {          "UCS-4BE", "UCS-4BE"                }
++	, {          "UCS-4LE", "UCS-4LE"                }
++	, {           "UTF-16", "UTF-16"                 }
++	, {           "UTF-16", "UTF16"                  }
++	, {         "UTF-16BE", "UTF-16BE"               }
++	, {         "UTF-16LE", "UTF-16LE"               }
++	, {           "UTF-32", "UTF-32"                 }
++	, {         "UTF-32BE", "UTF-32BE"               }
++	, {         "UTF-32LE", "UTF-32LE"               }
++	, {            "UTF-7", "UTF-7"                  }
++	, {            "UTF-7", "CSUNICODE11UTF7"        }
++	, {            "UTF-7", "UNICODE-1-1-UTF-7"      }
++	, {            "UTF-7", "UTF7"                   }
++	, {           "VISCII", "VISCII"                 }
++	, {           "VISCII", "CSVISCII"               }
++	, {           "VISCII", "VISCII1.1-1"            }
++
++	/* 
++	 * The following are noted in Tru64 manuals, but 
++	 * have no canonical names in FreeTDS
++	 *
++	 * 	TACTIS          TACTIS codeset	               
++	 * 	dechanyu        DEC Hanyu codeset              
++	 * 	dechanzi        DEC Hanzi codeset              
++	 * 	deckanji        DEC Kanji codeset              
++	 * 	deckorean       DEC Korean codeset             
++	 * 	sdeckanji       Super DEC Kanji codeset        
++	 */
++	 
++	/* no stopper row; add your own */
++#endif
+diff --git b/src/tds/character_sets.h a/src/tds/character_sets.h
+new file mode 100644
+index 0000000..2f6d1c7
+--- /dev/null
++++ a/src/tds/character_sets.h
+@@ -0,0 +1,125 @@
++/* 
++ * These are the canonical names for character sets accepted by GNU iconv.  
++ * See its documentation for the standard it follows.  
++ * 
++ * GNU iconv accepts other character set names, too, and your favorite operating system
++ * very likely uses still other names to represent the _same_ character set.  
++ * 
++ * Alternative character set names are mapped to these canonical ones in 
++ * alternative_character_sets.h and are accessed with canonical_charset();
++ */
++		  {"ISO-8859-1",	1, 1}
++		, {"UTF-8", 		1, 4}
++		, {"UCS-2LE", 		2, 2}
++		, {"UCS-2BE", 		2, 2}
++		, {"UCS-2",		2, 2}
++		, {"US-ASCII",		1, 1}
++		, {"UCS-4",		4, 4}
++		, {"UCS-4BE", 		4, 4}
++		, {"UCS-4LE", 		4, 4}
++		, {"UTF-16", 		2, 4}
++		, {"UTF-16BE", 		2, 4}
++		, {"UTF-16LE", 		2, 4}
++		, {"UTF-32", 		4, 4}
++		, {"UTF-32BE", 		4, 4}
++		, {"UTF-32LE", 		4, 4}
++		, {"UTF-7",		1, 4}
++		, {"UCS-2-INTERNAL", 	2, 2}
++		, {"UCS-2-SWAPPED", 	2, 2}
++		, {"UCS-4-INTERNAL", 	4, 4}
++		, {"UCS-4-SWAPPED", 	4, 4}
++		, {"C99", 		1, 1}
++		, {"JAVA", 		1, 1}
++		, {"ISO-8859-2", 	1, 1}
++		, {"ISO-8859-3", 	1, 1}
++		, {"ISO-8859-4", 	1, 1}
++		, {"ISO-8859-5",	1, 1}
++		, {"ISO-8859-6",	1, 1}
++		, {"ISO-8859-7", 	1, 1}
++		, {"ISO-8859-8",	1, 1}
++		, {"ISO-8859-9", 	1, 1}
++		, {"ISO-8859-10", 	1, 1}
++		, {"ISO-8859-13", 	1, 1}
++		, {"ISO-8859-14", 	1, 1}
++		, {"ISO-8859-15", 	1, 1}
++		, {"ISO-8859-16", 	1, 1}
++		, {"KOI8-R", 		1, 1}
++		, {"KOI8-U", 		1, 1}
++		, {"KOI8-RU", 		1, 1}
++		, {"CP1250", 		1, 1}
++		, {"CP1251", 		1, 1}
++		, {"CP1252", 		1, 1}
++		, {"CP1253", 		1, 1}
++		, {"CP1254", 		1, 1}
++		, {"CP1255", 		1, 1}
++		, {"CP1256", 		1, 1}
++		, {"CP1257", 		1, 1}
++		, {"CP1258", 		1, 1}
++		, {"CP850", 		1, 1}
++		, {"CP862", 		1, 1}
++		, {"CP866", 		1, 1}
++		, {"CP437", 		1, 1}
++		, {"MAC", 		1, 1}
++		, {"MACCENTRALEUROPE", 	1, 1}
++		, {"MACICELAND", 	1, 1}
++		, {"MACCROATIAN", 	1, 1}
++		, {"MACROMANIA", 	1, 1}
++		, {"MACCYRILLIC", 	1, 1}
++		, {"MACUKRAINE", 	1, 1}
++		, {"MACGREEK", 		1, 1}
++		, {"MACTURKISH", 	1, 1}
++		, {"MACHEBREW", 	1, 1}
++		, {"MACARABIC", 	1, 1}
++		, {"MACTHAI", 		1, 1}
++		, {"ROMAN8",		1, 1}
++		, {"NEXTSTEP", 		1, 1}
++		, {"ARMSCII-8", 	1, 1}
++		, {"GEORGIAN-ACADEMY", 	1, 1}
++		, {"GEORGIAN-PS", 	1, 1}
++		, {"KOI8-T", 		1, 1}
++		, {"MULELAO-1", 	1, 1}
++		, {"CP1133", 		1, 1}
++		, {"ISO-IR-166", 	1, 1}
++		, {"CP874", 		1, 1}
++		, {"CP936", 		1, 2}
++		, {"CN", 		1, 1}
++		, {"CP932", 		1, 2}
++		, {"CN-GB", 		1, 2}
++		, {"CP950", 		1, 2}
++		, {"CP949", 		1, 2}
++		, {"CP1361", 		1, 2}
++		, {"BIG-5", 		1, 2}
++		, {"BIG5-HKSCS", 	1, 2}
++		, {"SJIS", 		1, 2}
++		, {"EUC-KR", 		1, 2}
++		, {"VISCII", 		1, 1}
++		, {"ISO-IR-14", 	1, 1}
++		, {"EUC-JP", 		1, 3}
++		, {"EUC-TW", 		1, 4}
++		, {"ISO-2022-JP", 	1, 1}
++		, {"ISO-2022-KR", 	1, 2}
++		, {"ISO-2022-CN", 	1, 4}
++		, {"ISO-2022-CN-EXT", 	1, 4}
++		, {"ISO-2022-JP-2", 	1, 1}
++		, {"GB18030", 		1, 4}
++		/*
++		 * Beyond this point, I don't know the right answers.  
++		 * If you can provide the correct min/max (byte/char) values, please
++		 * correct them if necessary and move them above the stopper row.
++		 * Will the person vetting the last unknown row please turn off the lights?  
++		 * --jkl April 2003
++		 */
++		, {"",	 		0, 0}	/* stopper row */
++		
++		, {"TCVN", 		1, 1}
++		, {"JISX0201-1976", 	1, 1}
++		, {"ISO-IR-87", 	1, 1}
++		, {"ISO-IR-159", 	1, 1}
++		, {"CHINESE", 		1, 1}
++		, {"CN-GB-ISOIR165", 	1, 1}
++		, {"ISO-IR-149", 	1, 1}
++		, {"ISO-2022-JP-1", 	1, 1}
++		, {"HZ", 		1, 1}
++		/* stopper row */
++		, {"",	 		0, 0}
++		
+diff --git b/src/tds/encodings.pl a/src/tds/encodings.pl
+new file mode 100755
+index 0000000..1017836
+--- /dev/null
++++ a/src/tds/encodings.pl
+@@ -0,0 +1,290 @@
++#!/usr/bin/perl
++## This file is in the public domain.
++use File::Basename;
++
++$basename = basename($0);
++$srcdir = "$ARGV[0]/";
++
++# get list of character sets we know about
++$filename = "${srcdir}alternative_character_sets.h";
++open ALT, $filename or die qq($basename: could not open "$filename"\n);
++while(<ALT>){
++	next unless /^\t[, ] {\s+"(.+?)", "(.+?)"/;
++	$alternates{$2} = $1;
++}
++close ALT;
++
++$alternates{'UTF8'}	= 'UTF-8';
++$alternates{'ISO_1'}    = 'ISO-8859-1';
++$alternates{'ASCII_8'}  = 'ISO-8859-1';
++$alternates{'ISO_1'}    = 'ISO-8859-1';
++$alternates{'ISO646'}   = 'ANSI_X3.4-1968';
++
++$alternates{'MAC_CYR'}  = 'MACCYRILLIC';
++#alternates{'MAC_EE'}   = '';
++$alternates{'MACTURK'}  = 'MACTURKISH';
++
++$alternates{'KOI8'}  = 'KOI8-R';
++
++$filename = "${srcdir}sybase_character_sets.h";
++open(OUT, ">$filename") or die qq($basename: could not open "$filename"\n);
++print OUT "/*\n";
++print OUT " * This file produced from $0\n";
++print OUT ' * $Id: encodings.pl,v 1.10.4.1 2008/03/10 10:07:22 freddy77 Exp $', "\n";
++print OUT " */\n";
++
++# look up the canonical name
++$comma = ' ';
++while(<DATA>){
++	next if /^#/;
++	next if /^\s*$/;
++	($name) = split;
++	$Name = uc $name;
++	$iconv_name = $alternates{$Name};
++	
++	if( !$iconv_name ) { # try predictable transformations
++		$Name =~ s/ISO8859(\d{1,2})$/ISO-8859-$1/;
++		$Name =~ s/ISO(\d{1,2})$/ISO-8859-$1/;
++		
++		$iconv_name = $alternates{$Name};
++	}
++	
++	if( !$iconv_name ) { # try crude transformation
++		$Name =~ s/[\-\_]+//g;
++		$iconv_name = $alternates{$Name};
++	}
++	
++	$name = qq/"$name"/;
++	if( $iconv_name ) { 	# found, print element
++		$iconv_name = qq/"$iconv_name",/;
++		printf OUT "\t$comma { %20s %-15s }\n", $iconv_name , $name;
++	} else {		# not found, print comment
++		$iconv_name = qq/"",/;
++		printf OUT "\t /* %20s %-15s */\n", $iconv_name , $name;
++
++		# grep for similar names, as an aid to the to programmer.  
++		$name =~ s/[\-\_]+//g;
++		print STDERR $Name.":  $name alternative_character_sets.h\n";
++	}
++	$comma = ',';
++}
++print  OUT "\t/* stopper row */\n";
++printf OUT "\t$comma { %20s %-15s }\n", 'NULL,' , 'NULL';
++close(OUT);
++
++
++
++print "/*\n";
++$date = localtime;
++print " * This file produced from $0 on $date\n";
++print ' * $Id: encodings.pl,v 1.10.4.1 2008/03/10 10:07:22 freddy77 Exp $', "\n";
++print " */\n";
++
++%charsets = ();
++$filename = "${srcdir}character_sets.h";
++open(IN, "<$filename") or die qq($basename: could not open "$filename"\n);
++while(<IN>)
++{
++	if (/{.*"(.*)".*,\s*([0-9]+)\s*,\s*([0-9]+)\s*}/)
++	{
++		next if !$1;
++		$charsets{$1} = [$2,$3];
++	}
++}
++close(IN);
++
++# from all iconv to canonic
++%alternates = ();
++$filename = "${srcdir}alternative_character_sets.h";
++open(IN, "<$filename") or die qq($basename: could not open "$filename"\n);
++while(<IN>)
++{
++	if (/{\s*"(.+)"\s*,\s*"(.+)"\s*}/)
++	{
++		$alternates{$2} = $1;
++	}
++}
++close(IN);
++
++# from sybase to canonic
++%sybase = ();
++$filename = "${srcdir}sybase_character_sets.h";
++open(IN, "<$filename") or die qq($basename: could not open "$filename"\n);
++while(<IN>)
++{
++	if (/{\s*"(.+)"\s*,\s*"(.+)"\s*}/)
++	{
++		$sybase{$2} = $alternates{$1};
++	}
++}
++close(IN);
++
++# give an index to all canonic
++%index = ();
++$i = 0;
++$index{"ISO-8859-1"} = $i++;
++$index{"UTF-8"} = $i++;
++$index{"UCS-2LE"} = $i++;
++$index{"UCS-2BE"} = $i++;
++foreach $n (sort grep(!/^(ISO-8859-1|UTF-8|UCS-2LE|UCS-2BE)$/,keys %charsets))
++{
++	$index{$n} = $i;
++	$i++ if $n;
++}
++
++# output all charset
++print "static const TDS_ENCODING canonic_charsets[] = {\n";
++$i=0;
++foreach $n (sort { $index{$a} <=> $index{$b} } keys %charsets)
++{
++	my ($a, $b) = @{$charsets{$n}};
++	my $index = ($n)? (sprintf "/* %3d */", $i) : "\t";
++	printf "\t{%20s,\t$a, $b},\t%s\n", qq/"$n"/, $index;
++	$i++ if $n;
++}
++print "\t{\"\",\t0, 0}\n";
++print "};\n\n";
++
++# output enumerated charset indexes
++print "enum {\n";
++$i=0;
++foreach $n (sort { $index{$a} <=> $index{$b} } keys %charsets)
++{
++	$n =~ tr/-a-z/_A-Z/;
++	printf "\t%30s =%4d,\n", "TDS_CHARSET_$n", $i++;
++}
++printf "\t%30s =%4d\n};\n\n", "TDS_NUM_CHARSETS", $i++;
++
++# output all alias
++print "static const CHARACTER_SET_ALIAS iconv_aliases[] = {\n";
++foreach $n (sort keys %alternates)
++{
++	$a = $index{$alternates{$n}};
++	next if ("$a" eq "");
++	printf "\t{%25s,  %3d },\n", qq/"$n"/, $a;
++}
++print "\t{NULL,\t0}\n";
++print "};\n\n";
++
++# output all sybase
++print "static const CHARACTER_SET_ALIAS sybase_aliases[] = {\n";
++foreach $n (sort keys %sybase)
++{
++	$a = $index{$sybase{$n}};
++	next if ("$a" eq "");
++	printf "\t{%20s, %3d },\n", qq/"$n"/, $a;
++}
++print "\t{NULL,\t0}\n";
++print "};\n\n";
++
++exit 0;
++__DATA__
++#http://www.sybase.com/detail/1,6904,1016214,00.html
++						
++ascii_8
++big5
++big5hk
++cp1026
++cp1047
++cp1140
++cp1141
++cp1142
++cp1143
++cp1144
++cp1145
++cp1146
++cp1147
++cp1148
++cp1149
++cp1250
++cp1251
++cp1252
++cp1253
++cp1254
++cp1255
++cp1256
++cp1257
++cp1258
++cp273
++cp277
++cp278
++cp280
++cp284
++cp285
++cp297
++cp420
++cp424
++cp437
++cp500
++cp5026
++cp5026yen
++cp5035
++cp5035yen
++cp737
++cp775
++cp850
++cp852
++cp855
++cp857
++cp858
++cp860
++cp861
++cp862
++cp863
++cp864
++cp865
++cp866
++cp869
++cp870
++cp871
++cp874
++cp874ibm
++cp875
++cp921
++cp923
++cp930
++cp930yen
++cp932
++cp932ms
++cp933
++cp935
++cp936
++cp937
++cp939
++cp939yen
++cp949
++cp950
++cp954
++deckanji
++euccns
++eucgb
++eucjis
++eucksc
++greek8
++iso10
++iso13
++iso14
++iso15
++iso646
++iso88592
++iso88595
++iso88596
++iso88597
++iso88598
++iso88599
++iso_1
++koi8
++mac
++mac_cyr
++mac_ee
++macgrk2
++macgreek
++macthai
++macturk
++roman8
++roman9
++rcsu
++sjis
++tis620
++turkish8
++utf8
+diff --git b/src/tds/num_limits.pl a/src/tds/num_limits.pl
+new file mode 100755
+index 0000000..a26ff4b
+--- /dev/null
++++ a/src/tds/num_limits.pl
+@@ -0,0 +1,95 @@
++#!/usr/bin/perl
++
++#
++# $Id: num_limits.pl,v 1.2 2005/08/02 12:09:57 freddy77 Exp $
++# Compute limits table to check numeric typs
++#
++
++use strict;
++
++# This function convert a number given in textual form ("1000") to a
++# packet form (binary packet in groups of selected bit)
++sub to_pack($$)
++{
++	my ($num, $bit) = @_;
++	my @digits;
++
++	my ($carry, $n, $i, $pos, $bin);
++	my $out = "\x00" x 32;
++	$pos = 0;
++	$bin = '';
++	while($num ne '') {
++		@digits = split('', $num);
++		$carry = 0;
++		for $i (0..$#digits) {
++			$n = $carry * 10 + $digits[$i];
++			$digits[$i] = int($n / 2);
++			$carry = $n & 1;
++		}
++		$bin = "$carry$bin";
++		vec($out, $pos++, 1) = $carry;
++		shift @digits if ($digits[0] == 0);
++		$num = join('', @digits);
++	}
++	return reverse unpack($bit == 32 ? 'V' x 8 : 'v' x 16, $out);
++}
++
++# Print a tables for given bits
++# This function produce two arrays
++#  one (limits) store not 0 packet numbers
++#  the other (limit_indexes) store indexed in first array
++sub print_all()
++{
++	my ($bit) = @_;
++	my @limits = ();
++	my @indexes = ();
++	my $i;
++
++	$indexes[0] = 0;
++	# compute packet numbers and indexes
++	# we use 1000... number to reduce number length (lower packet are 
++	# zero for big numbers)
++	for $i (0..77) {
++		my @packet = &to_pack("1".('0'x$i), $bit);
++		$indexes[$i] = $#limits + 1;
++		while($packet[0] == 0) {
++			shift @packet;
++		}
++		while($packet[0] != 0) {
++			push @limits, shift @packet;
++		}
++		$indexes[$i+1] = $#limits + 1;
++	}
++
++	# fix indexes to use signed char numbers instead of int
++	my $adjust = $bit == 32 ? 4 : 6;
++	printf("#define LIMIT_INDEXES_ADJUST %d\n\n", $adjust);
++	for $i (0..78) {
++		my $idx = $indexes[$i];
++		$idx = $idx - $adjust * $i;
++		die ('error compacting indexes') if ($idx < -128 || $idx > 127);
++		$indexes[$i] = $idx;
++	}
++
++	# print all
++	print "static const signed char limit_indexes[79]= {\n";
++	for $i (0..78) {
++		printf("\t%d,\t/* %2d */\n", $indexes[$i], $i);
++	}
++	print "};\n\n";
++
++	print "static const TDS_WORD limits[]= {\n";
++	my $format = sprintf("\t0x%%0%dxu,\t/* %%3d */\n", $bit / 4);
++	for $i (0..$#limits) {
++		printf($format, $limits[$i], $i);
++		die ('limit if zero ??') if ($limits[$i] == 0);
++	}
++	print "};\n";
++}
++
++print "#ifndef HAVE_INT64\n";
++&print_all(16);
++print "#else\n";
++&print_all(32);
++print "#endif\n";
++
+diff --git b/src/tds/tds_willconvert.pl a/src/tds/tds_willconvert.pl
+new file mode 100755
+index 0000000..a695b51
+--- /dev/null
++++ a/src/tds/tds_willconvert.pl
+@@ -0,0 +1,80 @@
++#!perl
++
++$indent = "\t ";
++printf qq(/*** %-67s ***/\n), "Please do not edit this file!";
++printf qq(/*** %-67s ***/\n), "It was generated with 'perl tds_willconvert.pl > tds_willconvert.h'";
++printf qq(/*** %-67s ***/\n), "It is much easier to edit the __DATA__ table than this file.  ";
++printf qq(/*** %-67s ***/\n), " ";
++printf qq(/*** %67s ***/\n\n), "Thank you.";
++
++while(<DATA>) {
++	next if /^\s+To\s+$/;
++	next if /^From/;
++	if( /^\s+VARCHAR CHAR/ ) {
++		@to = split;
++		next;
++	}
++	last if /^BOUNDARY/;
++
++	@yn = split;
++	$from = shift @yn;
++	$i = 0;
++	foreach $to (@to) {
++		last if $to =~ /^BOUNDARY/;
++
++		$yn = $yn[$i];	# default
++		$yn = 1 if $yn[$i] eq 'T';
++		$yn = 0 if $yn[$i] eq 'F';
++		$yn = 0 if $yn[$i] eq 't';	# means it should be true, but isn't so far.
++
++		printf "$indent %-30.30s, %s", "{ SYB${from}, SYB${to}", "$yn }\n"; 
++
++		$i++;
++		$indent = "\t,";
++	}
++}
++
++__DATA__
++          To
++From
++          VARCHAR CHAR TEXT BINARY VARBINARY IMAGE INT1 INT2 INT4 INT8 FLT8 REAL NUMERIC DECIMAL BIT MONEY MONEY4 DATETIME DATETIME4 BOUNDARY SENSITIVITY
++VARCHAR     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T
++CHAR        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T
++TEXT        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T
++BINARY      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++VARBINARY   T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++IMAGE       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++INT1        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++INT2        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++INT4        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++INT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++FLT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++REAL        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++NUMERIC     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++DECIMAL     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++BIT         T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++MONEY       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++MONEY4      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
++DATETIME    T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F
++DATETIME4   T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F
++BOUNDARY    T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     T        F
++SENSITIVITY T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     F        T
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
++
+diff --git b/src/tds/unittests/.cvsignore a/src/tds/unittests/.cvsignore
+new file mode 100644
+index 0000000..eb6aa08
+--- /dev/null
++++ a/src/tds/unittests/.cvsignore
+@@ -0,0 +1,22 @@
++Makefile
++Makefile.in
++.libs
++.deps
++t0001
++t0002
++t0003
++t0004
++t0005
++t0006
++t0007
++t0008
++tdsdump.out
++dynamic1
++convert
++dataread
++flags
++utf8_1
++utf8_2
++utf8_3
++numeric
++iconv_fread
+diff --git b/src/tds/unittests/flags.c a/src/tds/unittests/flags.c
+new file mode 100644
+index 0000000..5c5f28b
+--- /dev/null
++++ a/src/tds/unittests/flags.c
+@@ -0,0 +1,168 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#include "common.h"
++
++#include <tdsconvert.h>
++
++static char software_version[] = "$Id: flags.c,v 1.14 2005/04/14 11:35:47 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static TDSLOGIN *login;
++static TDSSOCKET *tds;
++
++static void
++fatal_error(const char *msg)
++{
++	fprintf(stderr, "%s\n", msg);
++	exit(1);
++}
++
++static void
++check_flags(TDSCOLUMN * curcol, int n, const char *possible_results)
++{
++	char msg[256];
++	char flags[256];
++	int l;
++	char *all_res = strdup(possible_results);
++	char *res;
++	int correct = 0;
++
++	flags[0] = 0;
++	if (curcol->column_nullable)
++		strcat(flags, "nullable ");
++	if (curcol->column_writeable)
++		strcat(flags, "writable ");
++	if (curcol->column_identity)
++		strcat(flags, "identity ");
++	if (curcol->column_key)
++		strcat(flags, "key ");
++	if (curcol->column_hidden)
++		strcat(flags, "hidden ");
++	l = strlen(flags);
++	if (l)
++		flags[l - 1] = 0;
++
++	/* one result is valid ?? */
++	for (res = strtok(all_res, "-"); res; res = strtok(NULL, "-"))
++		if (strcmp(flags, res) == 0)
++			correct = 1;
++
++	if (!correct) {
++		sprintf(msg, "flags:%s\nexpected: %s\nwrong column %d flags", flags, possible_results, n + 1);
++		fatal_error(msg);
++	}
++}
++
++static void
++test_begin(const char *cmd)
++{
++	TDS_INT result_type;
++
++	fprintf(stdout, "%s: Testing query\n", cmd);
++	if (tds_submit_query(tds, cmd) != TDS_SUCCEED)
++		fatal_error("tds_submit_query() failed");
++
++	if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_SUCCEED)
++		fatal_error("tds_process_tokens() failed");
++
++	if (result_type != TDS_ROWFMT_RESULT)
++		fatal_error("expected row fmt() failed");
++
++	/* test columns results */
++	if (tds->current_results != tds->res_info)
++		fatal_error("wrong current_results");
++}
++
++static void
++test_end(void)
++{
++	TDS_INT result_type;
++	int done_flags;
++
++	if (tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS) != TDS_SUCCEED)
++		fatal_error("tds_process_tokens() failed");
++
++	if (result_type != TDS_DONE_RESULT)
++		fatal_error("expected done failed");
++
++	if (done_flags & TDS_DONE_ERROR)
++		fatal_error("query failed");
++
++	if (tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS) != TDS_NO_MORE_RESULTS)
++		fatal_error("tds_process_tokens() failed");
++}
++
++int
++main(int argc, char **argv)
++{
++	TDSRESULTINFO *info;
++	char mymsg[256];
++
++	fprintf(stdout, "%s: Testing flags from server\n", __FILE__);
++	if (try_tds_login(&login, &tds, __FILE__, 0) != TDS_SUCCEED) {
++		fprintf(stderr, "try_tds_login() failed\n");
++		return 1;
++	}
++
++	if (run_query(tds, "create table #tmp1 (i numeric(10,0) identity primary key, b varchar(20) null, c int not null)") !=
++	    TDS_SUCCEED)
++		fatal_error("creating table error");
++
++	/* TDS 4.2 without FOR BROWSE clause seem to forget flags... */
++	if (!IS_TDS42(tds)) {
++		/* check select of all fields */
++		test_begin("select * from #tmp1");
++		info = tds->current_results;
++
++		if (info->num_cols != 3) {
++			sprintf(mymsg,"wrong number of columns returned expected 3 got %d", info->num_cols);
++			fatal_error(mymsg);
++		}
++
++		check_flags(info->columns[0], 0, "identity");
++		check_flags(info->columns[1], 1, "nullable writable");
++		check_flags(info->columns[2], 2, "writable");
++
++		test_end();
++	}
++
++
++	/* check select of 2 field */
++	test_begin("select c, b from #tmp1 for browse");
++	info = tds->current_results;
++
++	if (info->num_cols != 3)
++		fatal_error("wrong number of columns returned");
++
++	check_flags(info->columns[0], 0, "writable");
++
++	if (!IS_TDS42(tds)) {
++		check_flags(info->columns[1], 1, "nullable writable");
++	} else {
++		check_flags(info->columns[1], 1, "writable-nullable writable");
++	}
++	/* TDS5 return not identity information altough documented.. */
++	check_flags(info->columns[2], 2, "writable identity key hidden-writable key hidden");
++
++	test_end();
++
++	try_tds_logout(login, tds, 0);
++	return 0;
++}
+diff --git b/vms/.cvsignore a/vms/.cvsignore
+new file mode 100644
+index 0000000..282522d
+--- /dev/null
++++ a/vms/.cvsignore
+@@ -0,0 +1,2 @@
++Makefile
++Makefile.in
+diff --git b/vms/Makefile.am a/vms/Makefile.am
+new file mode 100644
+index 0000000..fb78fcd
+--- /dev/null
++++ a/vms/Makefile.am
+@@ -0,0 +1,4 @@
++EXTRA_DIST = config_h.vms configure.com descrip_mms.template \
++	getpass.c libodbc.opt odbc_driver_axp.opt README.vms
++
++clean:
+diff --git b/win32/.cvsignore a/win32/.cvsignore
+new file mode 100644
+index 0000000..cf35acd
+--- /dev/null
++++ a/win32/.cvsignore
+@@ -0,0 +1,5 @@
++Makefile
++Makefile.in
++version.rc
++freetds.nsh
++setup.res
+diff --git b/win32/build_dsw.pl a/win32/build_dsw.pl
+new file mode 100644
+index 0000000..a52e303
+--- /dev/null
++++ a/win32/build_dsw.pl
+@@ -0,0 +1,217 @@
++#!/usr/bin/env perl
++
++use strict;
++
++my ($template, $dsp, $name);
++
++mkdir('vc6');
++
++$template = q|# Microsoft Developer Studio Project File - Name="t0002" - Package Owner=<4>
++# Microsoft Developer Studio Generated Build File, Format Version 6.00
++# ** DO NOT EDIT **
++
++# TARGTYPE "Win32 (x86) Console Application" 0x0103
++
++CFG=t0002 - Win32 Debug
++!MESSAGE This is not a valid makefile. To build this project using NMAKE,
++!MESSAGE use the Export Makefile command and run
++!MESSAGE 
++!MESSAGE NMAKE /f "t0002.mak".
++!MESSAGE 
++!MESSAGE You can specify a configuration when running NMAKE
++!MESSAGE by defining the macro CFG on the command line. For example:
++!MESSAGE 
++!MESSAGE NMAKE /f "t0002.mak" CFG="t0002 - Win32 Debug"
++!MESSAGE 
++!MESSAGE Possible choices for configuration are:
++!MESSAGE 
++!MESSAGE "t0002 - Win32 Release" (based on "Win32 (x86) Console Application")
++!MESSAGE "t0002 - Win32 Debug" (based on "Win32 (x86) Console Application")
++!MESSAGE 
++
++# Begin Project
++# PROP AllowPerConfigDependencies 0
++# PROP Scc_ProjName ""
++# PROP Scc_LocalPath ""
++CPP=cl.exe
++RSC=rc.exe
++
++!IF  "$(CFG)" == "t0002 - Win32 Release"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 0
++# PROP BASE Output_Dir "..\\Release"
++# PROP BASE Intermediate_Dir "..\\Release"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 0
++# PROP Output_Dir "..\\Release"
++# PROP Intermediate_Dir "..\\Release"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
++# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /YX /FD /c
++# ADD BASE RSC /l 0x410 /d "NDEBUG"
++# ADD RSC /l 0x410 /d "NDEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LINK32=link.exe
++# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386
++# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ntwdblib.lib /nologo /subsystem:console /machine:I386
++
++!ELSEIF  "$(CFG)" == "t0002 - Win32 Debug"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 1
++# PROP BASE Output_Dir "..\\Debug"
++# PROP BASE Intermediate_Dir "..\\Debug"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 1
++# PROP Output_Dir "..\\Debug"
++# PROP Intermediate_Dir "..\\Debug"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
++# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /YX /FD /GZ  /c
++# ADD BASE RSC /l 0x410 /d "_DEBUG"
++# ADD RSC /l 0x410 /d "_DEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LINK32=link.exe
++# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
++# ADD LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib  kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ntwdblib.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept
++
++!ENDIF 
++
++# Begin Target
++
++# Name "t0002 - Win32 Release"
++# Name "t0002 - Win32 Debug"
++# Begin Group "Source Files"
++
++# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
++# Begin Source File
++
++SOURCE=..\common.c
++# End Source File
++# Begin Source File
++
++SOURCE=..\t0002.c
++# End Source File
++# End Group
++# Begin Group "Header Files"
++
++# PROP Default_Filter "h;hpp;hxx;hm;inl"
++# Begin Source File
++
++SOURCE=..\common.h
++# End Source File
++# End Group
++# Begin Group "Resource Files"
++
++# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe"
++# End Group
++# End Target
++# End Project
++|;
++
++my ($dsw, $projects, $fn_out);
++my ($executables, $link_cmds, $tests);
++
++$fn_out = shift @ARGV;
++
++$projects = '';
++foreach $name (@ARGV) {
++	$name =~ s/\.exe$//i;
++	$projects .= qq|###############################################################################
++
++Project: "$name"=.\\vc6\\$name.dsp - Package Owner=<4>
++
++Package=<5>
++{{{
++}}}
++
++Package=<4>
++{{{
++}}}
++
++|;
++	$dsp = $template;
++	$dsp =~ s/t0002/$name/g;
++	$dsp =~ s/\n/\r\n/sg;
++	open(FILE, ">", "vc6/$name.dsp") or die("creating file");
++	print FILE $dsp;
++	close(FILE);
++
++	$executables .= qq| \\\n\t"\$(OUTDIR)\\$name.exe"|;
++	$link_cmds .= qq|"\$(OUTDIR)\\$name.exe" : "\$(OUTDIR)" "\$(INTDIR)\\common.obj" "\$(INTDIR)\\$name.obj"
++	\$(LINK32) \$(LINK32_FLAGS) "\$(INTDIR)\\common.obj" "\$(INTDIR)\\$name.obj" /pdb:"\$(OUTDIR)\\$name.pdb" /out:"\$(OUTDIR)\\$name.exe"
++
++|;
++	$tests .= qq|\n\t"\$(OUTDIR)\\$name.exe"|;
++}
++
++$template = qq|Microsoft Developer Studio Workspace File, Format Version 6.00
++# WARNING: DO NOT EDIT OR DELETE THIS WORKSPACE FILE!
++
++$projects
++###############################################################################
++
++Global:
++
++Package=<5>
++{{{
++}}}
++
++Package=<3>
++{{{
++}}}
++
++###############################################################################
++
++|;
++
++open(FILE, ">", $fn_out) or die("creating file");
++$template =~ s/\n/\r\n/sg;
++print FILE $template;
++close(FILE);
++
++$template = qq|!IF "\$(OS)" == "Windows_NT"
++NULL=
++!ELSE
++NULL=nul
++!ENDIF
++
++OUTDIR=.\\Release
++INTDIR=.\\Release
++
++ALL : $executables
++
++CLEAN :
++	-\@erase "\$(INTDIR)\*.obj"
++	-\@erase "\$(OUTDIR)\*.exe"
++
++"\$(OUTDIR)" :
++	if not exist "\$(OUTDIR)/\$(NULL)" mkdir "\$(OUTDIR)"
++
++CPP=cl.exe
++CPP_PROJ=/nologo /MD /W3 /O2 /Ob2 /I "./" /D WIN32 /D NDEBUG /D _CONSOLE /D _MBCS /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /Fo"\$(INTDIR)\\\\" /Fd"\$(INTDIR)\\\\" /FD /c 
++
++.c{\$(INTDIR)}.obj::
++	\$(CPP) \$(CPP_PROJ) \$<
++
++LINK32=link.exe
++LINK32_FLAGS=kernel32.lib user32.lib gdi32.lib advapi32.lib ws2_32.lib odbc32.lib ntwdblib.lib /nologo /subsystem:console /incremental:no /machine:I386
++
++$link_cmds
++
++CHECK :	$tests
++|;
++
++$fn_out =~ s/\.dsw$/.mak/i;
++
++open(FILE, ">", $fn_out) or die("creating file");
++$template =~ s/\n/\r\n/sg;
++print FILE $template;
++close(FILE);
+diff --git b/win32/dev-cpp/.cvsignore a/win32/dev-cpp/.cvsignore
+new file mode 100644
+index 0000000..282522d
+--- /dev/null
++++ a/win32/dev-cpp/.cvsignore
+@@ -0,0 +1,2 @@
++Makefile
++Makefile.in
+diff --git b/win32/msvc6/.cvsignore a/win32/msvc6/.cvsignore
+new file mode 100644
+index 0000000..282522d
+--- /dev/null
++++ a/win32/msvc6/.cvsignore
+@@ -0,0 +1,2 @@
++Makefile
++Makefile.in
+
+======== climb down out of branch
+commit 1a17baae01d07688ee80e21ac0a691acb45e9573
+Author: jklowden <jklowden>
+Date:   Wed May 7 22:57:52 2008 +0000
+
+    RELEASE 0.82
+
+diff --git b/ChangeLog a/ChangeLog
+index 5781cc1..6441953 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Wed May  7 18:56:39 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* configure.ac	RELEASE 0.82
+-
+ Mon May  5 23:19:57 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cstypes.h src/ctlib/ct.c
+ 	- applied CS_BIGINT patch from Stephen Degler
+@@ -145,4 +142,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.35 2008/05/07 22:57:52 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.34 2008/05/06 03:23:44 jklowden Exp $
+diff --git b/configure.ac a/configure.ac
+index f7c0b99..dc0ecbc 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.11 2008/05/07 22:57:52 jklowden Exp $
++dnl $Id: configure.ac,v 1.29.2.10 2008/03/23 21:04:31 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.82)
++AC_INIT(FreeTDS, 0.82RC5)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.11 $)
++AC_REVISION($Revision: 1.29.2.10 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+
+commit e34de1e55c90d279da09b8495a80e1958d26a5e4
+Author: jklowden <jklowden>
+Date:   Tue May 6 03:23:44 2008 +0000
+
+    applied CS_BIGINT patch from Stephen Degler
+
+diff --git b/ChangeLog a/ChangeLog
+index 6441953..92307e0 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Mon May  5 23:19:57 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* include/cstypes.h src/ctlib/ct.c
+-	- applied CS_BIGINT patch from Stephen Degler
+-	
+ Wed Apr 30 09:52:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c:
+ 	- return proper diagnostic for truncation on SQLGetData
+@@ -142,4 +138,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.34 2008/05/06 03:23:44 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.33 2008/04/30 14:59:32 freddy77 Exp $
+diff --git b/include/cstypes.h a/include/cstypes.h
+index a224c4f..aa494b1 100644
+--- b/include/cstypes.h
++++ a/include/cstypes.h
+@@ -30,37 +30,36 @@ extern "C"
+ #endif
+ #endif
+ 
+-static const char rcsid_cstypes_h[] = "$Id: cstypes.h,v 1.6.4.1 2008/05/06 03:23:45 jklowden Exp $";
++static const char rcsid_cstypes_h[] = "$Id: cstypes.h,v 1.6 2005/09/21 14:46:00 freddy77 Exp $";
+ static const void *const no_unused_cstypes_h_warn[] = { rcsid_cstypes_h, no_unused_cstypes_h_warn };
+ 
+-typedef tds_sysdep_int32_type 		CS_INT;
+-typedef unsigned tds_sysdep_int32_type 	CS_UINT;
+-typedef tds_sysdep_int64_type 		CS_BIGINT;
+-typedef unsigned tds_sysdep_int64_type 	CS_UBIGINT;
+-typedef tds_sysdep_int16_type 		CS_SMALLINT;
+-typedef unsigned tds_sysdep_int16_type 	CS_USMALLINT;
+-typedef unsigned char 			CS_TINYINT;
+-typedef char 				CS_CHAR;
+-typedef unsigned char 			CS_BYTE;
+-typedef tds_sysdep_real32_type 		CS_REAL;
+-typedef tds_sysdep_real64_type 		CS_FLOAT;
+-typedef tds_sysdep_int32_type 		CS_BOOL;
+-typedef void 				CS_VOID;
+-typedef unsigned char 			CS_IMAGE;
+-typedef unsigned char 			CS_TEXT;
+-typedef unsigned char 			CS_LONGBINARY;
+-typedef unsigned char 			CS_LONGCHAR;
+-typedef long 				CS_LONG;
+-typedef unsigned char 			CS_BINARY;
+-typedef unsigned tds_sysdep_int16_type 	CS_USHORT;
+-typedef unsigned char 			CS_BIT;
+ 
++typedef tds_sysdep_int32_type CS_INT;
++typedef unsigned tds_sysdep_int32_type CS_UINT;
++typedef tds_sysdep_int16_type CS_SMALLINT;
++typedef unsigned char CS_TINYINT;
++typedef char CS_CHAR;
++typedef unsigned char CS_BYTE;
++typedef tds_sysdep_real32_type CS_REAL;
++typedef tds_sysdep_real64_type CS_FLOAT;
++typedef tds_sysdep_int32_type CS_BOOL;
++typedef void CS_VOID;
++typedef unsigned char CS_IMAGE;
++typedef unsigned char CS_TEXT;
++typedef unsigned char CS_LONGBINARY;
++typedef unsigned char CS_LONGCHAR;
++typedef long CS_LONG;
++typedef unsigned char CS_BINARY;
++typedef unsigned tds_sysdep_int16_type CS_USHORT;
++typedef unsigned char CS_BIT;
+ typedef CS_INT CS_RETCODE;
+ 
++
++
+ #define CS_MAX_NAME 132
+ #define CS_MAX_SCALE 77
+ #define CS_MAX_PREC 77		/* used by php */
+-#define CS_MAX_NUMLEN 33	/* used by roguewave */
++#define CS_MAX_NUMLEN 33		/* used by roguewave */
+ #define CS_MAX_MSG 1024
+ #define CS_SQLSTATE_SIZE 8
+ #define CS_OBJ_NAME 400
+@@ -139,10 +138,6 @@ typedef struct _cs_money4
+ 	CS_INT mny4;
+ } CS_MONEY4;
+ 
+-typedef CS_INT CS_DATE;
+-
+-typedef CS_INT CS_TIME;
+-
+ typedef struct _cs_datetime
+ {
+ 	CS_INT dtdays;
+diff --git b/src/ctlib/ct.c a/src/ctlib/ct.c
+index 1a9a035..3e4db22 100644
+--- b/src/ctlib/ct.c
++++ a/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.177.2.1 2008/05/06 03:23:45 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.177 2007/12/21 15:23:24 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -1898,7 +1898,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_CHAR_TYPE;
+ 		break;
+ 	case SYBINT8:
+-		return CS_BIGINT_TYPE;
++		return CS_LONG_TYPE;
+ 		break;
+ 	case SYBINT4:
+ 		return CS_INT_TYPE;
+@@ -1912,7 +1912,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 	case SYBINTN:
+ 		switch (size) {
+ 		case 8:
+-			return CS_BIGINT_TYPE;
++			return CS_LONG_TYPE;
+ 		case 4:
+ 			return CS_INT_TYPE;
+ 		case 2:
+@@ -2015,7 +2015,6 @@ _ct_get_server_type(int datatype)
+ 		return SYBCHAR;
+ 		break;
+ 	case CS_LONG_TYPE:
+-	case CS_BIGINT_TYPE:
+ 		return SYBINT8;
+ 		break;
+ 	case CS_INT_TYPE:
+
+commit d07284c21104a86ff53463fe541f6d8374e7f708
+Author: freddy77 <freddy77>
+Date:   Wed Apr 30 14:59:32 2008 +0000
+
+    return proper diagnostic for truncation on SQLGetData
+
+diff --git b/ChangeLog a/ChangeLog
+index 92307e0..002b6dd 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Wed Apr 30 09:52:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c:
+-	- return proper diagnostic for truncation on SQLGetData
+-
+ Sun Mar 23 17:03:48 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac RC5
+ 
+@@ -138,4 +134,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.33 2008/04/30 14:59:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.32 2008/03/23 21:04:31 jklowden Exp $
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 4e85254..ffbabe7 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.10 2008/04/30 14:59:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.9 2008/03/11 08:25:30 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4651,10 +4651,9 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ 				++colinfo->column_text_sqlgetdatapos;
+ 			/* not all readed ?? */
+-			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {
+-				odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
++			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size)
++				/* TODO add diagnostic */
+ 				ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+-			}
+ 		} else {
+ 			colinfo->column_text_sqlgetdatapos = colinfo->column_size;
+ 		}
+
+commit 0e1bfcecb4f65c351c329b2701cd75617c7f576f
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 21:04:31 2008 +0000
+
+    RC5
+
+diff --git b/ChangeLog a/ChangeLog
+index 002b6dd..83fcda2 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Sun Mar 23 17:03:48 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* configure.ac RC5
+-
+ Sun Mar 23 17:01:13 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml clarified localization
+ 
+@@ -134,4 +131,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.32 2008/03/23 21:04:31 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.31 2008/03/23 21:02:51 jklowden Exp $
+diff --git b/configure.ac a/configure.ac
+index dc0ecbc..eab617c 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.10 2008/03/23 21:04:31 jklowden Exp $
++dnl $Id: configure.ac,v 1.29.2.9 2008/03/23 17:29:40 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.82RC5)
++AC_INIT(FreeTDS, 0.82RC4)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.10 $)
++AC_REVISION($Revision: 1.29.2.9 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+
+commit 83cb97db3955653def79b6813c3fcfe239c4d76a
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 21:02:51 2008 +0000
+
+    clarified localization
+
+diff --git b/ChangeLog a/ChangeLog
+index 83fcda2..b4885f8 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Sun Mar 23 17:01:13 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* doc/userguide.sgml clarified localization
+-
+ Sun Mar 23 13:26:57 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac doc/Makefile.am
+ 	- applied ML patches from Johnny C. Lam for callout locations
+@@ -131,4 +128,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.31 2008/03/23 21:02:51 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.30 2008/03/23 17:41:36 jklowden Exp $
+diff --git b/doc/userguide.sgml a/doc/userguide.sgml
+index e2e711f..2a09e0f 100644
+--- b/doc/userguide.sgml
++++ a/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/03/23 21:02:52 $</date>
+-		<releaseinfo>$Revision: 1.110.2.2 $</releaseinfo>
++		<date>$Date: 2008/01/10 20:58:43 $</date>
++		<releaseinfo>$Revision: 1.110.2.1 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.110.2.2 $</>
+-<member>$Date: 2008/03/23 21:02:52 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.110.2.2 2008/03/23 21:02:52 jklowden Exp $.</>
++<member>$Revision: 1.110.2.1 $</>
++<member>$Date: 2008/01/10 20:58:43 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.110.2.1 2008/01/10 20:58:43 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/03/23 21:02:52 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/01/10 20:58:43 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -928,7 +928,7 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	<row>
+ 	<entry id="clientcharset">client charset</entry>
+ 	<entry>any valid iconv character set</entry>
+-	<entry>ISO-8859-1<footnote><para>Valid for ISO 8859-1 character set.  See <link linkend="Localization">Localization and <acronym>TDS</> 7.0</link> for more information.  </para></footnote></entry>
++	<entry>ISO-8859-1<footnote><para>Valid for ISO 8859-1 character set.  See <link linkend="Nonwestern"><acronym>TDS</> 7.0 for Nonwestern Languages</link> for more information.  </para></footnote></entry>
+ 	<entry>Makes <productname>FreeTDS</productname> use iconv to convert to and from the specified character set from UCS-2 in <acronym>TDS</> 7.0/8.0.
+ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need to match the server's charset to insert any characters the server supports.</entry>
+ 	</row>
+@@ -1029,7 +1029,7 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ 	</tgroup>
+ </table>
+ 
+-	<para>For more about the wonderful world of <productname>FreeTDS</productname> logs, see <link linkend="logging">Logging</link>.</para>
++	<para>For more about the wonder world of <productname>FreeTDS</productname>logs, see <link linkend="logging">Logging</link>.</para>
+ 			</sect3>
+ 
+ 			<sect3><title>Deprecated options</>	
+@@ -1236,7 +1236,7 @@ When you're done, you should see something very like this:
+ 
+ 			<para>If you specify <literal><replaceable>dataserver</replaceable>\<replaceable>instance</replaceable></literal>
+ 			as dataserver during login, <productname>FreeTDS</productname> will attempt to connect to specified instance.
+-			Only Microsoft SQL Server instances are supported.  (This server feature was introduced with SQL Server 2000.)
++			Only Microsoft SQL Server instances are supported.  (This server feature was introduced with SQL Server 2000).
+ 			</para>
+ 
+ 			<para>Note that other <filename>freetds.conf</> properties still apply.
+@@ -1249,8 +1249,8 @@ When you're done, you should see something very like this:
+ 			
+ 			<sect2 id="tsql"><title><application>tsql</application></title>
+ 
+-			<para>The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  </para>
+-			<para><command>tsql</> can either use or bypass the configuration files.  By trying both options, you can usually determine if it's your dataserver that's not responding, or your configuration files that are messed up. </para> 
++			<para>
++The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  <command>tsql</> can either use or bypass the configuration files, allowing you to see if it's your dataserver that's not responding, or your configuration files that are messed up. </para> 
+ 
+ 			<bridgehead renderas='sect3'>Using <filename>freetds.conf</>:</bridgehead>
+ 			<para>
+@@ -1263,6 +1263,18 @@ When you're done, you should see something very like this:
+ </cmdsynopsis>
+ 			</para>
+ 
++			<bridgehead renderas='sect3'>Bypassing <filename>freetds.conf</>:</bridgehead>
++			<para>
++<cmdsynopsis label="Syntax synopsis for tsql">
++  <command>tsql</command> 
++	<arg choice='req'>-H <replaceable>hostname</replaceable></arg>
++	<arg choice='req'>-p <replaceable>port</replaceable></arg>
++	<arg choice='req'>-U <replaceable>username</replaceable></arg>
++	<arg choice='opt'>-P<replaceable>password</replaceable></arg>
++	<arg choice='opt'>-C</arg>
++</cmdsynopsis>
++			</para>
++
+ <example id="e.g.tsqlFail">
+ <title>Failing to connect with tsql</title>
+ <screen>
+@@ -1288,20 +1300,6 @@ There was a problem connecting to the server
+ </screen>
+ </example>
+ 
+-			<bridgehead renderas='sect3'>Bypassing <filename>freetds.conf</>:</bridgehead>
+-			<para>
+-<cmdsynopsis label="Syntax synopsis for tsql">
+-  <command>tsql</command> 
+-	<arg choice='req'>-H <replaceable>hostname</replaceable></arg>
+-	<arg choice='req'>-p <replaceable>port</replaceable></arg>
+-	<arg choice='req'>-U <replaceable>username</replaceable></arg>
+-	<arg choice='opt'>-P<replaceable>password</replaceable></arg>
+-	<arg choice='opt'>-C</arg>
+-</cmdsynopsis>
+-
+-			Keep in mind that the TDS protocol version normally comes from <filename>freetds.conf</>.  When using <command>tsql</> this way, the library uses the compiled-in default (set by the <filename>configure</> script).  If that's not what you want, override it using the <envar>TDSVER</> environment variable.  
+-			</para>
+-
+ <example id="e.g.tsqlhostname">
+ <title>Connect with <command>tsql</> using a hostname and port number</title>
+ <screen>
+@@ -1493,7 +1491,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ </tgroup>
+ </table>
+ 
+-<table id="tab.Connection.attributes.freetds.conf"><title>Connection attributes that may appear in <filename>odbc.ini</></title>
++<table id="tab.Connection.attributes.freetds.conf"><title>Connection attributes that may appear in <filename>freetds.conf</></title>
+ <tgroup cols="4">
+ <thead>
+ 	<row>
+@@ -1748,7 +1746,7 @@ This chapter details some advanced configurations that need expanded explanation
+ 			<para>
+ Several version of Microsoft SQL server have a bug that affects big endian clients.  This includes 7.0 GA and 7.0 SP1.  Furthermore, <acronym>TDS</> Protocol version 7.0 is natively little endian. <productname>SQL Server 2000</productname> is also reported not to work from big endian clients without little endian emulation turned on.
+ 			</para>
+-<Note><para>The terms <emphasis>big endian</emphasis> and <emphasis>little endian</emphasis> come originally from Gulliver's Travels.  In computer science they refer to the the integer byte-order for a processor.  Big endian processors, such as Sparc and PowerPC store the most significant byte in the first memory location of a multi-byte integer.  Little endian processors, such as Intel and Alpha do it the other way around.  So the 16-bit number 258 would be 0x0102 on big endian and 0x0201 on little endian machines.</para></Note>
++<Note><para>If you are unfamiliar with the terms <emphasis>big endian</emphasis> and <emphasis>little endian</emphasis>, they are terms that come originally from Gulliver's Travels.  What they refer to in computer science is the the order in which bytes are stored by a processor.  Big endian machines such as Sparc and PowerPC store the most significant byte in the first memory location of a multi-byte integer.  Little endian machines such as Intel and Alpha do it the other way around.  So the 16-bit number 258 would be 0x0102 on big endian and 0x0201 on little endian machines.</para></Note>
+ 
+ <para>
+ In this example we want to force connections to a server named <literal>mssql</literal> to emulate a little endian client.  We are using protocol version 4.2 here, version 7.0 and 8.0 will automatically emulate little endian mode regardless of the <filename>freetds.conf</filename> setting.
+@@ -1765,16 +1763,16 @@ In this example we want to force connections to a server named <literal>mssql</l
+ </programlisting>
+ </example>
+ 		</sect1>
+-		<sect1 id="Localization">
+-			<title>Localization and <acronym>TDS</> 7.0</title>
++		<sect1 id="Nonwestern">
++			<title><acronym>TDS</> 7.0 for Nonwestern Languages</title>
+ 			<para>
+-<acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.  (Background information on Unicode and how it affects <productname>FreeTDS</productname> can be found in the <link linkend="Unicode">appendix</link>.)
++<acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.
+ 			</para>
+ 			<para>
+-Because most Unix tools and environments do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> provides for conversion by the client to other character sets.  The mechanism used is determined by the <filename>configure</> script, which looks for a <function>iconv</>(3) function, an implementation of the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.    If no <function>iconv</> library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in <function>iconv</> substitute, and will be capable of converting among only <acronym>ISO 8859-1</>, <acronym>UTF-8</>, and <acronym>UCS-2</>.  
++Since most Unix tools and languages do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> allows conversion by the client to other character sets using the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.  Background information on Unicode and how it affects <productname>FreeTDS</productname> can be found in the <link linkend="Unicode">appendix</link>.  If no iconv library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in iconv substitute, and will be capable of converting between only <acronym>ISO-8859-1</> and <acronym>UCS-2</>.  
+ 			</para>
+ 			<para>
+-To learn what character set the client wants, <productname>FreeTDS</productname> prefers the applicable <link linkend="clientcharset"><filename>freetds.conf</></link> <literal>client charset</> property.  If that is not set, it parses the <envar>LANG</> environment variable.  In either case, the found string is passed to <function>iconv</>(3) (or its built-in replacment).  <footnote><para>The built-in replacement expects GNU iconv names: <literal>ISO-8859-1</>, <literal>US-ASCII</>, or <literal>UTF-8</>.</para></footnote>.  If neither is found, <acronym>UCS-2</> data are converted to <acronym>ISO 8859-1</>.  
++To learn what character set the client is using, <productname>FreeTDS</productname> examines the <link linkend="clientcharset"><filename>freetds.conf</></link> entry.  If it finds nothing there, it assumes the client is using <acronym>ISO-8859-1</>.   That is generally a safe assumption for western languages such as English or French, but produces garbage for other languages.
+ 			</para>
+ 
+ 			<para>
+@@ -1803,9 +1801,10 @@ In this example a server named <literal>mssql</literal> will return data encoded
+ If <productname>FreeTDS</productname> runs into a character it can not convert, its behavior varies according to the severity of the problem.  On retrieving data from the server, <productname>FreeTDS</productname> substitutes an <acronym>ASCII</> '?' in the character's place, and emits a warning message stating that some characters could not be converted.  On sending data to the server, <productname>FreeTDS</productname> aborts the query and emits an error message.  It is well to ensure that the data contained in the database is representable in the client's character set.</para>
+ 
+ 			<para>
+-If you have a mix of character data that can not be contained in a single-byte character set, you may wish to use <acronym>UTF-8</>.  <acronym>UTF-8</> is a variable length unicode encoding that is compatible with <acronym>ASCII</> in the range 0 to 127.  With <acronym>UTF-8</>, you are guaranteed to never have an unconvertible character.</para>
++If you have a mix of character data that can not be contained in a single byte character set, you may wish to use <acronym>UTF-8</>.  <acronym>UTF-8</> is a variable length unicode encoding that is compatible with <acronym>ASCII</> in the range 0 to 127.  With <acronym>UTF-8</>, you are guaranteed to never have an unconvertible character.</para>
+ 
+-<Important><para><productname>FreeTDS</productname> is not fully compatible with multi-byte character sets such as <acronym>UCS-2</>.  You must use an ASCII-extension charset (e.g., UTF-8, ISO-8859-*)<footnote><para>not EBCDIC or other weird charsets</para></footnote>. Great care should be taken testing applications using these encodings. Specifically, many applications do not expect the number of characters returned to exceed the column size (in bytes).  </para></Important>
++<Important><para><productname>FreeTDS</productname> is not fully compatible with multi-byte character sets such as <acronym>UCS-2</>.  You must use an ASCII-extension charset (e.g., UTF-8, ISO-8859-*)<footnote><para>not EBCDIC or other weird charsets</para></footnote>. Extreme care should be taken with testing applications using these encodings. Specifically, many applications do not expect the number of characters returned to exceed the column size (in bytes).  On the other hand, support of <acronym>UTF-8</> and <acronym>UCS-2</> is a high priority for the developers.  Patches and bug reports in this area are especially welcome.  
++</para></Important>
+ 			<para>
+ In the following example, a server named <literal>mssql</literal> will return data encoded in the <acronym>UTF-8</> character set.
+ 			</para>
+@@ -3484,7 +3483,7 @@ But check!  No point in trying to use a null pointer.  </para></callout>
+ 			</para>
+ 
+ 			
+-			<para>Typically it's more convenient to have <symbol>db-lib</> convert the data into the desired form.  The function that does that is <function>dbind()</>.  So: after fetching the metadata, and before fetching the data, we usually prepare the bound columns.  </para>
++			<para>Typically it's more convenient to have <symbol>db-lib</> convert the data into the desired for.  The function that does that is <function>dbind()</>.  So: after fetching the metadata, and before fetching the data, we usually prepare the bound columns.  </para>
+ 
+ 			<bridgehead id="samplecode.results.fetching.data" renderas="sect3">Fetching Data</>
+ 			
+
+commit a0813f12200d2b5ae6c1a9d0de5a08fc1fe82da4
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 17:41:36 2008 +0000
+
+    s/calout/callout/
+
+diff --git b/ChangeLog a/ChangeLog
+index b4885f8..eda4bf6 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,6 @@
+ Sun Mar 23 13:26:57 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac doc/Makefile.am
+-	- applied ML patches from Johnny C. Lam for callout locations
++	- applied ML patches from Johnny C. Lam for calout locations
+ 	- and gnutls test. Posted RC4. 
+ 
+ Wed Mar 12 17:16:17 EDT 2008 JK Lowden <jklowden@freetds.org>
+@@ -128,4 +128,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.30 2008/03/23 17:41:36 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.29 2008/03/23 17:29:40 jklowden Exp $
+
+commit b1b46092634032b2eff6d939b3e24cc11332679a
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 17:29:40 2008 +0000
+
+    applied ML patches from Johnny C. Lam for calout locations
+     and gnutls test. Posted RC4.
+
+diff --git b/ChangeLog a/ChangeLog
+index eda4bf6..bb13f4b 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,8 +1,3 @@
+-Sun Mar 23 13:26:57 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* configure.ac doc/Makefile.am
+-	- applied ML patches from Johnny C. Lam for calout locations
+-	- and gnutls test. Posted RC4. 
+-
+ Wed Mar 12 17:16:17 EDT 2008 JK Lowden <jklowden@freetds.org>
+ 	* posted 0.82RC3
+ 
+@@ -128,4 +123,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.29 2008/03/23 17:29:40 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.28 2008/03/12 21:17:28 jklowden Exp $
+diff --git b/configure.ac a/configure.ac
+index eab617c..ddd9ece 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.9 2008/03/23 17:29:40 jklowden Exp $
++dnl $Id: configure.ac,v 1.29.2.8 2008/02/29 08:21:41 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.82RC4)
++AC_INIT(FreeTDS, 0.82RC3)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.9 $)
++AC_REVISION($Revision: 1.29.2.8 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -621,7 +621,7 @@ AC_SUBST(ODBCNODMLIBAPP)
+ 
+ AC_ARG_WITH(gnutls,
+ AS_HELP_STRING([--with-gnutls], [build with TLS support]))
+-if test "$with_gnutls" = "yes"; then
++if test "$with_gnutls"; then
+ 	AC_DEFINE(HAVE_GNUTLS, 1, [Define to 1 if you have GNU tls.])
+ 	CPPFLAGS="$CPPFLAGS `libgnutls-config --cflags`"
+ 	NETWORK_LIBS="$NETWORK_LIBS `libgnutls-config --libs`"
+diff --git b/doc/Makefile.am a/doc/Makefile.am
+index 7a3ea51..d416361 100644
+--- b/doc/Makefile.am
++++ a/doc/Makefile.am
+@@ -2,7 +2,7 @@
+ # Converting DocBook to HTML (several small files)
+ # http://www.freebsd.org/tutorials/docproj-primer/x3132.html#AEN3140
+ 
+-# $Id: Makefile.am,v 1.62.2.1 2008/03/23 17:29:40 jklowden Exp $
++# $Id: Makefile.am,v 1.62 2008/01/08 15:38:23 jklowden Exp $
+ 
+ SHELL = /bin/sh
+ TXT2MAN = $(srcdir)/txt2man
+@@ -55,8 +55,7 @@ man:	$(man_MANS)
+ installdirs: 
+ 	$(mkinstalldirs)	$(TARGET_DOCDIR)/userguide    \
+ 				$(TARGET_DOCDIR)/reference    \
+-				$(TARGET_DOCDIR)/images       \
+-				$(TARGET_DOCDIR)/images/callouts 2>&1
++				$(TARGET_DOCDIR)/images 2>&1
+ 
+ MANOPTS = -I 'FreeTDS User Guide'  -v 'FreeTDS Utilities' -t $(PRODUCT) -r $(VERSION)
+ 
+@@ -118,8 +117,8 @@ install-data-local: installdirs $(DOCDIR)/reference/index.html $(DOCDIR)/usergui
+ 	if test -r $(DOCDIR)/reference ; then d=.; else d="$(srcdir)"; fi; \
+ 	find $$d/$(DOCDIR)/reference \( -type f -o -type l \) -exec \
+ 		$(INSTALL_DATA) {} $(TARGET_DOCDIR)/reference ';'
+-	cd $(srcdir) && find images -name \*.gif -exec \
+-		$(INSTALL_DATA) {} $(TARGET_DOCDIR)/{} ';'
++	find $(srcdir)/images -name \*.gif -exec \
++		$(INSTALL_DATA) {} $(TARGET_DOCDIR)/images ';'
+ 
+ uninstall-local:
+ 	rm -rf $(TARGET_DOCDIR)
+
+commit f011423c84bb8b36e96f749d6501a1f0666c4deb
+Author: jklowden <jklowden>
+Date:   Wed Mar 12 21:17:28 2008 +0000
+
+    RC3
+
+diff --git b/ChangeLog a/ChangeLog
+index bb13f4b..a674354 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Wed Mar 12 17:16:17 EDT 2008 JK Lowden <jklowden@freetds.org>
+-	* posted 0.82RC3
+-
+ Tue Mar 11 09:26:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h: win64 portability issue
+ 
+@@ -123,4 +120,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.28 2008/03/12 21:17:28 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.27 2008/03/11 08:27:34 freddy77 Exp $
+
+commit f67fe7c1c9f694c406f340946c2cbdb8d6b01923
+Author: freddy77 <freddy77>
+Date:   Tue Mar 11 08:27:34 2008 +0000
+
+    backported small win64 portability issue
+
+diff --git b/ChangeLog a/ChangeLog
+index a674354..355e48c 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Tue Mar 11 09:26:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds_sysdep_private.h: win64 portability issue
+-
+ Tue Mar 11 09:24:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c:
+ 	- backported SQL_ATTR_CONNECTION_DEAD support
+@@ -120,4 +117,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.27 2008/03/11 08:27:34 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.26 2008/03/11 08:25:30 freddy77 Exp $
+diff --git b/include/tds_sysdep_private.h a/include/tds_sysdep_private.h
+index c248cbf..9b6fcb0 100644
+--- b/include/tds_sysdep_private.h
++++ a/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.23.2.1 2008/03/11 08:27:35 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.23 2007/01/29 11:02:43 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -87,10 +87,6 @@ typedef DWORD pid_t;
+ #define WIN32 1
+ #endif
+ 
+-#if defined(_WIN64) && !defined(WIN64)
+-#define WIN64 1
+-#endif
+-
+ #define TDS_SDIR_SEPARATOR "\\"
+ 
+ /* use macros to use new style names */
+
+commit f9481de1889b109a825308f443039060008a705a
+Author: freddy77 <freddy77>
+Date:   Tue Mar 11 08:25:30 2008 +0000
+
+    backported SQL_ATTR_CONNECTION_DEAD support
+
+diff --git b/ChangeLog a/ChangeLog
+index 355e48c..3b5da89 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Tue Mar 11 09:24:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c:
+-	- backported SQL_ATTR_CONNECTION_DEAD support
+-
+ Mon Mar 10 11:05:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* .cvsignore: ignore autogenerated
+ 	* src/odbc/odbc.c:
+@@ -117,4 +113,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.26 2008/03/11 08:25:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.25 2008/03/10 10:07:22 freddy77 Exp $
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index ffbabe7..76c3426 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.9 2008/03/11 08:25:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.8 2008/03/10 10:07:22 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4469,12 +4469,6 @@ _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTE
+ 		*((SQLUINTEGER *) Value) = dbc->attr.autocommit;
+ 		ODBC_RETURN_(dbc);
+ 		break;
+-#if defined(SQL_ATTR_CONNECTION_DEAD) && defined(SQL_CD_TRUE)
+-	case SQL_ATTR_CONNECTION_DEAD:
+-		*((SQLUINTEGER *) Value) = IS_TDSDEAD(dbc->tds_socket) ? SQL_CD_TRUE : SQL_CD_FALSE;
+-		ODBC_RETURN_(dbc);
+-		break;
+-#endif
+ 	case SQL_ATTR_CONNECTION_TIMEOUT:
+ 		*((SQLUINTEGER *) Value) = dbc->attr.connection_timeout;
+ 		ODBC_RETURN_(dbc);
+
+commit 6c5bf4f21aad2501de55d52988638d873cc6281c
+Author: freddy77 <freddy77>
+Date:   Mon Mar 10 10:07:22 2008 +0000
+
+    fix txn and auto-commit setting
+
+diff --git b/.cvsignore a/.cvsignore
+index d6098e5..c4ca19c 100644
+--- b/.cvsignore
++++ a/.cvsignore
+@@ -18,4 +18,3 @@ freetds.spec
+ PWD
+ doxyfile
+ test-dist.log
+-compile
+diff --git b/ChangeLog a/ChangeLog
+index 3b5da89..d11ef26 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,10 +1,3 @@
+-Mon Mar 10 11:05:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* .cvsignore: ignore autogenerated
+-	* src/odbc/odbc.c:
+-	- tell the truth about transaction levels
+-	- fix setting auto-commit off before connection
+-	* src/tds/encodings.pl: fix a problem with cvs
+-
+ Fri Feb 29 11:23:13 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/rowset.c:
+ 	- improved adding test for SQLExtendedFetch
+@@ -113,4 +106,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.25 2008/03/10 10:07:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.24 2008/02/29 10:24:41 freddy77 Exp $
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 76c3426..74e297a 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.8 2008/03/10 10:07:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.7 2008/02/29 09:23:51 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -224,9 +224,6 @@ change_autocommit(TDS_DBC * dbc, int state)
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
+ 		dbc->attr.autocommit = state;
+-	} else {
+-		/* if not connected we will change auto-commit after login */
+-		dbc->attr.autocommit = state;
+ 	}
+ 	ODBC_RETURN_(dbc);
+ }
+@@ -326,10 +323,6 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 	if (IS_TDS7_PLUS(dbc->tds_socket))
+ 		dbc->cursor_support = 1;
+ 
+-	if (dbc->attr.autocommit != SQL_AUTOCOMMIT_ON)
+-		if (!SQL_SUCCEEDED(change_autocommit(dbc, dbc->attr.autocommit)))
+-			ODBC_RETURN_(dbc);
+-
+ 	/* this overwrite any error arrived (wanted behavior, Sybase return error for conversion errors) */
+ 	ODBC_RETURN(dbc, SQL_SUCCESS);
+ }
+@@ -5534,7 +5527,8 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 		SIVAL = SQL_TC_ALL;
+ 		break;
+ 	case SQL_TXN_ISOLATION_OPTION:
+-		UIVAL = SQL_TXN_READ_COMMITTED;
++		/* TODO check SQLSetConnectAttr support */
++		UIVAL = SQL_TXN_READ_COMMITTED | SQL_TXN_READ_UNCOMMITTED | SQL_TXN_REPEATABLE_READ | SQL_TXN_SERIALIZABLE;
+ 		break;
+ 	case SQL_UNION:
+ 		UIVAL = SQL_U_UNION | SQL_U_UNION_ALL;
+diff --git b/src/tds/encodings.pl a/src/tds/encodings.pl
+index 1017836..2346c18 100755
+--- b/src/tds/encodings.pl
++++ a/src/tds/encodings.pl
+@@ -30,7 +30,7 @@ $filename = "${srcdir}sybase_character_sets.h";
+ open(OUT, ">$filename") or die qq($basename: could not open "$filename"\n);
+ print OUT "/*\n";
+ print OUT " * This file produced from $0\n";
+-print OUT ' * $Id: encodings.pl,v 1.10.4.1 2008/03/10 10:07:22 freddy77 Exp $', "\n";
++print OUT ' * $Id: encodings.pl,v 1.10 2005/04/06 06:44:33 jklowden Exp $', "\n";
+ print OUT " */\n";
+ 
+ # look up the canonical name
+@@ -64,7 +64,7 @@ while(<DATA>){
+ 
+ 		# grep for similar names, as an aid to the to programmer.  
+ 		$name =~ s/[\-\_]+//g;
+-		print STDERR $Name.":  $name alternative_character_sets.h\n";
++		print STDERR "$Name:  $name alternative_character_sets.h\n";
+ 	}
+ 	$comma = ',';
+ }
+@@ -77,7 +77,7 @@ close(OUT);
+ print "/*\n";
+ $date = localtime;
+ print " * This file produced from $0 on $date\n";
+-print ' * $Id: encodings.pl,v 1.10.4.1 2008/03/10 10:07:22 freddy77 Exp $', "\n";
++print ' * $Id: encodings.pl,v 1.10 2005/04/06 06:44:33 jklowden Exp $', "\n";
+ print " */\n";
+ 
+ %charsets = ();
+
+commit 0efd878ec0e374785a15e46b48cbdd639993979a
+Author: freddy77 <freddy77>
+Date:   Fri Feb 29 10:24:41 2008 +0000
+
+    improved adding test for SQLExtendedFetch
+
+diff --git b/ChangeLog a/ChangeLog
+index d11ef26..1354a3e 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Fri Feb 29 11:23:13 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/rowset.c:
+-	- improved adding test for SQLExtendedFetch
+-
+ Fri Feb 29 10:22:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/rowset.c(added):
+@@ -106,4 +102,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.24 2008/02/29 10:24:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.23 2008/02/29 09:23:51 freddy77 Exp $
+diff --git b/src/odbc/unittests/rowset.c a/src/odbc/unittests/rowset.c
+index e1f2e78..d2c23ea 100644
+--- b/src/odbc/unittests/rowset.c
++++ a/src/odbc/unittests/rowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rowset.c,v 1.1.2.2 2008/02/29 10:24:41 freddy77 Exp $";
++static char software_version[] = "$Id: rowset.c,v 1.1.2.1 2008/02/29 09:23:51 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHK(func,params) \
+@@ -44,67 +44,25 @@ test_err(int n)
+ int
+ main(int argc, char *argv[])
+ {
+-	int i;
+ 	SQLLEN len;
+-#ifdef HAVE_SQLROWSETSIZE
+-	SQLROWSETSIZE row_count;
+-#else
+-	SQLULEN row_count;
+-#endif
+-	SQLUSMALLINT statuses[10];
+-	char buf[32];
+-	SQLRETURN rc;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	/* initial value should be 1 */
+ 	CHK(SQLGetStmtAttr, (Statement, SQL_ROWSET_SIZE, &len, sizeof(len), NULL));
+ 	if (len != 1) {
+ 		fprintf(stderr, "len should be 1\n");
+ 		Disconnect();
+ 		return 1;
+ 	}
+-
+-	/* check invalid parameter values */
++	
+ 	test_err(-123);
+ 	test_err(-1);
+ 	test_err(0);
+ 
+-	/* set some correct values */
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0));
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0));
+ 
+-	/* now check that SQLExtendedFetch works as expected */
+-	Command(Statement, "CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
+-	for (i = 0; i < 10; ++i) {
+-		char s[10];
+-		char sql[128];
+-
+-		memset(s, 'a' + i, 9);
+-		s[9] = 0;
+-		sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s);
+-		Command(Statement, sql);
+-	}
+-
+-	ResetStatement();
+-	CHK(SQLSetStmtOption, (Statement, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC));
+-	rc = CommandWithResult(Statement, "SELECT * FROM #rowset ORDER BY n");
+-	if (!SQL_SUCCEEDED(rc))
+-		ODBC_REPORT_ERROR("SQLExecDirect error");
+-
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, buf, sizeof(buf), &len));
+-
+-	row_count = 0xdeadbeef;
+-	memset(statuses, 0x55, sizeof(statuses));
+-	CHK(SQLExtendedFetch, (Statement, SQL_FETCH_NEXT, 1, &row_count, statuses));
+-
+-	if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) {
+-		fprintf(stderr, "Invalid result\n");
+-		Disconnect();
+-		return 1;
+-	}
+-
+ 	Disconnect();
+ 
+ 	printf("Done.\n");
+
+commit 15a4a82830ba9c69cacf7290678494d10d4834e7
+Author: freddy77 <freddy77>
+Date:   Fri Feb 29 09:23:51 2008 +0000
+
+    fix SQL_ROWSET_SIZE
+
+diff --git b/ChangeLog a/ChangeLog
+index 1354a3e..3b6ca5e 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,8 +1,3 @@
+-Fri Feb 29 10:22:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/rowset.c(added):
+-	- fix SQL_ROWSET_SIZE
+-
+ Fri Feb 29 09:20:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac: avoid version clash
+ 
+@@ -102,4 +97,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.23 2008/02/29 09:23:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.22 2008/02/29 08:21:41 freddy77 Exp $
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 74e297a..8d564a4 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.7 2008/02/29 09:23:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.6 2008/02/27 16:08:57 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -1472,7 +1472,8 @@ _SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR * phstmt)
+ 	stmt->attr.simulate_cursor = SQL_SC_NON_UNIQUE;
+ 	stmt->attr.use_bookmarks = SQL_UB_OFF;
+ 
+-	stmt->sql_rowset_size = 1;
++	/* is not the same of using APD sql_desc_bind_type */
++	stmt->sql_rowset_size = SQL_BIND_BY_COLUMN;
+ 
+ 	stmt->row_count = TDS_NO_COUNT;
+ 	stmt->row_status = NOT_IN_ROW;
+@@ -6175,10 +6176,6 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN
+ 		stmt->attr.use_bookmarks = ui;
+ 		break;
+ 	case SQL_ROWSET_SIZE:	/* although this is ODBC2 we must support this attribute */
+-		if (((TDS_INTPTR) ValuePtr) < 1) {
+-			odbc_errs_add(&stmt->errs, "HY024", NULL);
+-			ODBC_RETURN(stmt, SQL_ERROR);
+-		}
+ 		stmt->sql_rowset_size = ui;
+ 		break;
+ 	default:
+diff --git b/src/odbc/unittests/.cvsignore a/src/odbc/unittests/.cvsignore
+index 2da9b2c..d7c663e 100644
+--- b/src/odbc/unittests/.cvsignore
++++ a/src/odbc/unittests/.cvsignore
+@@ -64,4 +64,3 @@ cursor5
+ attributes
+ hidden
+ blob1
+-rowset
+diff --git b/src/odbc/unittests/Makefile.am a/src/odbc/unittests/Makefile.am
+index f6a4a35..8146c2a 100644
+--- b/src/odbc/unittests/Makefile.am
++++ a/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.68.2.3 2008/02/29 09:23:51 freddy77 Exp $
++# $Id: Makefile.am,v 1.68.2.2 2008/01/10 13:22:19 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -20,8 +20,7 @@ TESTS		=	\
+ 			paramcore$(EXEEXT) timeout2$(EXEEXT) timeout3$(EXEEXT) \
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+-			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+-			rowset$(EXEEXT)
++			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -80,7 +79,6 @@ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
+ hidden_SOURCES	= hidden.c common.c common.h
+ blob1_SOURCES	= blob1.c common.c common.h
+-rowset_SOURCES	= rowset.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git b/src/odbc/unittests/rowset.c a/src/odbc/unittests/rowset.c
+deleted file mode 100644
+index d2c23ea..0000000
+--- b/src/odbc/unittests/rowset.c
++++ /dev/null
+@@ -1,70 +0,0 @@
+-#include "common.h"
+-
+-static char software_version[] = "$Id: rowset.c,v 1.1.2.1 2008/02/29 09:23:51 freddy77 Exp $";
+-static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+-
+-#define CHK(func,params) \
+-	if (func params != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func)
+-
+-static char odbc_err[256];
+-static char odbc_sqlstate[6];
+-
+-static void
+-ReadError(void)
+-{
+-	memset(odbc_err, 0, sizeof(odbc_err));
+-	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
+-	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+-}
+-
+-static void
+-test_err(int n)
+-{
+-	SQLRETURN rc;
+-
+-	rc = SQLSetStmtAttr(Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(n), 0);
+-	if (rc != SQL_ERROR) {
+-		fprintf(stderr, "SQLSetStmtAttr should fail\n");
+-		Disconnect();
+-		exit(1);
+-        }
+-	ReadError();
+-	if (strcmp(odbc_sqlstate, "HY024") != 0) {
+-		fprintf(stderr, "Unexpected sql state returned\n");
+-		Disconnect();
+-		exit(1);
+-        }
+-}
+-
+-int
+-main(int argc, char *argv[])
+-{
+-	SQLLEN len;
+-
+-	use_odbc_version3 = 1;
+-	Connect();
+-
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ROWSET_SIZE, &len, sizeof(len), NULL));
+-	if (len != 1) {
+-		fprintf(stderr, "len should be 1\n");
+-		Disconnect();
+-		return 1;
+-	}
+-	
+-	test_err(-123);
+-	test_err(-1);
+-	test_err(0);
+-
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0));
+-
+-	Disconnect();
+-
+-	printf("Done.\n");
+-	return 0;
+-}
+
+commit bba9b941d3a9e054583667f355f8dd49ed6ed8d0
+Author: freddy77 <freddy77>
+Date:   Fri Feb 29 08:21:41 2008 +0000
+
+    avoid version clash
+
+diff --git b/ChangeLog a/ChangeLog
+index 3b6ca5e..fd93f61 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Fri Feb 29 09:20:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: avoid version clash
+-
+ Thu Feb 28 18:21:50 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* vms/configure.com turn off iconv by default
+ 
+@@ -97,4 +94,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.22 2008/02/29 08:21:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.21 2008/02/28 23:22:43 jklowden Exp $
+diff --git b/configure.ac a/configure.ac
+index ddd9ece..adad2d2 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.8 2008/02/29 08:21:41 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.7 2008/02/15 10:48:25 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.82RC3)
++AC_INIT(FreeTDS, 0.82RC2)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.8 $)
++AC_REVISION($Revision: 1.29.2.7 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+
+commit 9a04187a9fef3e2cfed6d32d27e332fbe04c5feb
+Author: jklowden <jklowden>
+Date:   Thu Feb 28 23:22:43 2008 +0000
+
+    turn off iconv by default
+
+diff --git b/ChangeLog a/ChangeLog
+index fd93f61..7ca0b8d 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Thu Feb 28 18:21:50 EST 2008	JK Lowden <jklowden@freetds.org>
+-	* vms/configure.com turn off iconv by default
+-
+ Thu Feb 28 17:32:33 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* posted 0.82RC2
+ 
+@@ -94,4 +91,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.21 2008/02/28 23:22:43 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.20 2008/02/28 22:53:49 jklowden Exp $
+diff --git b/vms/configure.com a/vms/configure.com
+index 3f0d02a..37b59b3 100644
+--- b/vms/configure.com
++++ a/vms/configure.com
+@@ -16,7 +16,7 @@ $! License along with this library; if not, write to the
+ $! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ $! Boston, MA 02111-1307, USA.
+ $!
+-$! $Id: configure.com,v 1.5.4.1 2008/02/28 23:22:43 jklowden Exp $
++$! $Id: configure.com,v 1.5 2005/12/29 10:24:34 freddy77 Exp $
+ $!
+ $! CONFIGURE.COM -- run from top level source directory as @[.vms]configure
+ $!
+@@ -38,9 +38,7 @@ $! The system-supplied iconv() is fine, but unless the internationalization
+ $! kit has been installed, we may not have the conversions we need.  Check
+ $! for their presence and use the homegrown iconv() if necessary.
+ $!
+-$ IF -
+-    "FALSE" - ! native iconv() buggy, don't use for now
+-    .AND. F$SEARCH("SYS$I18N_ICONV:UCS-2_ISO8859-1.ICONV") .NES. "" -
++$ IF F$SEARCH("SYS$I18N_ICONV:UCS-2_ISO8859-1.ICONV") .NES. "" -
+     .AND. F$SEARCH("SYS$I18N_ICONV:ISO8859-1_UCS-2.ICONV") .NES. "" -
+     .AND. F$SEARCH("SYS$I18N_ICONV:UTF-8_ISO8859-1.ICONV") .NES. "" -
+     .AND. F$SEARCH("SYS$I18N_ICONV:ISO8859-1_UTF-8.ICONV") .NES. ""
+
+commit ccb100b3638d3d6adfad27d95555eee2536b112a
+Author: jklowden <jklowden>
+Date:   Thu Feb 28 22:53:49 2008 +0000
+
+    released RC2
+
+diff --git b/ChangeLog a/ChangeLog
+index 7ca0b8d..5944acd 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Thu Feb 28 17:32:33 EST 2008	JK Lowden <jklowden@freetds.org>
+-	* posted 0.82RC2
+-
+ Wed Feb 27 17:06:22 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c:
+ 	- SQLExecDirect/SQLExecute return SQL_SUCCESS instead of SQL_NO_DATA
+@@ -91,4 +88,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.20 2008/02/28 22:53:49 jklowden Exp $
++$Id: ChangeLog,v 1.2454.2.19 2008/02/27 16:08:40 freddy77 Exp $
+
+commit b4ea3901405b132255a63b9d9786948a393cad02
+Author: freddy77 <freddy77>
+Date:   Wed Feb 27 16:08:40 2008 +0000
+
+    SQLExecDirect/SQLExecute return SQL_SUCCESS instead of SQL_NO_DATA
+
+diff --git b/ChangeLog a/ChangeLog
+index 5944acd..58ee2df 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Wed Feb 27 17:06:22 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c:
+-	- SQLExecDirect/SQLExecute return SQL_SUCCESS instead of SQL_NO_DATA
+-
+ Fri Feb 15 11:47:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac: fix nasty problem with HP-UX
+ 
+@@ -88,4 +84,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.19 2008/02/27 16:08:40 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.18 2008/02/15 10:48:24 freddy77 Exp $
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 8d564a4..a639c4c 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.6 2008/02/27 16:08:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.5 2008/01/29 10:14:29 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3179,6 +3179,9 @@ _SQLExecute(TDS_STMT * stmt)
+ 	case TDS_CMD_DONE:
+ 		if (stmt->dbc->current_statement == stmt)
+ 			stmt->dbc->current_statement = NULL;
++		if (stmt->errs.lastrc == SQL_SUCCESS && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3
++		    && stmt->row_count == TDS_NO_COUNT && !stmt->cursor)
++			ODBC_RETURN(stmt, SQL_NO_DATA);
+ 		break;
+ 
+ 	case TDS_CMD_FAIL:
+
+commit 133d01873224b00eb74ba5db2d614780b841fa05
+Author: freddy77 <freddy77>
+Date:   Fri Feb 15 10:48:24 2008 +0000
+
+    fix an ABI problem under HP-UX
+
+diff --git b/ChangeLog a/ChangeLog
+index 58ee2df..3349c0f 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Fri Feb 15 11:47:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: fix nasty problem with HP-UX
+-
+ Tue Feb 12 16:41:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqlodbc.c: fix memory error
+ 	* src/tds/query.c: remove possible buffer underflow
+@@ -84,4 +81,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.18 2008/02/15 10:48:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.17 2008/02/12 15:41:51 freddy77 Exp $
+diff --git b/configure.ac a/configure.ac
+index adad2d2..318611d 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.7 2008/02/15 10:48:25 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.6 2008/01/27 10:41:21 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.82RC2)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.7 $)
++AC_REVISION($Revision: 1.29.2.6 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -47,6 +47,7 @@ case $host in
+     netdb_reentrant=yes
+     ;;
+   *-*-hpux11*)
++    CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED"
+     netdb_reentrant=yes
+     ;;
+   *-*-cygwin*)
+@@ -150,27 +151,6 @@ case $host in
+ 	fi
+ 	AM_CONDITIONAL(MINGW32, true)
+ 	;;
+-*-*-hpux*)
+-	# these lines are needed to fix a problem for HP-UX
+-	# HP-UX define two versions of sockets, one BSD and one X/Open
+-	# these versions are not binary compatible (BSD use int where X/Open 
+-	# use socklen_t == size_t) and different libraries (BSD in libc and
+-	# X/Open in libxnet). X/Open is used if _XOPEN_SOURCE and 
+-	# _XOPEN_SOURCE_EXTENDED are defined. To complicate the things gcc
+-	# by default define _XOPEN_SOURCE_EXTENDED so define always both
+-	# constants and link always libxnet!
+-	CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED"
+-	LIBS="$LIBS -lxnet"
+-	AC_SEARCH_LIBS(gethostbyname, nsl)
+-	if test "$enable_krb5" = "yes" ; then
+-		AC_SEARCH_LIBS(gss_init_sec_context, [gssapi_krb5 gssapi])
+-		if test "$ac_cv_search_gss_init_sec_context" != no; then
+-			AC_DEFINE(ENABLE_KRB5, 1, [Defined if --enable-krb5 used and library detected])
+-		fi
+-	fi
+-
+-	AM_CONDITIONAL(MINGW32, false)
+-	;;
+ *)
+ 	AC_SEARCH_LIBS(socket, socket)
+ 	AC_SEARCH_LIBS(gethostbyname, nsl)
+
+commit 32afc4af2cd25dafb6df4d2d53e2594229f49c6e
+Author: freddy77 <freddy77>
+Date:   Tue Feb 12 15:41:51 2008 +0000
+
+    fix possible memory errors
+
+diff --git b/ChangeLog a/ChangeLog
+index 3349c0f..34b8f87 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Tue Feb 12 16:41:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/bsqlodbc.c: fix memory error
+-	* src/tds/query.c: remove possible buffer underflow
+-
+ Wed Feb 06 09:48:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/unittests/t0007.c: test more data
+ 
+@@ -81,4 +77,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.17 2008/02/12 15:41:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.16 2008/02/06 08:49:44 freddy77 Exp $
+diff --git b/src/apps/bsqlodbc.c a/src/apps/bsqlodbc.c
+index 5a6cc42..1050550 100644
+--- b/src/apps/bsqlodbc.c
++++ a/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.9.2.1 2008/02/12 15:41:51 freddy77 Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.9 2007/11/26 06:25:57 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -354,8 +354,7 @@ next_query()
+ 	fprintf(options.verbose, "%s:%d: Query:\n", options.appname, __LINE__);
+ 	
+ 	free(sql);
+-	sql = NULL;
+-
++	
+ 	while (fgets(query_line, sizeof(query_line), stdin)) {
+ 		/* 'go' or 'GO' separates command batches */
+ 		char *p = query_line;
+diff --git b/src/tds/query.c a/src/tds/query.c
+index 3996aef..8ef57f7 100644
+--- b/src/tds/query.c
++++ a/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.217.2.1 2008/02/12 15:41:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.217 2008/01/05 11:24:40 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -577,7 +577,7 @@ tds_next_placeholder_ucs2le(const char *start, const char *end, int named)
+ 		case '?':
+ 			return p;
+ 		case '@':
+-			if (named && !isalnum((unsigned char) prev))
++			if (named && !isalnum(prev))
+ 				return p;
+ 		default:
+ 			p += 2;
+@@ -849,7 +849,7 @@ tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t quer
+ 					continue;
+ 				/* find end of param name */
+ 				for (id_end = e + 2; id_end != query_end; id_end += 2)
+-					if (!id_end[1] && (id_end[0] != '_' && id_end[1] != '#' && !isalnum((unsigned char) id_end[0])))
++					if (!id_end[1] && (id_end[0] != '_' && id_end[1] != '#' && !isalnum(id_end[0])))
+ 						break;
+ 				ids[i].p = e;
+ 				ids[i].len = id_end - e;
+
+commit 0f12f08f4f3231c3785f43c913cb98e8ff0d8207
+Author: freddy77 <freddy77>
+Date:   Wed Feb 6 08:49:44 2008 +0000
+
+    more conversions tests
+
+diff --git b/ChangeLog a/ChangeLog
+index 34b8f87..2441480 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Wed Feb 06 09:48:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/unittests/t0007.c: test more data
+-
+ Mon Feb 04 08:54:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/convert.c: fix memory leak
+ 
+@@ -77,4 +74,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.16 2008/02/06 08:49:44 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.15 2008/02/04 07:55:39 freddy77 Exp $
+diff --git b/src/tds/unittests/t0007.c a/src/tds/unittests/t0007.c
+index 4f1479a..d867fbe 100644
+--- b/src/tds/unittests/t0007.c
++++ a/src/tds/unittests/t0007.c
+@@ -20,7 +20,7 @@
+ #include "common.h"
+ #include <tdsconvert.h>
+ 
+-static char software_version[] = "$Id: t0007.c,v 1.14.2.1 2008/02/06 08:49:44 freddy77 Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.14 2006/06/08 08:19:05 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static TDSCONTEXT ctx;
+@@ -39,7 +39,6 @@ test0(const char *src, int len, int dsttype, const char *result)
+ 	if (res < 0)
+ 		strcpy(buf, "error");
+ 	else {
+-		buf[0] = 0;
+ 		switch (dsttype) {
+ 		case SYBINT1:
+ 			sprintf(buf, "%d", cr.ti);
+@@ -50,9 +49,6 @@ test0(const char *src, int len, int dsttype, const char *result)
+ 		case SYBINT4:
+ 			sprintf(buf, "%d", cr.i);
+ 			break;
+-		case SYBINT8:
+-			sprintf(buf, "0x%08x%08x", (unsigned int) ((cr.bi >> 32) & 0xfffffffflu), (unsigned int) (cr.bi & 0xfffffffflu));
+-			break;
+ 		case SYBUNIQUE:
+ 			sprintf(buf, "%08X-%04X-%04X-%02X%02X%02X%02X"
+ 				"%02X%02X%02X%02X",
+@@ -96,42 +92,9 @@ main(int argc, char **argv)
+ 	test("123", SYBINT1, "123");
+ 	test("  -    1234   ", SYBINT2, "-1234");
+ 	test("  -    1234   a", SYBINT2, "error");
+-	test("", SYBINT4, "0");
+-	test("    ", SYBINT4, "0");
+-	test("    123", SYBINT4, "123");
+-	test("    123    ", SYBINT4, "123");
+-	test("  +  123  ", SYBINT4, "123");
+-	test("+", SYBINT4, "error");
+-	test("   +", SYBINT4, "error");
+-	test("+   ", SYBINT4, "error");
+-	test("   +   ", SYBINT4, "error");
+-	test("-", SYBINT4, "error");
+-	test("   -", SYBINT4, "error");
+-	test("-   ", SYBINT4, "error");
+-	test("   -   ", SYBINT4, "error");
+-
+-	test("  -    1234   ", SYBINT8, "0xfffffffffffffb2e");
+-	test("  -    1234   a", SYBINT8, "error");
+-	test("", SYBINT8, "0x0000000000000000");
+-	test("    ", SYBINT8, "0x0000000000000000");
+-	test("    123", SYBINT8, "0x000000000000007b");
+-	test("    123    ", SYBINT8, "0x000000000000007b");
+-	test("  +  123  ", SYBINT8, "0x000000000000007b");
+-	test("+", SYBINT8, "error");
+-	test("   +", SYBINT8, "error");
+-	test("+   ", SYBINT8, "error");
+-	test("   +   ", SYBINT8, "error");
+-	test("-", SYBINT8, "error");
+-	test("   -", SYBINT8, "error");
+-	test("-   ", SYBINT8, "error");
+-	test("   -   ", SYBINT8, "error");
+ 
+ 	/* test for overflow */
+ 	printf("overflow checks...\n");
+-	test("9223372036854775807", SYBINT8, "0x7fffffffffffffff");
+-	test("9223372036854775808", SYBINT8, "error");
+-	test("-9223372036854775808", SYBINT8, "0x8000000000000000");
+-	test("-9223372036854775809", SYBINT8, "error");
+ 	test("2147483647", SYBINT4, "2147483647");
+ 	test("2147483648", SYBINT4, "error");
+ 	test("-2147483648", SYBINT4, "-2147483648");
+@@ -158,7 +121,6 @@ main(int argc, char **argv)
+ 
+ 	/* test not terminated string */
+ 	test0("1234", 2, SYBINT4, "12");
+-	test0("123456", 4, SYBINT8, "0x00000000000004d2");
+ 
+ 	/* some test for unique */
+ 	printf("unique type...\n");
+
+commit 66996076495c6cb0f369d4a082180d465ea8c35e
+Author: freddy77 <freddy77>
+Date:   Mon Feb 4 07:55:39 2008 +0000
+
+    fix silly memory leak
+
+diff --git b/ChangeLog a/ChangeLog
+index 2441480..b0130db 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Mon Feb 04 08:54:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/convert.c: fix memory leak
+-
+ Tue Jan 29 11:12:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	* src/odbc/unittests/getdata.c:
+@@ -74,4 +71,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.15 2008/02/04 07:55:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.14 2008/01/29 10:14:23 freddy77 Exp $
+diff --git b/src/tds/convert.c a/src/tds/convert.c
+index fa03c47..fa8dbd1 100644
+--- b/src/tds/convert.c
++++ a/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.179.2.1 2008/02/04 07:55:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.179 2007/12/31 10:06:50 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -1958,7 +1958,6 @@ string_to_datetime(const char *instr, int desttype, CONV_RESULT * cr)
+ 
+ 			tdsdump_log(TDS_DBG_INFO1,
+ 				    "error_handler:  Attempt to convert data stopped by syntax error in source field \n");
+-			free(in);
+ 			return TDS_CONVERT_SYNTAX;
+ 		}
+ 
+
+commit 8cfd82525fd0f902afb5e7894c709df0ea437cf9
+Author: freddy77 <freddy77>
+Date:   Tue Jan 29 10:14:23 2008 +0000
+
+    handle errors from convert_tds2sql
+
+diff --git b/ChangeLog a/ChangeLog
+index b0130db..6ea3faa 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,8 +1,3 @@
+-Tue Jan 29 11:12:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/convert_tds2sql.c src/odbc/odbc.c src/odbc/odbc_util.c:
+-	* src/odbc/unittests/getdata.c:
+-	- backported fix for error handling in SQLGetData/SQLFetch
+-
+ Sun Jan 27 11:40:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/apps/Makefile.am:
+ 	- backported fix for bsqlodbc dependency
+@@ -71,4 +66,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.14 2008/01/29 10:14:23 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.13 2008/01/27 10:41:21 freddy77 Exp $
+diff --git b/src/odbc/convert_tds2sql.c a/src/odbc/convert_tds2sql.c
+index cc7bc7d..04e0b8a 100644
+--- b/src/odbc/convert_tds2sql.c
++++ a/src/odbc/convert_tds2sql.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.49.2.1 2008/01/29 10:14:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.49 2007/05/25 09:10:10 freddy77 Exp $");
+ 
+ TDS_INT
+ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+@@ -56,7 +56,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 	TIMESTAMP_STRUCT *tssp;
+ 	SQL_NUMERIC_STRUCT *num;
+ 
+-	int ret = TDS_CONVERT_FAIL;
++	int ret = TDS_FAIL;
+ 	int i, cplen;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "convert_tds2sql: src is %d dest = %d\n", srctype, desttype);
+@@ -89,7 +89,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 			} else {
+ 				/* if destlen == 0 we return only length */
+ 				if (destlen != 0)
+-					ret = TDS_CONVERT_FAIL;
++					ret = TDS_FAIL;
+ 			}
+ 			return ret;
+ 		}
+@@ -143,7 +143,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 		} else {
+ 			/* if destlen == 0 we return only length */
+ 			if (destlen != 0)
+-				ret = TDS_CONVERT_FAIL;
++				ret = TDS_FAIL;
+ 		}
+ 		break;
+ 
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index a639c4c..1e3c3a8 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.5 2008/01/29 10:14:29 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.4 2008/01/27 10:41:23 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3340,28 +3340,6 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ 	}
+ }
+ 
+-static void
+-odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err)
+-{
+-	switch (err) {
+-	case TDS_CONVERT_NOAVAIL:
+-		odbc_errs_add(errs, "HY003", NULL);
+-		break;
+-	case TDS_CONVERT_SYNTAX:
+-		odbc_errs_add(errs, "22018", NULL);
+-		break;
+-	case TDS_CONVERT_OVERFLOW:
+-		odbc_errs_add(errs, "22003", NULL);
+-		break;
+-	case TDS_CONVERT_FAIL:
+-		odbc_errs_add(errs, "07006", NULL);
+-		break;
+-	case TDS_CONVERT_NOMEM:
+-		odbc_errs_add(errs, "HY001", NULL);
+-		break;
+-	}
+-}
+-
+ /*
+  * - handle correctly SQLGetData (for forward cursors accept only row_size == 1
+  *   for other types application must use SQLSetPos)
+@@ -3596,7 +3574,6 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				len = convert_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+ 				if (len < 0) {
+-					odbc_convert_err_set(&stmt->errs, len);
+ 					row_status = SQL_ROW_ERROR;
+ 					break;
+ 				}
+@@ -4614,19 +4591,10 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+ 		if (fCType == SQL_C_DEFAULT)
+ 			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+-		if (fCType == SQL_ARD_TYPE) {
+-			if (icol > stmt->ard->header.sql_desc_count) {
+-				odbc_errs_add(&stmt->errs, "07009", NULL);
+-				ODBC_RETURN(stmt, SQL_ERROR);
+-			}
+-			fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+-		}
+ 		assert(fCType);
+ 		*pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+-		if (*pcbValue < 0) {
+-			odbc_convert_err_set(&stmt->errs, *pcbValue);
++		if (*pcbValue < 0)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+-		}
+ 
+ 		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ 			/* calc how many bytes was readed */
+diff --git b/src/odbc/odbc_util.c a/src/odbc/odbc_util.c
+index bd73130..fb38d5b 100644
+--- b/src/odbc/odbc_util.c
++++ a/src/odbc/odbc_util.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.94.2.1 2008/01/29 10:14:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.94 2007/06/19 13:31:34 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -140,7 +140,7 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ 
+ 		len = convert_tds2sql(context, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
+ 				      drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
+-		if (len < 0)
++		if (TDS_FAIL == len)
+ 			return /* SQL_ERROR */ ;
+ 		if (drec->sql_desc_indicator_ptr)
+ 			LEN(drec->sql_desc_indicator_ptr) = 0;
+diff --git b/src/odbc/unittests/getdata.c a/src/odbc/unittests/getdata.c
+index 0c2d112..eead6e0 100644
+--- b/src/odbc/unittests/getdata.c
++++ a/src/odbc/unittests/getdata.c
+@@ -1,54 +1,15 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.4.2.1 2008/01/29 10:14:31 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.4 2007/08/07 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static char odbc_err[256];
+-static char odbc_sqlstate[6];
+-
+-static void
+-ReadError(void)
+-{
+-	memset(odbc_err, 0, sizeof(odbc_err));
+-	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
+-	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+-}
+-
+-static void
+-test_err(const char *data, int c_type, const char *state)
+-{
+-	char sql[128];
+-	SQLRETURN rc;
+-	SQLLEN ind;
+-	const unsigned int buf_size = 128;
+-	char *buf = (char *) malloc(buf_size);
+-
+-	sprintf(sql, "SELECT '%s'", data);
+-	Command(Statement, sql);
+-	SQLFetch(Statement);
+-	rc = SQLGetData(Statement, 1, c_type, buf, buf_size, &ind);
+-	free(buf);
+-	if (rc != SQL_ERROR)
+-		ODBC_REPORT_ERROR("SQLGetData error expected");
+-	ReadError();
+-	if (strcmp(odbc_sqlstate, state) != 0) {
+-		fprintf(stderr, "Unexpected sql state returned\n");
+-		Disconnect();
+-		exit(1);
+-	}
+-	ResetStatement();
+-}
+-
+ int
+ main(int argc, char *argv[])
+ {
+ 	char buf[16];
+ 	SQLINTEGER int_buf;
+ 	SQLLEN len;
++	int ms_db = 0;
+ 
+ 	Connect();
+ 
+@@ -129,24 +90,14 @@ main(int argc, char *argv[])
+ 
+ 	ResetStatement();
+ 
++	ms_db = db_is_microsoft();
++
+ 	Disconnect();
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	if (ms_db) {
++		use_odbc_version3 = 1;
++		Connect();
+ 
+-	/* test error from SQLGetData */
+-	/* wrong constant */
+-	test_err("prova 123",           SQL_VARCHAR,     "HY003");
+-	/* use ARD but no ARD data column */
+-	test_err("prova 123",           SQL_ARD_TYPE,    "07009");
+-	/* wrong conversion, int */
+-	test_err("prova 123",           SQL_C_LONG,      "22018");
+-	/* wrong conversion, int */
+-	test_err("prova 123",           SQL_C_TIMESTAMP, "22018");
+-	/* overflow */
+-	test_err("1234567890123456789", SQL_C_LONG,      "22003");
+-
+-	if (db_is_microsoft()) {
+ 		Command(Statement, "SELECT CONVERT(TEXT,'')");
+ 
+ 		if (SQLFetch(Statement) != SQL_SUCCESS)
+@@ -163,9 +114,9 @@ main(int argc, char *argv[])
+ 
+ 		if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 1, NULL) != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("invalid return from SQLGetData");
+-	}
+ 
+-	Disconnect();
++		Disconnect();
++	}
+ 
+ 	printf("Done.\n");
+ 	return 0;
+
+commit 41c2785bfcd95cb9da5c6d42446b60687c1cbff1
+Author: freddy77 <freddy77>
+Date:   Sun Jan 27 10:41:21 2008 +0000
+
+    backported fix for SQLCancel and bsqlodbc dependency
+
+diff --git b/ChangeLog a/ChangeLog
+index 6ea3faa..92f275a 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,9 +1,3 @@
+-Sun Jan 27 11:40:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/apps/Makefile.am:
+-	- backported fix for bsqlodbc dependency
+-	* include/tdsodbc.h src/odbc/odbc.c src/tds/token.c:
+-	- backported fix for SQLCancel
+-
+ Wed Jan 23  9:48:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac include/tds_sysdep_public.h.in:
+ 	* src/ctlib/unittests/cancel.c src/dblib/unittests/timeout.c:
+@@ -66,4 +60,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.13 2008/01/27 10:41:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.12 2008/01/23 08:50:15 freddy77 Exp $
+diff --git b/configure.ac a/configure.ac
+index 318611d..b8eef11 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.6 2008/01/27 10:41:21 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.5 2008/01/23 08:50:16 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.82RC2)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.6 $)
++AC_REVISION($Revision: 1.29.2.5 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -476,7 +476,6 @@ if test "$with_odbc_nodm"; then
+ 	# Can't use ODBCLIB/LDFLAGS variables since they are used in building
+ 	#  other directories.
+ 	ODBCNODMLIB="-L.. -ltdsodbc"
+-	ODBCNODMLIBAPP="-L../odbc -ltdsodbc"
+ 	odbc=true
+ fi
+ 
+@@ -597,7 +596,6 @@ AC_SUBST(ODBC_INC)
+ AC_SUBST(ODBCLIB)
+ AC_SUBST(ODBCINSTLIB)
+ AC_SUBST(ODBCNODMLIB)
+-AC_SUBST(ODBCNODMLIBAPP)
+ 
+ AC_ARG_WITH(gnutls,
+ AS_HELP_STRING([--with-gnutls], [build with TLS support]))
+diff --git b/include/tdsodbc.h a/include/tdsodbc.h
+index 733647b..59fdfc1 100644
+--- b/include/tdsodbc.h
++++ a/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.103.2.1 2008/01/27 10:41:22 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.103 2007/11/26 18:12:30 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -370,7 +370,6 @@ struct _hstmt
+ 	int special_row;
+ 	/* do NOT free cursor, free from socket or attach to connection */
+ 	TDSCURSOR *cursor;
+-	unsigned char cancel_sent;
+ };
+ 
+ typedef struct _henv TDS_ENV;
+diff --git b/src/apps/Makefile.am a/src/apps/Makefile.am
+index 447d9b8..cfa03ac 100644
+--- b/src/apps/Makefile.am
++++ a/src/apps/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.25.2.1 2008/01/27 10:41:22 freddy77 Exp $
++# $Id: Makefile.am,v 1.25 2008/01/01 23:09:46 freddy77 Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -28,8 +28,9 @@ bsqldb_LDADD	= ../dblib/libsybdb.la \
+ 		  $(NETWORK_LIBS)
+ 
+ if ODBC
+-bsqlodbc_LDADD	= $(ODBCLIB) $(ODBCNODMLIBAPP) \
+-		  ../replacements/libreplacements.la $(NETWORK_LIBS)
++bsqlodbc_LDADD	= ../odbc/libtdsodbc.la \
++		  ../replacements/libreplacements.la \
++		  $(ODBCLIB) $(NETWORK_LIBS)
+ bsqlodbc_CPPFLAGS	= $(ODBC_INC) $(AM_CPPFLAGS)
+ endif
+ 
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 1e3c3a8..c8dc89f 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.4 2008/01/27 10:41:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.3 2008/01/13 20:39:27 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -562,7 +562,6 @@ odbc_lock_statement(TDS_STMT* stmt)
+ 		tds->query_timeout = (stmt->attr.query_timeout != DEFAULT_QUERY_TIMEOUT) ?
+ 			stmt->attr.query_timeout : stmt->dbc->default_query_timeout;
+ 	stmt->dbc->current_statement = stmt;
+-	stmt->cancel_sent = 0;
+ 	return 1;
+ }
+ 
+@@ -1583,7 +1582,6 @@ SQLCancel(SQLHSTMT hstmt)
+ 
+ 	/* FIXME test current statement */
+ 
+-	stmt->cancel_sent = 1;
+ 	if (tds_send_cancel(tds) == TDS_FAIL) {
+ 		ODBC_SAFE_ERROR(stmt);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+@@ -1594,9 +1592,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	/* only if we processed cancel reset statement */
+-	if (stmt->dbc->current_statement && stmt->dbc->current_statement == stmt && tds->state == TDS_IDLE)
+-		stmt->dbc->current_statement = NULL;
++	stmt->dbc->current_statement = NULL;
+ 
+ 	ODBC_RETURN_(stmt);
+ }
+@@ -2029,12 +2025,6 @@ odbc_errmsg_handler(const TDSCONTEXT * ctx, TDSSOCKET * tds, TDSMESSAGE * msg)
+ 		tdsdump_log(TDS_DBG_INFO1, "in timeout\n");
+ 		if (tds && (dbc = (TDS_DBC *) tds->parent) && dbc->current_statement) {
+ 			TDS_STMT *stmt = dbc->current_statement;
+-			/* cancel sent, handling interrupt */
+-			if (tds->in_cancel && stmt->cancel_sent) {
+-				stmt->cancel_sent = 0;
+-				tdsdump_log(TDS_DBG_INFO1, "returning from timeout\n");
+-				return TDS_INT_TIMEOUT;
+-			}
+ 			if (!tds->in_cancel)
+ 				odbc_errs_add(&stmt->errs, "HYT00", "Timeout expired");
+ 			stmt->errs.lastrc = SQL_ERROR;
+diff --git b/src/tds/token.c a/src/tds/token.c
+index 7b4a707..0c80a00 100644
+--- b/src/tds/token.c
++++ a/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.343.2.1 2008/01/27 10:41:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.343 2007/12/28 23:00:18 jklowden Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2238,7 +2238,7 @@ tds_process_end(TDSSOCKET * tds, int marker, int *flags_parm)
+ 	if (IS_TDSDEAD(tds))
+ 		return TDS_FAIL;
+ 
+-	return was_cancelled ? TDS_CANCELLED : TDS_SUCCEED;
++	return TDS_SUCCEED;
+ }
+ 
+ /**
+
+commit 85d6fdfb184c7048ad79253274cab05f4a70652c
+Author: freddy77 <freddy77>
+Date:   Fri Jan 25 11:05:24 2008 +0000
+
+    merged
+
+diff --git b/src/dblib/unittests/timeout.c a/src/dblib/unittests/timeout.c
+index ea1bd05..a3ef6f4 100644
+--- b/src/dblib/unittests/timeout.c
++++ a/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.3.2.2 2008/01/25 11:05:24 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.3.2.1 2008/01/23 08:50:16 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+
+commit 8b4057dfd4929f7a201865c3f2af2509285233af
+Author: freddy77 <freddy77>
+Date:   Wed Jan 23 08:50:15 2008 +0000
+
+    portability fixes for win64
+
+diff --git b/ChangeLog a/ChangeLog
+index 92f275a..5fda0d4 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,9 +1,3 @@
+-Wed Jan 23  9:48:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac include/tds_sysdep_public.h.in:
+-	* src/ctlib/unittests/cancel.c src/dblib/unittests/timeout.c:
+-	* win32/tds_sysdep_public.h win32/winlogin.c win32/winsetup.c:
+-	- backport portability fixes for win64
+-
+ Sun Jan 13 21:38:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: backported cancel error set
+ 
+@@ -60,4 +54,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.12 2008/01/23 08:50:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.11 2008/01/13 20:39:27 freddy77 Exp $
+diff --git b/configure.ac a/configure.ac
+index b8eef11..f4d877a 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.5 2008/01/23 08:50:16 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.4 2008/01/13 20:37:59 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.82RC2)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.5 $)
++AC_REVISION($Revision: 1.29.2.4 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -142,9 +142,7 @@ tds_mingw=no
+ case $host in
+ *-*-mingw*)
+ 	tds_mingw=yes
+-	if test "$host_cpu" = "x86_64"; then
+-		LIBS="-lws2_32"
+-	elif test -r /usr/lib/w32api/libwsock32.a; then
++	if test -r /usr/lib/w32api/libwsock32.a; then
+ 		LIBS="-L/usr/lib/w32api -lwsock32"
+ 	else
+ 		LIBS="-lwsock32"
+@@ -383,7 +381,7 @@ TDS_NULL_IS_ZERO
+ AC_CHECK_FUNCS([vsnprintf _vsnprintf gettimeofday \
+ nl_langinfo locale_charset setenv putenv \
+ getuid getpwuid getpwuid_r fstat alarm fork \
+-gethrtime localtime_r setitimer])
++gethrtime localtime_r])
+ OLD_LIBS="$LIBS"
+ LIBS="$LIBS $NETWORK_LIBS"
+ AC_CHECK_FUNCS([inet_ntoa_r getipnodebyaddr getipnodebyname \
+diff --git b/include/tds_sysdep_public.h.in a/include/tds_sysdep_public.h.in
+index 6e78da6..4ab78fb 100644
+--- b/include/tds_sysdep_public.h.in
++++ a/include/tds_sysdep_public.h.in
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_public_h_
+ #define _tds_sysdep_public_h_
+ 
+-/* $Id: tds_sysdep_public.h.in,v 1.11.2.1 2008/01/23 08:50:16 freddy77 Exp $ */
++/* $Id: tds_sysdep_public.h.in,v 1.11 2006/04/12 13:54:10 freddy77 Exp $ */
+ 
+ #ifdef __cplusplus
+ extern "C"
+@@ -37,11 +37,7 @@ extern "C"
+ #define tds_sysdep_int64_type __int64	/* 64-bit int */
+ #define tds_sysdep_real32_type float	/* 32-bit real */
+ #define tds_sysdep_real64_type double	/* 64-bit real */
+-#if !defined(WIN64) && !defined(_WIN64)
+-#define tds_sysdep_intptr_type int      /* 32-bit int */
+-#else
+-#define tds_sysdep_intptr_type __int64  /* 64-bit int */
+-#endif
++#define tds_sysdep_intptr_type int	/* 32-bit int */
+ #endif				/* defined(WIN32) || defined(_WIN32) || defined(__WIN32__) */
+ 
+ #ifndef tds_sysdep_int16_type
+diff --git b/src/ctlib/unittests/cancel.c a/src/ctlib/unittests/cancel.c
+index c1767ec..09f3a1a 100644
+--- b/src/ctlib/unittests/cancel.c
++++ a/src/ctlib/unittests/cancel.c
+@@ -10,10 +10,10 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cancel.c,v 1.11.2.1 2008/01/23 08:50:16 freddy77 Exp $";
++static char software_version[] = "$Id: cancel.c,v 1.11 2006/06/15 12:17:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#if defined(HAVE_ALARM) && defined(HAVE_SETITIMER)
++#ifdef HAVE_ALARM
+ 
+ /* protos */
+ int do_fetch(CS_COMMAND * cmd, int *cnt);
+diff --git b/src/dblib/unittests/timeout.c a/src/dblib/unittests/timeout.c
+index a3ef6f4..736f968 100644
+--- b/src/dblib/unittests/timeout.c
++++ a/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.3.2.1 2008/01/23 08:50:16 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.3 2007/12/04 02:06:38 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+@@ -29,7 +29,7 @@ timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char
+ 		return INT_CANCEL;
+ 		
+ 	if (dberr == SYBETIME) {
+-		fprintf(stderr, "%d timeouts received in %ld seconds, ", ++ntimeouts, (long int) (time(NULL) - start_time));
++		fprintf(stderr, "%d timeouts received in %ld seconds, ", ++ntimeouts, time(NULL) - start_time);
+ 		if (ntimeouts > max_timeouts) {
+ 			if (++ncancels > 1) {
+ 				fprintf(stderr, "could not timeout cleanly, breaking connection\n");
+@@ -73,14 +73,14 @@ timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char
+ int 
+ chkintr(DBPROCESS * dbproc)
+ {
+-	printf("in chkintr, %ld seconds elapsed\n", (long int) (time(NULL) - start_time));
++	printf("in chkintr, %ld seconds elapsed\n", time(NULL) - start_time);
+ 	return FALSE;
+ }
+ 
+ int 
+ hndlintr(DBPROCESS * dbproc)
+ {
+-	printf("in hndlintr, %ld seconds elapsed\n", (long int) (time(NULL) - start_time));
++	printf("in hndlintr, %ld seconds elapsed\n", time(NULL) - start_time);
+ 	return INT_CONTINUE;
+ }
+ 
+diff --git b/win32/tds_sysdep_public.h a/win32/tds_sysdep_public.h
+index 9d7f815..048c409 100644
+--- b/win32/tds_sysdep_public.h
++++ a/win32/tds_sysdep_public.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_public_h_
+ #define _tds_sysdep_public_h_
+ 
+-static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.5.6.1 2008/01/23 08:50:17 freddy77 Exp $";
++static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.5 2004/02/03 19:28:12 jklowden Exp $";
+ static void *no_unused_tds_sysdep_public_h_warn[] = { rcsid_tds_sysdep_public_h, no_unused_tds_sysdep_public_h_warn };
+ 
+ #ifdef __cplusplus
+@@ -34,23 +34,12 @@ extern "C"
+ #define tds_sysdep_int64_type __int64	/* 64-bit int */
+ #define tds_sysdep_real32_type float	/* 32-bit real */
+ #define tds_sysdep_real64_type double	/* 64-bit real */
+-#if !defined(WIN64) && !defined(_WIN64)
+ #define tds_sysdep_intptr_type int	/* 32-bit int */
+-#else
+-#define tds_sysdep_intptr_type __int64	/* 64-bit int */
+-#endif
+ typedef SOCKET TDS_SYS_SOCKET;
+ #ifndef TDS_IS_SOCKET_INVALID
+ #define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
+ #endif
+ 
+-#if !defined(MSDBLIB) && !defined(SYBDBLIB)
+-#define SYBDBLIB 1
+-#endif
+-#if defined(MSDBLIB) && defined(SYBDBLIB)
+-#error MSDBLIB and SYBDBLIB cannot both be defined
+-#endif
+-
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git b/win32/winlogin.c a/win32/winlogin.c
+index 9e5969d..4a2c2aa 100644
+--- b/win32/winlogin.c
++++ a/win32/winlogin.c
+@@ -88,14 +88,6 @@ get_desktop_file(const char *file)
+ 	return res;
+ }
+ 
+-#ifndef WIN64
+-#define GetWindowUserData(wnd)       GetWindowLong((wnd), GWL_USERDATA)
+-#define SetWindowUserData(wnd, data) SetWindowLong((wnd), GWL_USERDATA, (data))
+-#else
+-#define GetWindowUserData(wnd)       GetWindowLongPtr((wnd), GWLP_USERDATA)
+-#define SetWindowUserData(wnd, data) SetWindowLongPtr((wnd), GWLP_USERDATA, (data))
+-#endif
+-
+ /**
+  * Callback function for the DSN Configuration dialog 
+  * \param hDlg identifies the dialog
+@@ -115,7 +107,7 @@ LoginDlgProc(HWND hDlg, UINT message, WPARAM wParam,	/* */
+ 	case WM_INITDIALOG:
+ 		/* lParam points to the TDSCONNECTION */
+ 		connection = (TDSCONNECTION *) lParam;
+-		SetWindowUserData(hDlg, lParam);
++		SetWindowLong(hDlg, GWL_USERDATA, lParam);
+ 
+ 		/* copy info from TDSCONNECTION to the dialog */
+ 		SendDlgItemMessage(hDlg, IDC_LOGINSERVER, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&connection->server_name));
+@@ -130,7 +122,7 @@ LoginDlgProc(HWND hDlg, UINT message, WPARAM wParam,	/* */
+ 
+ 	case WM_COMMAND:
+ 		/* Dialog's user data points to TDSCONNECTION */
+-		connection = (TDSCONNECTION *) GetWindowUserData(hDlg);
++		connection = (TDSCONNECTION *) GetWindowLong(hDlg, GWL_USERDATA);
+ 
+ 		/* The wParam indicates which button was pressed */
+ 		if (LOWORD(wParam) == IDCANCEL) {
+diff --git b/win32/winsetup.c a/win32/winsetup.c
+index e33dc76..20585f0 100644
+--- b/win32/winsetup.c
++++ a/win32/winsetup.c
+@@ -192,13 +192,6 @@ validate(DSNINFO * di)
+ 	return NULL;
+ }
+ 
+-#ifndef WIN64
+-#define GetWindowUserData(wnd)       GetWindowLong((wnd), GWL_USERDATA)
+-#define SetWindowUserData(wnd, data) SetWindowLong((wnd), GWL_USERDATA, (data))
+-#else
+-#define GetWindowUserData(wnd)       GetWindowLongPtr((wnd), GWLP_USERDATA)
+-#define SetWindowUserData(wnd, data) SetWindowLongPtr((wnd), GWLP_USERDATA, (data))
+-#endif
+ 
+ /** 
+  * Callback function for the DSN Configuration dialog
+@@ -223,7 +216,7 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 	case WM_INITDIALOG:
+ 		/* lParam points to the DSNINFO */
+ 		di = (DSNINFO *) lParam;
+-		SetWindowUserData(hDlg, lParam);
++		SetWindowLong(hDlg, GWL_USERDATA, lParam);
+ 
+ 		/* Stuff legal protocol names into IDC_PROTOCOL */
+ 		for (i = 0; protocols[i]; i++) {
+@@ -243,7 +236,7 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 
+ 	case WM_COMMAND:
+ 		/* Dialog's user data points to DSNINFO */
+-		di = (DSNINFO *) GetWindowUserData(hDlg);
++		di = (DSNINFO *) GetWindowLong(hDlg, GWL_USERDATA);
+ 
+ 		/* The wParam indicates which button was pressed */
+ 		if (LOWORD(wParam) == IDCANCEL) {
+
+commit d9abbc45b533464c7d5305d8f36cbd2269d1ad73
+Author: freddy77 <freddy77>
+Date:   Sun Jan 13 20:39:27 2008 +0000
+
+    backported cancel error set
+
+diff --git b/ChangeLog a/ChangeLog
+index 5fda0d4..403a684 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Sun Jan 13 21:38:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: backported cancel error set
+-
+ Sun Jan 13 21:36:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac: add missing tests for heavy loads backport
+ 
+@@ -54,4 +51,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.11 2008/01/13 20:39:27 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.10 2008/01/13 20:37:59 freddy77 Exp $
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index c8dc89f..60c8e00 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.3 2008/01/13 20:39:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.2 2008/01/10 13:13:46 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3260,7 +3260,6 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ 		case TDS_NO_MORE_RESULTS:
+ 			return TDS_CMD_DONE;
+ 		case TDS_CANCELLED:
+-			odbc_errs_add(&stmt->errs, "HY008", NULL);
+ 		case TDS_FAIL:
+ 			return TDS_CMD_FAIL;
+ 		}
+@@ -4188,8 +4187,6 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 				continue;
+ 			case TDS_NO_MORE_RESULTS:
+ 				break;
+-			case TDS_CANCELLED:
+-				odbc_errs_add(&stmt->errs, "HY008", NULL);
+ 			default:
+ 				stmt->errs.lastrc = SQL_ERROR;
+ 				break;
+@@ -4591,7 +4588,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			int readed = cbValueMax;
+ 
+ 			/* FIXME test on destination char ??? */
+-			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && readed > 0)
++			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR /* is_char_type(nSybType) */ && readed > 0)
+ 				--readed;
+ 			if (readed > *pcbValue)
+ 				readed = *pcbValue;
+@@ -5686,9 +5683,6 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 			if (n >= varchar_pos && varchar_pos > 0)
+ 				goto redo;
+ 			break;
+-		case TDS_CANCELLED:
+-			odbc_errs_add(&stmt->errs, "HY008", NULL);
+-			break;
+ 		}
+ 		if (!tds->current_results)
+ 			break;
+
+commit ac9fc48b5f019af9b5bf4b41c8193acf821a1525
+Author: freddy77 <freddy77>
+Date:   Sun Jan 13 20:37:59 2008 +0000
+
+    Add missing tests
+
+diff --git b/ChangeLog a/ChangeLog
+index 403a684..9ce0774 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Sun Jan 13 21:36:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: add missing tests for heavy loads backport
+-
+ Sat Jan 12  1:21:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: small fix for 64bit
+ 	* src/tds/net.c: fix for heavy loads
+@@ -51,4 +48,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.10 2008/01/13 20:37:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.9 2008/01/12 00:21:39 freddy77 Exp $
+diff --git b/configure.ac a/configure.ac
+index f4d877a..d9bfaec 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.4 2008/01/13 20:37:59 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.3 2008/01/11 12:46:52 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.82RC2)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.4 $)
++AC_REVISION($Revision: 1.29.2.3 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -217,8 +217,7 @@ AC_CHECK_MEMBERS([struct tm.__tm_zone],,,[#include <sys/types.h>
+ #include <$ac_cv_struct_tm>
+ ])
+ AC_CHECK_HEADERS([unistd.h errno.h wchar.h sys/time.h sys/types.h \
+-sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h \
+-signal.h libgen.h poll.h])
++sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h signal.h libgen.h])
+ if test $tds_mingw = no; then
+ 	AC_CHECK_HEADERS([sys/socket.h arpa/inet.h netdb.h netinet/in.h \
+ netinet/tcp.h paths.h sys/ioctl.h langinfo.h])
+@@ -385,7 +384,7 @@ gethrtime localtime_r])
+ OLD_LIBS="$LIBS"
+ LIBS="$LIBS $NETWORK_LIBS"
+ AC_CHECK_FUNCS([inet_ntoa_r getipnodebyaddr getipnodebyname \
+-getaddrinfo getnameinfo inet_ntop gethostname poll])
++getaddrinfo getnameinfo inet_ntop gethostname])
+ LIBS="$OLD_LIBS"
+ AC_REPLACE_FUNCS([asprintf vasprintf atoll strtok_r readpassphrase \
+ strlcpy strlcat basename])
+
+commit 606c262bc5a4513a67789f3186207869c6ba2c6b
+Author: freddy77 <freddy77>
+Date:   Sun Jan 13 20:36:05 2008 +0000
+
+    update version
+
+diff --git b/misc/freetds_autobuild a/misc/freetds_autobuild
+index a78d6f4..7217a27 100755
+--- b/misc/freetds_autobuild
++++ a/misc/freetds_autobuild
+@@ -9,7 +9,7 @@ export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:$HOME
+ 
+ GROUPDIR=/home/groups/f/fr/freetds/htdocs
+ # directory to compile
+-FTDSDIR=freetds82
++FTDSDIR=freetds65
+ # output directory on server
+ OUTDIR=out
+ # additional flags for Autogen (current version)
+
+commit 09c5cdaf1cc430a40dd58b9915f769953e92cdbf
+Author: freddy77 <freddy77>
+Date:   Sat Jan 12 00:21:39 2008 +0000
+
+    fix for heavy load on server
+
+diff --git b/ChangeLog a/ChangeLog
+index 9ce0774..5cd7d29 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,7 +1,3 @@
+-Sat Jan 12  1:21:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/blob1.c: small fix for 64bit
+-	* src/tds/net.c: fix for heavy loads
+-
+ Fri Jan 11 13:46:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/apps/tsql.c: backport fix for MacOSX
+ 
+@@ -48,4 +44,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.9 2008/01/12 00:21:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.8 2008/01/11 12:46:52 freddy77 Exp $
+diff --git b/src/odbc/unittests/blob1.c a/src/odbc/unittests/blob1.c
+index e5d0344..0ac14c0 100755
+--- b/src/odbc/unittests/blob1.c
++++ a/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.1.2.5 2008/01/12 00:21:39 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.1.2.4 2008/01/11 12:44:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -101,11 +101,11 @@ main(int argc, char **argv)
+ 	int i;
+ 
+ 	int key;
+-	SQLLEN vind0;
++	SQLINTEGER vind0;
+ 	char buf1[NBYTES];
+-	SQLLEN vind1;
++	SQLINTEGER vind1;
+ 	char buf2[NBYTES];
+-	SQLLEN vind2;
++	SQLINTEGER vind2;
+ 	int cnt = 2;
+ 
+ 	use_odbc_version3 = 1;
+diff --git b/src/tds/net.c a/src/tds/net.c
+index 62c0705..c551127 100644
+--- b/src/tds/net.c
++++ a/src/tds/net.c
+@@ -82,10 +82,6 @@
+ #include <sys/select.h>
+ #endif /* HAVE_SELECT_H */
+ 
+-#if HAVE_POLL_H
+-#include <poll.h>
+-#endif /* HAVE_POLL_H */
+-
+ #include "tds.h"
+ #include "tdsstring.h"
+ #include "replacements.h"
+@@ -103,23 +99,9 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.71.2.1 2008/01/12 00:21:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.71 2007/12/12 06:27:38 freddy77 Exp $");
+ 
+-#undef USE_POLL
+-#if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+-# define USE_POLL 1
+-# define TDSSELREAD  POLLIN
+-# define TDSSELWRITE POLLOUT
+-/* error is always returned */
+-# define TDSSELERR   0
+-#else
+-# define USE_POLL 0
+-# define TDSSELREAD  1
+-# define TDSSELWRITE 2
+-# define TDSSELERR   4
+-#endif
+-
+-static int tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
++static int tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout_seconds);
+ 
+ 
+ /**
+@@ -261,6 +243,8 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	if (retval == 0) {
+ 		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
+ 	} else {
++		fd_set fds;
++
+ 		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", strerror(sock_errno));
+ #if DEBUGGING_CONNECTING_PROBLEM
+ 		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != EINPROGRESS) {
+@@ -280,7 +264,8 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 		if (sock_errno != TDSSOCK_EINPROGRESS)
+ 			goto not_available;
+ 		
+-		if (tds_select(tds, TDSSELWRITE|TDSSELERR, timeout) <= 0) {
++		FD_ZERO(&fds);
++		if (tds_select(tds, NULL, &fds, &fds, timeout) <= 0) {
+ 			tds_error = TDSESOCK;
+ 			goto not_available;
+ 		}
+@@ -335,39 +320,13 @@ tds_close_socket(TDSSOCKET * tds)
+  * This function does not call tdserror or close the socket because it can't know the context in which it's being called.   
+  */
+ static int
+-tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
++tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout_seconds)
+ {
+ 	int rc, seconds;
+ 	unsigned int poll_seconds;
+-#if !USE_POLL
+-	fd_set fds[3];
+-	fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
+-#endif
+ 
+ 	assert(tds != NULL);
+ 	assert(timeout_seconds >= 0);
+-
+-#if !USE_POLL
+-#if !defined(WIN32) && defined(FD_SETSIZE)
+-	if (tds->s >= FD_SETSIZE) {
+-		sock_errno = EINVAL;
+-		return -1;
+-	}
+-#endif
+-	if ((tds_sel & TDSSELREAD) != 0) {
+-		FD_ZERO(&fds[0]);
+-		readfds = &fds[0];
+-	}
+-	if ((tds_sel & TDSSELWRITE) != 0) {
+-		FD_ZERO(&fds[1]);
+-		writefds = &fds[1];
+-	}
+-	if ((tds_sel & TDSSELERR) != 0) {
+-		FD_ZERO(&fds[2]);
+-		exceptfds = &fds[2];
+-	}
+-#endif
+-
+ 	/* 
+ 	 * The select loop.  
+ 	 * If an interrupt handler is installed, we iterate once per second, 
+@@ -385,16 +344,8 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 	 */
+ 	poll_seconds = (tds->tds_ctx && tds->tds_ctx->int_handler)? 1 : timeout_seconds;
+ 	for (seconds = timeout_seconds; timeout_seconds == 0 || seconds > 0; seconds -= poll_seconds) {
+-#if USE_POLL
+-		struct pollfd fd;
+-		int timeout = poll_seconds ? poll_seconds * 1000 : -1;
+-
+-		fd.fd = tds->s;
+-		fd.events = tds_sel;
+-		fd.revents = 0;
+-		rc = poll(&fd, 1, timeout);
+-#else
+ 		struct timeval tv, *ptv = poll_seconds? &tv : NULL;
++		
+ 		tv.tv_sec = poll_seconds;
+ 		tv.tv_usec = 0; 
+ 
+@@ -406,7 +357,6 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 			FD_SET(tds->s, exceptfds);
+ 
+ 		rc = select(tds->s + 1, readfds, writefds, exceptfds, ptv); 
+-#endif
+ 
+ 		if (rc > 0 ) {
+ 			return rc;
+@@ -471,6 +421,7 @@ static int
+ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfinished)
+ {
+ 	int rc, got = 0;
++	fd_set rfds;
+ 
+ 	if (buf == NULL || buflen < 1 || tds == NULL)
+ 		return 0;
+@@ -481,19 +432,23 @@ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfi
+ 		if (IS_TDSDEAD(tds))
+ 			return -1;
+ 
+-		if ((len = tds_select(tds, TDSSELREAD, tds->query_timeout)) > 0) {
++		FD_ZERO(&rfds);
++		if ((len = tds_select(tds, &rfds, NULL, NULL, tds->query_timeout)) > 0) {
++			len = 0;
++			if (FD_ISSET(tds->s, &rfds)) {
+ #ifndef MSG_NOSIGNAL
+-			len = READSOCKET(tds->s, buf + got, buflen);
++				len = READSOCKET(tds->s, buf + got, buflen);
+ #else
+-			len = recv(tds->s, buf + got, buflen, MSG_NOSIGNAL);
++				len = recv(tds->s, buf + got, buflen, MSG_NOSIGNAL);
+ #endif
+-			if (len < 0 && sock_errno == EAGAIN)
+-				continue;
+-			/* detect connection close */
+-			if (len <= 0) {
+-				tdserror(tds->tds_ctx, tds, len == 0 ? TDSESEOF : TDSEREAD, sock_errno);
+-				tds_close_socket(tds);
+-				return -1;
++				if (len < 0 && sock_errno == EAGAIN)
++					continue;
++				/* detect connection close */
++				if (len <= 0) {
++					tdserror(tds->tds_ctx, tds, len == 0 ? TDSESEOF : TDSEREAD, sock_errno);
++					tds_close_socket(tds);
++					return -1;
++ 				}
+ 			}
+ 		} else if (len < 0) {
+ 			if (sock_errno == EAGAIN) /* shouldn't happen, but OK */
+@@ -685,30 +640,35 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *p, int len, unsigned char la
+ {
+ 	int remaining = len;
+ 	int nput, rc, err=0;
++	fd_set fds;
+ 
+ 	/* Fix of SIGSEGV when FD_SET() called with negative fd (Sergey A. Cherukhin, 23/09/2005) */
+ 	if (TDS_IS_SOCKET_INVALID(tds->s))
+ 		return -1;
+ 
+ 	while (remaining > 0) {
+-		if ((rc = tds_select(tds, TDSSELWRITE, tds->query_timeout)) > 0) {
++		FD_ZERO(&fds);
++		if ((rc = tds_select(tds, NULL, &fds, NULL, tds->query_timeout)) > 0) {
++			nput = 0;
++			if (FD_ISSET(tds->s, &fds)) {
+ #ifdef USE_MSGMORE
+-			nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
+-			/* In case the kernel does not support MSG_MORE, try again without it */
+-			if (nput < 0 && errno == EINVAL && !last)
+-				nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
++				nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
++				/* In case the kernel does not support MSG_MORE, try again without it */
++				if (nput < 0 && errno == EINVAL && !last)
++					nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
+ #elif !defined(MSG_NOSIGNAL)
+-			nput = WRITESOCKET(tds->s, p, remaining);
++				nput = WRITESOCKET(tds->s, p, remaining);
+ #else
+-			nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
++				nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
+ #endif
+-			if (nput < 0 && sock_errno == EAGAIN)
+-				continue;
+-			/* detect connection close */
+-			if (nput <= 0) {
+-				tdserror(tds->tds_ctx, tds, nput == 0 ? TDSESEOF : TDSEWRIT, sock_errno);
+-				tds_close_socket(tds);
+-				return -1;
++				if (nput < 0 && sock_errno == EAGAIN)
++					continue;
++				/* detect connection close */
++				if (nput <= 0) {
++					tdserror(tds->tds_ctx, tds, nput == 0 ? TDSESEOF : TDSEWRIT, sock_errno);
++					tds_close_socket(tds);
++					return -1;
++ 				}
+ 			}
+ 		} else if (rc < 0) {
+ 			if (sock_errno == EAGAIN) /* shouldn't happen, but OK, retry */
+@@ -821,12 +781,8 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 	int num_try;
+ 	struct sockaddr_in sin;
+ 	ioctl_nonblocking_t ioctl_nonblocking;
+-#if USE_POLL
+-	struct pollfd fd;
+-#else
+ 	struct timeval selecttimeout;
+ 	fd_set fds;
+-#endif
+ 	int retval;
+ 	TDS_SYS_SOCKET s;
+ 	char msg[1024];
+@@ -850,15 +806,6 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		return 0;
+ 	}
+ 
+-#if !USE_POLL
+-#if !defined(WIN32) && defined(FD_SETSIZE)
+-	if (s >= FD_SETSIZE) {
+-		sock_errno = EINVAL;
+-		return 0;
+-	}
+-#endif
+-#endif
+-
+ 	/*
+ 	 * on cluster environment is possible that reply packet came from
+ 	 * different IP so do not filter by ip with connect
+@@ -881,20 +828,12 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		tds_strlcpy(msg + 1, instance, sizeof(msg) - 1);
+ 		sendto(s, msg, strlen(msg) + 1, 0, (struct sockaddr *) &sin, sizeof(sin));
+ 
+-#if USE_POLL
+-		fd.fd = s;
+-		fd.events = POLLIN;
+-		fd.revents = 0;
+-
+-		retval = poll(&fd, 1, 1000);
+-#else
+ 		FD_ZERO(&fds);
+ 		FD_SET(s, &fds);
+ 		selecttimeout.tv_sec = 1;
+ 		selecttimeout.tv_usec = 0;
+ 		
+ 		retval = select(s + 1, &fds, NULL, NULL, &selecttimeout);
+-#endif
+ 		
+ 		/* on interrupt ignore */
+ 		if (retval < 0 && sock_errno == TDSSOCK_EINTR)
+
+commit 385bf5239dbd89559c437b8a7252ee88ba9b4a5f
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 12:46:52 2008 +0000
+
+    backport fix for MacOSX
+
+diff --git b/ChangeLog a/ChangeLog
+index 5cd7d29..851bd0f 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Fri Jan 11 13:46:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/apps/tsql.c: backport fix for MacOSX
+-
+ Fri Jan 11 13:43:08 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: backport fix for Sybase
+ 
+@@ -44,4 +41,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.8 2008/01/11 12:46:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.7 2008/01/11 12:44:39 freddy77 Exp $
+diff --git b/configure.ac a/configure.ac
+index d9bfaec..1b9cc43 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.3 2008/01/11 12:46:52 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.2 2008/01/11 06:48:38 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.82RC2)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.3 $)
++AC_REVISION($Revision: 1.29.2.2 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -178,24 +178,7 @@ if test $tds_mingw = no; then
+ 	AC_CHECK_LIB([readline], [readline], [LIBS="$LIBS -lreadline"
+ 	  AC_DEFINE(HAVE_READLINE, 1, [Define to 1 if you have the GNU Readline library.])], [LIBS=""] )
+ 	AC_CHECK_FUNCS([rl_on_new_line rl_reset_line_state])
+-	AC_LINK_IFELSE([AC_LANG_SOURCE([[
+ 
+-#include <stdio.h>
+-#ifdef HAVE_STDLIB_H
+-#include <stdlib.h>
+-#endif
+-
+-#ifdef HAVE_READLINE
+-#include <readline/readline.h>
+-#include <readline/history.h>
+-#endif /* HAVE_READLINE */
+-
+-int main()
+-{
+-	rl_inhibit_completion = 1;
+-	return 0;
+-}
+-]])],AC_DEFINE(HAVE_RL_INHIBIT_COMPLETION, 1, [Define to 1 if you have rl_inhibit_completion.]))
+ 	READLINE_LIBS="$LIBS"
+ 	LIBS="$OLDLIBS"
+ 	AC_SUBST(READLINE_LIBS)
+diff --git b/src/apps/tsql.c a/src/apps/tsql.c
+index 2081212..6a04027 100644
+--- b/src/apps/tsql.c
++++ a/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.112.2.1 2008/01/11 12:46:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.112 2007/12/23 21:12:02 jklowden Exp $");
+ 
+ enum
+ {
+@@ -683,7 +683,7 @@ main(int argc, char **argv)
+ 	mybuf[0] = '\0';
+ 	buflen = 0;
+ 
+-#if defined(HAVE_READLINE) && HAVE_RL_INHIBIT_COMPLETION
++#ifdef HAVE_READLINE
+ 	rl_inhibit_completion = 1;
+ #endif
+ 
+
+commit 9c10c557cb4e0955466b37dd61879563ef447c99
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 12:44:39 2008 +0000
+
+    backported fix for Sybase
+
+diff --git b/ChangeLog a/ChangeLog
+index 851bd0f..c9b46cc 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Fri Jan 11 13:43:08 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/blob1.c: backport fix for Sybase
+-
+ Fri Jan 11  9:32:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c src/odbc/unittests/cursor3.c:
+ 	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
+@@ -41,4 +38,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.7 2008/01/11 12:44:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.6 2008/01/11 08:33:18 freddy77 Exp $
+diff --git b/src/odbc/unittests/blob1.c a/src/odbc/unittests/blob1.c
+index 0ac14c0..dfa8319 100755
+--- b/src/odbc/unittests/blob1.c
++++ a/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.1.2.4 2008/01/11 12:44:39 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.1.2.3 2008/01/11 08:33:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -167,7 +167,7 @@ main(int argc, char **argv)
+ 
+ 	}
+ 
+-	/* Now fetch rows ... */
++	/* No fetch rows ... */
+ 
+ 	for (i = 0; i < cnt; i++) {
+ 
+@@ -175,12 +175,10 @@ main(int argc, char **argv)
+ 		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ 		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+ 
+-		if (db_is_microsoft()) {
+-			rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-			rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+-		}
++		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
++		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ 
+ 		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+
+commit f42f2399b3c5dd1e67f36dda7702be5b81310ca8
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 08:33:18 2008 +0000
+
+    merged changes for tests
+
+diff --git b/ChangeLog a/ChangeLog
+index c9b46cc..30783d8 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,9 +1,3 @@
+-Fri Jan 11  9:32:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/blob1.c src/odbc/unittests/cursor3.c:
+-	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
+-	* src/odbc/unittests/hidden.c:
+-	- merged changes for tests
+-
+ Fri Jan 11  7:48:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac: avoid clash
+ 
+@@ -38,4 +32,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.6 2008/01/11 08:33:18 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.5 2008/01/11 06:48:37 freddy77 Exp $
+diff --git b/src/odbc/unittests/blob1.c a/src/odbc/unittests/blob1.c
+index dfa8319..b8c45b0 100755
+--- b/src/odbc/unittests/blob1.c
++++ a/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.1.2.3 2008/01/11 08:33:18 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.1.2.2 2008/01/10 13:13:46 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -111,7 +111,8 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b IMAGE, v INT )");
++	Command(Statement, "IF OBJECT_ID('tt') IS NOT NULL DROP TABLE tt");
++	Command(Statement, "CREATE TABLE tt ( k INT, t TEXT, b IMAGE, v INT )");
+ 
+ 	/* Insert rows ... */
+ 
+@@ -121,7 +122,7 @@ main(int argc, char **argv)
+ 		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ 		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ? )", SQL_NTS);
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "insert into tt values ( ?, ?, ?, ? )", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+ 
+ 		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+@@ -180,7 +181,7 @@ main(int argc, char **argv)
+ 		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM tt WHERE k = ?", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+ 
+ 		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+diff --git b/src/odbc/unittests/cursor3.c a/src/odbc/unittests/cursor3.c
+index 18c2f1d..791783a 100644
+--- b/src/odbc/unittests/cursor3.c
++++ a/src/odbc/unittests/cursor3.c
+@@ -1,7 +1,7 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.3.2.1 2008/01/11 08:33:18 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.3 2007/12/21 10:39:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLHDBC m_hdbc;
+@@ -69,11 +69,12 @@ main(int argc, char **argv)
+ 
+ 	m_hdbc = Connection;
+ 
+-	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (2, 'bbbbb')");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (3, 'ccccccccc')");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (4, 'dd')");
++	exec_direct(0, "DROP TABLE t1");
++	exec_direct(1, "CREATE TABLE t1 ( k INT, c VARCHAR(20))");
++	exec_direct(1, "INSERT INTO t1 VALUES (1, 'aaa')");
++	exec_direct(1, "INSERT INTO t1 VALUES (2, 'bbbbb')");
++	exec_direct(1, "INSERT INTO t1 VALUES (3, 'ccccccccc')");
++	exec_direct(1, "INSERT INTO t1 VALUES (4, 'dd')");
+ 
+ 	m_hstmt1 = NULL;
+ 	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+@@ -113,10 +114,10 @@ main(int argc, char **argv)
+ 	rcode = SQLSetCursorName(m_hstmt2, (SQLCHAR *) "c2", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SetCursorName c2");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM t1", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Prepare 1");
+ 
+-	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "SELECT * FROM t1", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "Prepare 2");
+ 
+ 	rcode = SQLExecute(m_hstmt1);
+@@ -151,6 +152,8 @@ main(int argc, char **argv)
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLFreeHandle 2");
+ 
++	exec_direct(1, "DROP TABLE t1");
++
+ 	Disconnect();
+ 
+ 	return 0;
+diff --git b/src/odbc/unittests/cursor4.c a/src/odbc/unittests/cursor4.c
+index 58c249d..b352644 100755
+--- b/src/odbc/unittests/cursor4.c
++++ a/src/odbc/unittests/cursor4.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.3.2.1 2008/01/11 08:33:18 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.3 2007/12/21 10:39:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLHDBC m_hdbc;
+@@ -72,8 +72,9 @@ main(int argc, char **argv)
+ 
+ 	m_hdbc = Connection;
+ 
+-	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
++	exec_direct(0, "DROP TABLE t1");
++	exec_direct(1, "CREATE TABLE t1 ( k INT, c VARCHAR(20))");
++	exec_direct(1, "INSERT INTO t1 VALUES (1, 'aaa')");
+ 
+ 	m_hstmt1 = NULL;
+ 	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+@@ -85,7 +86,7 @@ main(int argc, char **argv)
+ 	rcode = SQLSetCursorName(m_hstmt1, (SQLCHAR *) "c112", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SetCursorName c112");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1 FOR UPDATE", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM t1 FOR UPDATE", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Prepare 2");
+ 
+ 	exec_direct(1, "BEGIN TRANSACTION");
+@@ -96,14 +97,14 @@ main(int argc, char **argv)
+ 	rcode = SQLFetch(m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFetch 1");
+ 
+-	exec_direct(1, "UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");
++	exec_direct(1, "UPDATE t1 SET c = 'xxx' WHERE CURRENT OF c112");
+ 
+ 	rcode = SQLCloseCursor(m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLCloseCursor 2");
+ 
+ 	exec_direct(1, "COMMIT TRANSACTION");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c FROM #t1 WHERE k = 1", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c FROM t1 WHERE k = 1", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 2");
+ 
+ 	rcode = SQLFetch(m_hstmt1);
+@@ -117,6 +118,8 @@ main(int argc, char **argv)
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle 1");
+ 
++	exec_direct(1, "DROP TABLE t1");
++
+ 	Disconnect();
+ 
+ 	return 0;
+diff --git b/src/odbc/unittests/cursor5.c a/src/odbc/unittests/cursor5.c
+index 5e73dc6..c7be7e4 100755
+--- b/src/odbc/unittests/cursor5.c
++++ a/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.2.2.1 2008/01/11 08:33:18 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.2 2007/12/21 10:39:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -76,14 +76,15 @@ main(int argc, char **argv)
+ 	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle StmtH 2");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "create table #mytab1 (k int, c char(30))", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "drop table mytab1", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "create table mytab1 (k int, c char(30))", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.1");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (1,'aaa')", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into mytab1 values (1,'aaa')", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.2");
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (2,'bbb')", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into mytab1 values (2,'bbb')", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.3");
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (3,'ccc')", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into mytab1 values (3,'ccc')", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.4");
+ 
+ /*
+@@ -94,7 +95,7 @@ main(int argc, char **argv)
+ 	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLSetStmtAttr 1");
+ 
+-	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "select k, c from #mytab1 order by k", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "select k, c from mytab1 order by k", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLPrepare 3");
+ 
+ 	rcode = SQLBindCol(m_hstmt2, 1, SQL_C_LONG, &v_int_3, 0, &v_ind_3_1);
+@@ -125,6 +126,9 @@ main(int argc, char **argv)
+ 	rcode = SQLCloseCursor(m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLCloseCursor StmtH 2");
+ 
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "drop table mytab1", SQL_NTS);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.3");
++
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle StmtH 1");
+ 
+diff --git b/src/odbc/unittests/hidden.c a/src/odbc/unittests/hidden.c
+index ad75433..66be442 100755
+--- b/src/odbc/unittests/hidden.c
++++ a/src/odbc/unittests/hidden.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.1.2.2 2008/01/11 08:33:18 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.1.2.1 2008/01/10 08:52:46 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -70,7 +70,6 @@ main(int argc, char **argv)
+ 
+ 	/* test hidden column with cursors*/
+ 	CheckCursor();
+-	m_hstmt1 = Statement;
+ 
+ 	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+
+commit 4e976741808d4e336d864d45da07626ae502ce69
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 06:48:37 2008 +0000
+
+    avoid version clash
+
+diff --git b/ChangeLog a/ChangeLog
+index 30783d8..fbe59e4 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Fri Jan 11  7:48:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: avoid clash
+-
+ Thu Jan 10 15:55:32 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* INSTALL.CVS NEWS README TODO ChangeLog-0.82
+ 	* ChangeLog doc/userguide.sgml documentation updates
+@@ -32,4 +29,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2454.2.5 2008/01/11 06:48:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2454.2.4 2008/01/10 20:58:42 jklowden Exp $
+diff --git b/configure.ac a/configure.ac
+index 1b9cc43..d2d0fed 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.2 2008/01/11 06:48:38 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29.2.1 2008/01/09 06:50:55 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.82RC2)
++AC_INIT(FreeTDS, 0.82RC1)
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.2 $)
++AC_REVISION($Revision: 1.29.2.1 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+
+commit ea5b7edd6dbc01f152e91e23bf80070355bfe0dc
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 20:58:42 2008 +0000
+
+    documentation updates
+
+diff --git b/ChangeLog a/ChangeLog
+index fbe59e4..d054e6f 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,32 +1,49 @@
+-Thu Jan 10 15:55:32 EST 2008	JK Lowden <jklowden@freetds.org>
+-	* INSTALL.CVS NEWS README TODO ChangeLog-0.82
+-	* ChangeLog doc/userguide.sgml documentation updates
+-
+-Thu Jan 10 17:04:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/cancel.c(added):
+-	- add test for SQLCancel
+-
+-Thu Jan 10 16:28:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/blob1.c src/odbc/unittests/cursor3.c:
+-	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
+-	- use temporary tables
+-
+-Thu Jan 10 16:25:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/README.releasing misc/freetds_autobuild: updates
+-
+-Thu Jan 10 14:10:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Thu Jan 10 14:12:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/blob1.c(added):
+ 	- fix problem with SQLGetData and blobs
+ 
+-Thu Jan 10 09:46:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Thu Jan 10 09:51:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am:
+ 	- small fix for hidden fields (ignore them entirely)
+ 
+-Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+-	* ChangeLog  truncated because of release
+-	* ChangeLog-0.82 added because of release
+-	
+-$Id: ChangeLog,v 1.2454.2.4 2008/01/10 20:58:42 jklowden Exp $
++Wed Jan  9  7:50:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac: preparing 0.82
++
++Tue Jan  8 10:31:43 EST 2008	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am added freetds.conf.5
++	* src/dblib/bcp.c applied BCPKEEPIDENTIY patch from [email]
++
++Tue Jan  8 14:28:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS doc/README.releasing doc/userguide.sgml:
++	- updates for new release
++
++Tue Jan  8 10:33:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: relax for no-dm
++
++Mon Jan  7 19:32:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
++	- fix millisecond round off for TIMESTAMP
++	- improve genparams test to catch this problem
++	- make genparams works with MS ODBC
++
++Mon Jan  7 15:04:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdssrv.h src/server/login.c src/server/server.c:
++	* src/server/unittest.c:
++	- small improves
++	* src/pool/user.c: style update
++
++Sun Jan  6 11:48:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: even SQLExecDirect support parameters!
++	* src/odbc/unittests/genparams.c: improve
++
++Sat Jan  5 12:23:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c:
++	- add parameterized flag calling sp_cursoropen if needed
++
++Wed Jan  2 00:08:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/apps/Makefile.am:
++	- remove GNU style
++	* src/dblib/dblib.c: make it compile
++
+diff --git b/ChangeLog-0.82 a/ChangeLog-0.82
+deleted file mode 100644
+index cc4cbea..0000000
+--- b/ChangeLog-0.82
++++ /dev/null
+@@ -1,2289 +0,0 @@
+-Tue Jan  8 10:31:43 EST 2008	JK Lowden <jklowden@freetds.org>
+-	* doc/Makefile.am added freetds.conf.5
+-	* src/dblib/bcp.c applied BCPKEEPIDENTIY patch 
+-	- from Jonathan Olson <jpolsonaz@mac.com>
+-
+-Tue Jan  8 14:28:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* NEWS doc/README.releasing doc/userguide.sgml:
+-	- updates for new release
+-
+-Tue Jan  8 10:33:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/genparams.c: relax for no-dm
+-
+-Mon Jan  7 19:32:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
+-	- fix millisecond round off for TIMESTAMP
+-	- improve genparams test to catch this problem
+-	- make genparams works with MS ODBC
+-
+-Mon Jan  7 15:04:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdssrv.h src/server/login.c src/server/server.c:
+-	* src/server/unittest.c:
+-	- small improves
+-	* src/pool/user.c: style update
+-
+-Sun Jan  6 11:48:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: even SQLExecDirect support parameters!
+-	* src/odbc/unittests/genparams.c: improve
+-
+-Sat Jan  5 12:23:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/query.c:
+-	- add parameterized flag calling sp_cursoropen if needed
+-
+-Wed Jan  2 00:08:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/apps/Makefile.am:
+-	- remove GNU style
+-	* src/dblib/dblib.c: make it compile
+-
+-
+-Mon Dec 31 15:05:16 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/dblib.c fixed DBPRPAD, maybe
+-
+-Mon Dec 31 11:29:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/test-other.sh src/odbc/odbc.c:
+-	- relax test for cursor
+-
+-Mon Dec 31 11:06:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/blk.c src/odbc/unittests/attributes.c:
+-	* src/odbc/unittests/describecol.c src/tds/convert.c:
+-	* src/tds/login.c src/tds/mem.c:
+-	- minor signed/unsigned fixes
+-	* src/dblib/bcp.c: minor performance improve
+-	* src/dblib/dblib.c: fix date portability
+-
+-Fri Dec 28 17:57:08 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/tds/token.c minor change
+-	* src/tds/convert.c simpler tds_strftime
+-	* src/dblib/unittests/done_handling.c no spurious messages
+-
+-Wed Dec 28 15:11:48 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/userguide.sgml: accepted patch #1854381
+-
+-Wed Dec 28 14:44:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/freetds_autobuild misc/test-other.sh:
+-	- make amd64 works
+-	* misc/test-auto.sh: add --help option
+-	* src/tds/convert.c:
+-	- fix overflow in tds_convert_char
+-	- minor fixes for tds_strftime
+-
+-Thu Dec 27 14:43:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/.cvsignore: ignore autogenerated
+-	* include/tds.h src/replacements/vasprintf.c src/tds/convert.c:
+-	* src/tds/login.c src/tds/query.c src/tds/read.c:
+-	- remove some warnings
+-
+-Thu Dec 27 11:20:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/common.c: make unixODBC happy
+-	* win32/config.h: define TDS_I64_FORMAT
+-
+-Thu Dec 27 10:19:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/buffering.h:
+-	- remove warning if compiled with NDEBUG defined
+-
+-Wed Dec 26 21:57:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/attributes.c: make it works
+-
+-Wed Dec 26 19:44:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/freetds.conf.5: typo fix
+-	* src/ctlib/unittests/common.c: make tests compile
+-	* src/odbc/odbc.c: add diagnostic for truncate
+-
+-Tue Dec 25 00:55:02 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* freetds.conf doc/Makefile.am doc/freetds.conf.5 (added)
+-	- shortened default freetds.conf and moved documentation
+-	- to a proper man page.  Merry Christmas! 
+-
+-Mon Dec 24 11:34:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h: removed unused fields
+-
+-Sun Dec 23 16:08:29 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/tsql.c 
+-	* src/ctlib/cs.c src/ctlib/unittests/common.c
+-	* src/dblib/dblib.c
+-	* src/tds/config.c src/tds/unittests/convert.c
+-	- added STD_DATETIME_FMT to allow for WIN32 shortcomings
+-
+-Fri Dec 21 16:20:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/ctlib/ct.c src/odbc/odbc.c src/tds/query.c:
+-	- make odbc cursor test work using sp_cursoropen with parameters
+-
+-Fri Dec 21 11:38:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
+-	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
+-	* src/odbc/unittests/cursor5.c:
+-	- cursor tests should work
+-
+-Fri Dec 21 10:05:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac include/replacements.h src/replacements/vasprintf.c:
+-	* win32/config.h:
+-	- applied modified patch #1848920
+-
+-Thu Dec 20 22:56:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c src/dblib/unittests/common.h:
+-	* src/dblib/unittests/setnull.c src/dblib/unittests/thread.c:
+-	- remove warnings
+-
+-Thu Dec 20 17:46:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c:
+-	- improve cursor attribute setting
+-	- fix a small issue with unixODBC and 64 bit
+-
+-Wed Dec 19 16:08:17 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
+-	- remove warnings
+-
+-Wed Dec 19 15:35:22 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/attributes.c(added) src/odbc/unittests/attributes.in(added):
+-	* src/odbc/unittests/Makefile.am: add a test for statement attributes
+-	* src/odbc/unittests/describecol.c: fix possible core
+-
+-Tue Dec 18 09:09:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/cursor3.c(added):
+-	* src/odbc/unittests/cursor4.c(added) src/odbc/unittests/cursor5.c(added):
+-	- merged test from Sebastien FLAESCH
+-
+-Sun Dec 16 19:08:38 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/api_status.txt 
+-	- set useless db-lib functions' status to 'never'
+-
+-Sun Dec 16 16:58:35 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/Makefile.am doc/bsqlodbc.txt doc/osql.txt
+-	* doc/userguide.sgml
+-	- updated for next release
+-
+-Fri Dec 14 11:23:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/test-other.sh: fix some strange echo portability
+-	* src/dblib/unittests/null.c src/dblib/unittests/null2.c:
+-	- make ignore less verbose
+-
+-Thu Dec 13 23:45:55 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/Makefile.am build bsqlodbc out-of-tree
+-	* src/dblib/unittests/null.c prettier & correct, passes
+-
+-Thu Dec 13 21:12:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/buffering.h: fix null2
+-
+-Thu Dec 13 19:04:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/Makefile.am:
+-	- fix bsqlodbc compile if not standard sql.h path
+-
+-Wed Dec 12 07:27:07 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c: fix for 64bit
+-
+-Tue Dec 11 11:09:52 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/userguide.sgml: remove warning
+-	* misc/freetds_autobuild: fix if password empty
+-
+-Tue Dec 11 00:02:16 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/userguide.sgml minor touchups 
+-	* src/dblib/dblib.c src/dblib/unittests/setnull.c
+-	- unittests/setnull.c passes.
+-
+-Mon Dec 10 14:05:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/convert.c: remove warning
+-
+-Mon Dec 10 00:08:45 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/Makefile.am doc/userguide.sgml some improvements
+-	doc/grep_sample_code doc/images/caution.gif 
+-	doc/images/warning.gif
+-	doc/images/callouts/1.gif doc/images/callouts/2.gif
+-	doc/images/callouts/3.gif doc/images/callouts/4.gif
+-	doc/images/callouts/5.gif doc/images/callouts/6.gif
+-	doc/images/callouts/7.gif doc/images/callouts/8.gif
+-	doc/images/callouts/9.gif doc/images/callouts/10.gif
+-	- added from http://tldp.org/LDP/abs/images/
+-
+-Sun Dec  9 19:51:11 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/userguide.sgml added tenderfoot tutorial
+-
+-Fri Dec  7 00:26:01 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/tds.h src/dblib/dblib.c
+-	* src/dblib/dbutil.c src/tds/util.c
+-	- pass errno via tdserror.  
+-
+-Thu Dec  6 21:41:23 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/tds/convert.c tds_willconvert returns size
+-
+-Thu Dec  6 21:32:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c: fix for 64bit machines
+-	* src/dblib/unittests/setnull.c: improve
+-
+-Thu Dec  6 19:59:59 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac include/replacements.h src/apps/bsqldb.c:
+-	* src/dblib/unittests/setnull.c:
+-	- use basename from MingW if available
+-	* src/dblib/dblib.c: fix malloc portability problem
+-
+-Thu Dec  6 10:18:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/rpc.c src/dblib/unittests/setnull.c:
+-	- fix compile problems
+-
+-Thu Dec  6 01:00:42 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/buffering.h src/dblib/dblib.c:
+-	- dbgetnull tolerates negative varlen, looks pretty good
+-
+-Wed Dec  5 10:38:55 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/dblib.c:
+-	- t0011 passes but copy_data_to_host_var likely wrong
+-
+-Tue Dec  4 20:19:38 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/dblib.h src/dblib/buffering.h src/dblib/dblib.c:
+-	- removed _db_set_null and associated mallocs
+-	- dblib/unittest/t0011.c failing mysteriously
+-
+-Mon Dec  3 23:18:55 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/dblib.c src/dblib/unittests/setnull.c:
+-	- corrected dbsetnull()
+-
+-Mon Dec  3 18:45:22 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/bsqldb.c
+-	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/unittests/rpc.c
+-	* src/dblib/unittests/setnull.c src/dblib/unittests/t0001.c
+-	* src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c
+-	* src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c
+-	* src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c
+-	* src/dblib/unittests/t0008.c src/dblib/unittests/t0011.c
+-	* src/dblib/unittests/t0015.c src/dblib/unittests/t0018.c
+-	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c
+-	* src/dblib/unittests/thread.c src/dblib/unittests/timeout.c:
+-	- dbbind uses zero, not -1 to indicate sufficient space.  
+-
+-Mon Dec  3 17:57:54 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c: don't cast malloc and don't assume it worked. 
+-
+-Mon Dec  3 19:54:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/Makefile.am: remove GNU make pattern
+-
+-Mon Dec  3 15:35:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c:
+-	- do not call dbcolptr for compute result but call new dbacolptr
+-	- dbcolptr return TDSCOLUMN* to optimize it
+-
+-Mon Dec  3 11:53:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c: remove a warning
+-
+-Mon Dec  3 10:18:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c src/dblib/unittests/.cvsignore:
+-	* src/dblib/unittests/Makefile.am src/dblib/unittests/setnull.c(added):
+-	- add a test for setnull
+-
+-Sun Dec  2 17:58:40 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/api_status.txt
+-	* include/dblib.h include/sybdb.h include/tds.h
+-	* src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c
+-	- full implementation of dbsetnull().
+-	- Replaced _DB_GETCOLINFO macro with dbcolptr(). 
+-
+-Sat Dec  1 14:05:54 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c src/dblib/unittests/null.c
+-	- correct TDS 5.0 bcp offset table calcuation in presence of NULLs.
+-
+-Fri Nov 30 09:54:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/common.c: missing new line
+-
+-Thu Nov 29 09:03:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/null2.c: improve
+-
+-Wed Nov 28 15:15:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac:
+-	- include windows.h under windows
+-	- include sql.h directly to avoid MingW problems
+-	* include/dblib.h src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
+-	- avoid core checking for parameters if argument are expected
+-	* src/dblib/unittests/null.c src/dblib/unittests/null2.c:
+-	- avoid invalid references to deallocated stack
+-
+-Wed Nov 28 09:48:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/bcp.c: remove warnings
+-
+-Wed Nov 28 00:27:36 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c fixed TDS 5.0 null-column bug, cf. ML
+-	* doc/tds.html Added BCP, made 4.01 strict, validated. 
+-
+-Tue Nov 27 16:12:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/Makefile.am src/dblib/unittests/null2.c(added):
+-	- test dbbind/dbnullbind with NULLs
+-	* src/dblib/unittests/null.c: add note
+-
+-Tue Nov 27 13:37:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/t0001.c src/dblib/unittests/t0022.c:
+-	- compile with Sybase libraries
+-	* src/dblib/unittests/t0008.c: more verbose
+-
+-Mon Nov 26 21:02:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/array_out.c: fix silly core
+-
+-Mon Nov 26 19:11:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac include/tdsodbc.h src/odbc/odbc.c:
+-	* src/odbc/unittests/array_out.c src/odbc/unittests/common.h:
+-	* src/odbc/unittests/describecol.c src/odbc/unittests/freeclose.c:
+-	* src/odbc/unittests/insert_speed.c src/odbc/unittests/timeout.c:
+-	* src/odbc/unittests/timeout3.c src/odbc/unittests/type.c:
+-	- minor fixes for 64bit
+-
+-Mon Nov 26 16:47:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/apps/fisql/fisql.c:
+-	- do not use functions not availables
+-
+-Mon Nov 26 09:43:03 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c src/tds/unittests/iconv_fread.c
+-	- small changes
+-
+-Mon Nov 26 09:51:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/bcp.c: fix printf
+-
+-Mon Nov 26 07:24:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
+-	* src/odbc/unittests/const_params.c src/odbc/unittests/cursor1.c:
+-	* src/odbc/unittests/describecol.c src/odbc/unittests/freeclose.c:
+-	* src/odbc/unittests/insert_speed.c src/odbc/unittests/raiserror.c:
+-	* src/odbc/unittests/rpc.c src/odbc/unittests/scroll.c:
+-	* src/tds/challenge.c:
+-	- fix minor issues with 64bit
+-
+-Thu Nov 22 09:43:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/ctlib/Makefile.am src/dblib/Makefile.am:
+-	* src/odbc/Makefile.am:
+-	- do not filter symbols under MacOsX (avoid libtool problems)
+-
+-Wed Nov 21 11:31:37 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/ctlib/blk.c: correctly test result of cs_convert
+-	* src/dblib/rpc.c: minor edits
+-	* src/dblib/unittests/bcp.c src/dblib/unittests/bcp.h:
+-	- test works for TDS 7.0.
+-
+-Tue Nov 20 23:08:15 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c src/dblib/unittests/bcp.c:
+-	* src/dblib/dblib.c src/tds/convert.c src/tds/net.c:
+-	- small changes
+-
+-Thu Nov 15 14:32:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/.cvsignore src/dblib/dblib.c:
+-	* src/dblib/unittests/Makefile.am src/dblib/unittests/null.c:
+-	- fix problem with empty string and TEXT
+-	- add a test to test empty/NULL behavior of dbdatlen/dbdata
+-
+-Thu Nov 15 10:18:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/login.c: return error if no username given and no Kerberos
+-
+-Tue Nov 13 10:13:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/challenge.c src/tds/gssapi.c:
+-	* src/tds/login.c src/tds/token.c:
+-	- port ntlm to new authentication code
+-	- move all ntlm stuff to challenge.c
+-
+-Mon Nov 12 17:15:03 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/sybdb.h src/dblib/bcp.c
+-	* src/dblib/dblib.c src/dblib/dbutil.c
+-	* src/dblib/rpc.c
+-	* src/tds/log.c src/tds/login.c
+-	- trying to convince Doxygen not to ignore functions, 
+-	- e.g. dbinit 
+-
+-Mon Nov 12 13:38:04 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/dblib.h src/dblib/dbutil.c
+-	* src/dblib/dblib.c src/dblib/rpc.c src/dblib/bcp.c
+-	- added DBDEAD test to all public functions
+-
+-Mon Nov 12 14:32:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: cleanup
+-	* src/tds/gssapi.c: compute fqdn name in service name
+-
+-Mon Nov 12 12:34:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac include/tds.h src/tds/gssapi.c:
+-	* src/tds/login.c src/tds/mem.c src/tds/token.c:
+-	- new TDSAUTHENTICATION structure
+-	- new --enable-krb5 to enable Kerberos authentication
+-	  (disable by default)
+-
+-Fri Nov 09 11:29:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: remove some leaks
+-
+-Mon Nov 05 11:05:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: use pipes to avoid infinite counter
+-
+-Mon Nov 05 09:29:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/login.c: fix log avoidance for long logins
+-
+-Sun Nov 04 09:16:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/gssapi.c: small cleanup
+-
+-Sat Nov 03 14:31:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/config.c src/tds/mem.c:
+-	- add server_host_name to TDSCONNECTION
+-	* src/tds/gssapi.c: some improves
+-
+-Fri Nov 02 11:33:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/gssapi.c: add small comment
+-
+-Tue Oct 30 16:45:41 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/Makefile.am src/tds/gssapi.c src/tds/login.c:
+-	- include developing code for GSSAPI
+-
+-Tue Oct 30 16:36:29 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/login.c src/ctlib/ct.c src/tds/read.c:
+-	* src/tds/token.c:
+-	- finish merging tds9 code as developing
+-
+-Tue Oct 30 16:02:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c:
+-	- make odbc row_count 64bit
+-
+-Tue Oct 30 13:14:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/config.c src/tds/query.c:
+-	- more merge for tds9
+-
+-Tue Oct 30 11:31:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c:
+-	* src/server/server.c src/tds/token.c:
+-	- merge partially tds9 patch
+-
+-Tue Oct 30 11:15:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c:
+-	- avoid wrong assert if error and tdserror called
+-	* src/tds/query.c: limit data length to maximun allowed
+-
+-Wed Oct 24 17:55:56 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* include/sqldb.h define dbfreelogin
+-	* src/dblib/unittests/common.h add commentary
+-
+-Tue Oct 23 19:41:03 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* src/tds/net.c src/tds/util.c
+-	- ct-lib seems OK with EINTR (sqsh works) but db-lib
+-	- applications get a weird message. 
+-
+-Tue Oct 23 18:08:00 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* src/tds/net.c 
+-	- return from tds_select as if timed out on EINTR. 
+-	- sqsh still unhappy when ^C pressed on long-running query. 
+-
+-Thu Oct 18 16:48:23 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c: fix core
+-
+-Thu Oct 18 13:49:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/query.c src/tds/token.c:
+-	- more free(NULL)
+-
+-Tue Oct 16 16:59:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c src/ctlib/blk.c src/ctlib/cs.c src/ctlib/ct.c:
+-	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
+-	* src/dblib/unittests/rpc.c src/odbc/error.c src/odbc/odbc.c:
+-	* src/odbc/sql2tds.c src/odbc/unittests/binary_test.c:
+-	* src/pool/config.c src/tds/locale.c src/tds/login.c:
+-	* src/tds/mem.c src/tds/query.c src/tds/token.c:
+-	* src/tds/vstrbuild.c src/tds/unittests/dataread.c:
+-	- do not check for free(NULL)
+-
+-Wed Oct 10 13:59:37 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/tsql.c 
+-	- added some error checking for malloc/realloc, more needed
+-
+-Tue Oct 09 13:40:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/mem.c: fix small memory leak
+-
+-Mon Sep 24 13:12:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/query.c: limit size preparing queries
+-
+-Mon Sep 24 12:01:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/server/query.c src/server/server.c:
+-	- small server improve
+-
+-Thu Sep 20 17:32:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/sybdb.h src/dblib/dblib.c src/dblib/dbopen.c:
+-	- apply constify patch #1786200
+-
+-Thu Sep 20 17:02:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: do not strip empty lines
+-
+-Mon Sep 17 17:22:32 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c correct freebcp -L behavior 
+-	* src/tds/net.c TDSECONN on no socket failure 
+-	* src/tds/util.c change iconv messages
+-
+-Mon Sep 17 17:52:09 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: update for tds9
+-	* src/server/login.c: remove warning
+-
+-Mon Sep 17 12:13:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c:
+-	- improve for very large query (from 9.2 to 0.3 seconds on my 
+-	  test machine)
+-
+-Mon Sep 17 10:42:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: update
+-	* src/ctlib/unittests/get_send_data.c: small fix
+-	* include/sybdb.h src/dblib/dblib.c src/dblib/unittests/t0022.c:
+-	- small update for future tds9
+-	* src/pool/main.c src/pool/user.c src/server/login.c:
+-	- improve portability and possible remote leakage
+-
+-Thu Sep 13 12:42:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/freeclose.c:
+-	- make it works even if login is quite long
+-
+-Thu Sep 13 08:57:26 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/unittests/dynamic1.c: use tds_set_param_type
+-
+-Thu Sep 06 13:15:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: update for tds9
+-	* src/tds/read.c: work if initial in_pos is != 0
+-
+-Sat Aug 25 12:32:01 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
+-	- use ODBC_API instead of SQL_API to allow combined compile
+-
+-Fri Aug 24 11:50:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/login.c:
+-	* src/tds/query.c src/tds/token.c:
+-	- small changes for TDS 9.0
+-
+-Mon Aug 16 10:09:42 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
+-	* src/odbc/unittests/Makefile.am src/tds/net.c:
+-	* src/tds/unittests/Makefile.am:
+-	- remove other warnings
+-
+-Mon Aug 16 08:29:38 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/unittests/convert.c win32/initnet.c:	
+-	- remove some warnings compiling with MingW
+-
+-Sat Aug 11 08:51:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c vms/config_h.vms vms/descrip_mms.template:
+-	- applied Craig A. Berry patch #1772080 for VMS systems
+-
+-Fri Aug 10 11:17:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* NEWS: updated
+-
+-Fri Aug 10 11:14:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* win32/dev-cpp/Makefile.win: add missing file
+-
+-Thu Aug 09 14:52:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c: small fixes
+-
+-Thu Aug 09 10:26:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/userguide.sgml: document port override syntax
+-
+-Thu Aug 09 09:49:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/htdoc/basic_jdbc_question.html doc/htdoc/contrib.html:
+-	* doc/htdoc/docs.html doc/htdoc/index.html doc/htdoc/news.html:
+-	* doc/htdoc/software.html doc/htdoc/support.html:
+-	* doc/htdoc/vague_jdbc_question.html doc/htdoc/which_api.html:
+-	- make xhtml compatible
+-
+-Wed Aug 08 15:24:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/odbc/Makefile.am win32/version.rc.in:
+-	- fix odbc cross compile using MingW
+-
+-Wed Aug 08 11:34:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/freetds_autobuild:
+-	- improved adding test for server:port and server\instance case
+-
+-Wed Aug 08 11:10:36 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/config.c: fix bug #1759652 (cannot use server\INSTANCE)
+-
+-Tue Aug 07 15:34:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: improve cursor updates
+-	* src/odbc/unittests/cursor1.c: improved and fixed
+-
+-Tue Aug 07 11:55:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/query.c: use table name for update
+-
+-Tue Aug 07 11:19:33 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/odbc/odbc.c src/odbc/unittests/getdata.c:
+-	- fix bug #1758831
+-	- additional fixes and checks for SQLGetData
+-
+-Tue Aug 07 10:29:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/userguide.sgml: update links
+-
+-Fri Aug 03 13:15:42 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/config.c: lookup server name correctly for instances
+-
+-Thu Aug 02 13:31:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/sqlfront.h: small compatiblity improve with ms
+-
+-Fri Jul 13 18:56:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/getdata.c: portability fix
+-
+-Thu Jul 12 16:31:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: fix for SQLGetData using empty fields
+-	* src/odbc/unittests/getdata.c:
+-	- improve test to catch previous problem
+-
+-Sat Jul 07 19:55:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* m4/sprintf_i64_format.m4: improve portability
+-
+-Sat Jul 07 19:09:59 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c:
+-	- check cbValueMax in SQLGetData even if DM present
+-
+-Tue Jul 03 17:12:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/compute.c src/odbc/unittests/tables.c:
+-	* src/odbc/unittests/typeinfo.c:
+-	- relax test for Sybase
+-	* src/tds/token.c: fix length computation
+-
+-Tue Jul 03 15:37:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c:
+-	* src/odbc/odbc.c src/tds/mem.c src/tds/token.c:
+-	- add table_column_name to read real column name (if available),
+-	  read from wire and use when needed
+-
+-Sun Jul 01 12:10:31 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsstring.h src/odbc/connectparams.c:
+-	* src/odbc/descriptor.c src/odbc/odbc.c src/tds/config.c:
+-	* src/tds/tdsstring.c:
+-	- added tds_dstr_dup to duplicate DSTR
+-	- use tds_dstr_dup
+-	- improve tds_dstr_set
+-
+-Wed Jun 27 16:51:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: add Column Info token
+-	* src/odbc/unittests/timeout2.c: portability fix
+-
+-Mon Jun 25 11:47:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/api_status.txt include/cspublic.h include/ctlib.h:
+-	* src/ctlib/cs.c src/ctlib/ct.c:
+-	- applied patch #1729392, it adds support for ctlib locale
+-
+-Mon Jun 25 10:20:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: review cursors
+-
+-Thu Jun 21 09:19:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/freetds_autobuild: test for Sybase 15
+-	* src/odbc/unittests/data.c: bigint for Sybase
+-	* src/tds/data.c src/tds/mem.c src/tds/read.c src/tds/tds_checks.c:
+-	- add support for Sybase bigint
+-	- do not check decault capabilities if not necessary
+-
+-Tue Jun 19 15:30:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/ctlib/ct.c src/odbc/odbc_util.c:
+-	* src/pool/stream.c src/tds/data.c src/tds/net.c:
+-	* src/tds/tds_checks.c src/tds/tds_checks.h src/tds/token.c:
+-	- fix problem with Sybase LONGCHAR
+-
+-Tue Jun 19 14:06:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/unittests/t0007.c src/odbc/unittests/prepare_results.c:
+-	- more verbose
+-	- fix for possible Sybase conversion
+-	* src/odbc/odbc.c: additional check if no dm
+-
+-Mon Jun 18 15:20:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/convert.c:
+-	- patch #1736289 for bcp/bulk insert problem
+-
+-Mon Jun 18 14:02:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c src/tds/locale.c:
+-	- use correct charset based on locale
+-
+-Mon Jun 18 13:58:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/genparams.c: remove warning
+-
+-Sun Jun 17 19:38:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/freeclose.c src/odbc/unittests/timeout3.c:
+-	- fix small thread problem
+-	- fix possible deadlock
+-
+-Sun Jun 17 09:45:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/freeclose.c src/odbc/unittests/genparams.c:
+-	- fix thread and small portability
+-
+-Sun Jun 17 09:08:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/dblib.h src/dblib/buffering.h src/dblib/dblib.c:
+-	- patch #1717123 for dbsetnull implementation (removed warnings)
+-
+-Sun Jun 17 08:16:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c:
+-	- patch #1703363 for delimiters (modified)
+-
+-Wed Jun 13 09:26:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/fisql/fisql.c: compile even if readline is not available
+-
+-Mon Jun  4 17:09:03 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/Makefile.am skip bsqlodb if ODBC disabled
+-
+-Mon Jun 04 10:03:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/.cvsignore src/dblib/unittests/Makefile.am:
+-	* src/dblib/unittests/hang.c(added) src/tds/net.c:
+-	- fix problem with tds_select (detected by Perception Technologies)
+-
+-Fri Jun 01 10:52:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/token.c: avoid overflow leading to memory errors
+-
+-Thu May 31 17:02:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c:
+-	- fixes, partially from Brent of Perception Technologies Ltd
+-
+-Thu May 31 10:54:14 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* TODO add recent potential bug reports
+-
+-Thu May 31 14:21:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* m4/ac_nullzero.m4: fix cross compile test
+-
+-Wed May 30 09:55:52 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/threadsafe.c:
+-	- implement gethostbyname_r with getaddrinfo (for UnixWare 7 and others)
+-
+-Tue May 29 10:48:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac win32/config.h: cleanup
+-
+-Fri May 25 11:07:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/convert_tds2sql.c:
+-	- remove a FIXME
+-	* src/odbc/odbc.c:
+-	- fix bug #1716594 ("SQLFreeStmt with SQL_CLOSE shouldn't 
+-	  unprepare statement")
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/freeclose.c(added)
+-	* src/odbc/unittests/.cvsignore:
+-	- add a test for bug #1716594
+-
+-Mon May 21 14:01:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c:
+-	- fix cursor updates, this undo part of change of src/odbc/odbc.c
+-	  from 1.331 to 1.332, log:
+-	  Wed Jul 21 16:50:11 CET 2004
+-	   : some fix for SQLFetch and multiple rows
+-	  but tests works
+-	* src/odbc/unittests/cursor1.c: improve
+-
+-Mon May 21 10:40:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/cursor1.c: improve test
+-
+-Thu May 17 12:32:33 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_checks.c:
+-	* src/odbc/odbc_util.c:
+-	- avoid core
+-	- fix and check invalid values of num_param_rows and curr_param_row
+-
+-Thu May 17 09:18:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/warning.c: improve and comments
+-
+-Wed May 16 14:23:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
+-	* src/odbc/sql2tds.c:
+-	- support row binding in RPC
+-	- reuse new odbc_get_octet_len
+-
+-Wed May 16 14:23:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/freetds_autobuild: minor updates
+-
+-Mon May 14 16:04:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/login.c: remove copy error
+-
+-Mon May 14 10:16:37 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/login.c src/tds/mem.c src/tds/token.c src/tds/util.c:
+-	- give proper errors on protocol autodiscovery
+-
+-Wed May 09 10:31:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: finish ODBC timeout
+-
+-Fri May 03 14:54:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/const_params.c:
+-	- reset statement to be sure to cleanup
+-
+-Wed May 02 16:54:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c:
+-	- use query timeout from freetds.conf
+-
+-Mon Apr 30 15:14:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: use default linkage for static functions
+-
+-Mon Apr 30 15:02:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/blk.c: fix strange link error using gcc 4.1
+-
+-Mon Apr 23 09:56:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c: fix portability issue
+-
+-Fri Apr 20 15:26:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
+-	* src/odbc/unittests/scroll.c:
+-	- make valgrind more happy if Sybase is used
+-
+-Fri Apr 20 11:13:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/timeout4.c(added):
+-	- add a test for timeout
+-	- fix timeout on prepare (not detected)
+-	- fix timeout if connection broken
+-
+-Thu Apr 19 11:11:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
+-	* src/odbc/unittests/scroll.c:
+-	- give only warning for Sybase
+-
+-Thu Apr 19 10:45:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c:
+-	- say we not still support cursors for sybase
+-
+-Wed Apr 18 16:28:29 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* TODO.freddy include/tdsodbc.h src/odbc/odbc.c:
+-	* src/odbc/odbc_util.c src/odbc/prepare_query.c src/odbc/sql2tds.c:
+-	- fix cursor updates
+-
+-Mon Apr 16 22:08:07 EDT 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/bsqlodbc.c ODBC3 conformant 
+-
+-Sun Apr 15 10:01:36 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: fix leak
+-
+-Fri Apr 13 17:27:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: cursor update
+-
+-Fri Apr 13 17:22:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/query.c:
+-	- add cursor update to libTDS
+-
+-Fri Apr 13 10:08:07 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/bsqlodbc.c:
+-	- catch all error
+-	- fix some memory problems
+-
+-Thu Apr 12 15:33:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/funccall.c:
+-	- add test from ML
+-
+-Thu Apr 12 15:07:09 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* freetds.spec.in: fix odbc directory
+-	* src/dblib/unittests/Makefile.am: fix for make distcheck
+-	* src/odbc/unittests/raiserror.c src/odbc/unittests/warning.c:
+-	- relax if dm used
+-
+-Thu Apr 12 09:47:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c src/odbc/unittests/copydesc.c:
+-	- test and fix a problem with SQLAllocHandle
+-	* src/odbc/unittests/connect2.c: add test for not existing dbs
+-
+-Thu Apr 12 09:05:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/unittests/array_bind.c src/ctlib/unittests/ct_diagall.c:
+-	* src/ctlib/unittests/ct_diagclient.c:
+-	- fix buffer overflow leading in core
+-
+-Wed Apr 11 14:55:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/common.c src/odbc/unittests/common.c:
+-	- remove warning compiling with MingW
+-
+-Wed Apr 11 13:52:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/connectparams.c src/odbc/odbc.c:
+-	* src/odbc/unittests/connect2.c:
+-	- finish and fix test for change_database
+-
+-Wed Apr 11 11:47:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/connect2.c: fix test
+-	* src/odbc/unittests/describecol.in: relax test
+-
+-Wed Apr 11 09:09:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/connect2.c src/odbc/unittests/Makefile.am:
+-	- add a test for change_database
+-
+-Tue Apr 10 16:00:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
+-	- fixes for describecol test
+-
+-Tue Apr 10 15:16:28 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/coverage.sh: remove system files
+-	* src/odbc/unittests/describecol.in: relax test
+-
+-Fri Apr 06 10:52:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdssrv.h src/server/login.c src/server/unittest.c:
+-	- remove warning
+-
+-Fri Apr 06 10:29:31 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* NEWS src/odbc/unittests/funccall.c src/tds/mem.c:
+-	* src/tds/query.c:
+-	- added some notes
+-
+-Thu Apr 05 16:16:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* INSTALL INSTALL.CVS NEWS README doc/userguide.sgml:
+-	- merge from 0.64
+-
+-Wed Apr 04 13:39:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* NEWS: updated
+-
+-Wed Apr 04 11:53:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h include/tdsodbc.h src/ctlib/ct.c src/dblib/rpc.c:
+-	* src/odbc/prepare_query.c src/odbc/sql2tds.c src/tds/mem.c:
+-	* src/tds/token.c src/tds/unittests/dynamic1.c:
+-	- removed unused paramter from tds_alloc_param_data
+-	- fix possible problem in prepare_rpc
+-
+-Wed Apr 04 11:39:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* vms/descrip_mms.template: add log.c
+-	* src/server/query.c: use constants
+-
+-Wed Apr 04 09:14:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/userguide.sgml: improve slow check
+-
+-Tue Apr 03 16:23:17 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* win32/dev-cpp/FreeTDS.dev win32/dev-cpp/Makefile.win:
+-	- updated adding log.c
+-
+-Mon Apr 02 17:06:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/userguide.sgml: add encryption parameter
+-
+-Thu Mar 29 16:32:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/blk.c: initial fix for bcp state
+-
+-Thu Mar 29 16:25:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/server/login.c src/tds/config.c:
+-	* src/tds/login.c:
+-	- added encryption setting in freetds.conf
+-
+-Thu Mar 29 12:17:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: check includes for ODBC
+-
+-Thu Mar 29 09:44:11 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/genparams.c: add test for money
+-
+-Wed Mar 28 14:43:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* freetds.spec.in src/odbc/unittests/Makefile.am:
+-	- fix test-dist test
+-
+-Mon Mar 26 13:27:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/.cvsignore src/dblib/unittests/Makefile.am:
+-	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
+-	* win32/build_dsw.pl:
+-	- distribute projects for vc6 unittests
+-
+-Mon Mar 26 10:05:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/htdoc/news.html: validate page
+-
+-Sun Mar 24 09:23:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/bsqlodbc.c:
+-	- avoid dangerous casts
+-
+-Tue Mar 20 16:24:26 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/replacements/gettimeofday.c src/apps/datacopy.c:
+-	- remove warning
+-
+-Mon Mar 19 11:01:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/replacements.h: fix warning for win32
+-
+-Sun Mar 18 12:37:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/common.c src/odbc/unittests/timeout2.c:
+-	* src/odbc/unittests/timeout3.c:
+-	- fix cross-compile for win32
+-
+-Sun Mar 18 12:09:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/Makefile.am 	src/apps/bsqlodbc.c src/apps/tsql.c:
+-	* src/apps/fisql/Makefile.am 	win32/winsetup.c:
+-	- fix cross-compile for win32
+-
+-Fri Mar 16 16:32:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/Makefile.am src/tds/Makefile.am:
+-	- full libTDS privatization
+-	* src/server/unittest.c: use mnemonic
+-
+-Wed Mar 14 17:18:23 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: update
+-	* include/tdssrv.h src/pool/user.c src/server/login.c:
+-	* src/server/query.c src/server/server.c src/server/unittest.c:
+-	- update server stuff, at least login works
+-	* src/tds/tdsstring.c: fix possible mising NUL terminator
+-	* src/apps/tsql.c: fix wrong error handler result
+-
+-Wed Mar 14 09:47:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html include/tds.h: update documentation
+-
+-Tue Mar 13 17:24:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/pool/user.c src/server/login.c:
+-	* src/server/unittest.c src/tds/login.c src/tds/query.c:
+-	- use mnemonic for packet types
+-
+-Tue Mar 13 16:45:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: added known tokens
+-
+-Tue Mar 13 14:18:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: updated from code
+-
+-Mon Mar 12 14:27:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/ctlib.h include/dblib.h include/des.h include/md4.h:
+-	* include/md5.h include/replacements.h include/tdsiconv.h:
+-	* include/tdsstring.h include/replacements/readpassphrase.h:
+-	* src/server/Makefile.am:
+-	- privatize functions using gcc visibility if available
+-	- privatize server library
+-
+-Mon Mar 12 13:31:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/unittests/blk_in2.c(added) src/ctlib/unittests/Makefile.am:
+-	- added test from ML to test cancel and bulk together
+-
+-Mon Mar 12 10:52:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tds.html: improved, added types
+-
+-Fri Feb 16 14:52:10 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h: improve documentation
+-
+-Mon Feb 12 14:29:53 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c: Increase size of dbprrow() conversion buffer to 8K.
+-
+-Mon Feb 12 10:53:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/timeout3.c:
+-	- use thread instead of fork
+-
+-Wed Feb  7 01:11:27 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/bsqlodbc.c don't exit on SQL_SUCCESS_WITH_INFO
+-
+-Wed Feb  7 00:04:15 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/bsqldb.c exit noisily on severe errors
+-	* src/dblib/dblib.c src/tds/token.c 
+-	- fix timeout with buffering problem per yesterday's ML. 
+-
+-Tue Feb  6 17:14:50 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c:
+-	- Sybase docs for dbsqlok() says: "If the command buffer contains
+-	  multiple commands, a run-time error will not cause dbsqlok to
+-	  fail.  Instead, failure will occur with the dbresults call that
+-	  processes the command causing the run-time error."
+-	* src/apps/fisql/fisql.c:
+-	- Correct result set processing.
+-	
+-Tue Feb  6 14:11:02 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c: Don't print or store column separator after final result column
+-
+-Tue Feb 06 10:18:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/odbc/Makefile.am:
+-	- use -module option only for darwin
+-
+-Tue Feb 06 09:53:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/bsqlodbc.c:
+-	- make more functions static
+-	- remove warning
+-	* src/tds/net.c: remove warning
+-
+-Mon Feb  5 21:48:58 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/Makefile.am src/apps/bsqlodbc.c src/apps/osql
+-	- added bsqlodbc as general batch script processor. 
+-
+-Mon Feb 05 09:41:02 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/test-other.sh phptests/null.php:
+-	- fixed PHP check, updated test to PHP 5.2
+-
+-Fri Feb 02 11:51:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/timeout3.c(added):
+-	- added a test for connection timeout
+-	- fix timeout connection in odbc
+-
+-Mon Jan 29 12:02:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds_sysdep_private.h src/apps/fisql/fisql.c:
+-	* src/tds/net.c:
+-	- remove some warnings
+-
+-Fri Jan 26 18:19:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/fisql/fisql.c:
+-	- remove warning
+-	- reuse malloc
+-	- fix compile error including config.h
+-	* src/dblib/dblib.c: remove warning
+-
+-Fri Jan 26 18:06:44 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/error.c src/odbc/odbc.c:
+-	- remove warning compiling
+-
+-Wed Jan 24 14:14:55 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* doc/fisql.txt: compute rows in fisql work now, remove BUGS entry
+-
+-Wed Jan 24 14:11:56 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: indent
+-
+-Wed Jan 24 14:08:09 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: good enough compute layout
+-
+-Wed Jan 24 12:24:30 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: almost correct compute layout
+-
+-Wed Jan 24 11:32:56 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: minor compute layout fixes, still more to do
+-
+-Tue Jan 23 17:15:33 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: better compute results, layout needs fixing
+-
+-Tue Jan 23 11:24:40 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c: fix off-by-one bug in dbbylist()
+-
+-Mon Jan 22 15:54:02 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: fix :r with unreadable file
+-
+-Mon Jan 22 15:50:31 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c: print line separator after compute results
+-
+-Mon Jan 22 00:56:12 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/odbc/connectparams.c src/odbc/error.c
+-	* src/odbc/odbc.c
+-	- added log entry for API functions
+-	* src/odbc/unittests/common.c always use '/' separator
+-
+-Sat Jan 20 15:24:03 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/dblib.h include/sybdb.h src/dblib/dblib.c
+-	- moved DBOPTION to dblib.h and removed unused members.
+-
+-Sat Jan 20 01:29:36 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/defncopy.txt doc/fisql.txt cleanup formatting
+-	* src/apps/bsqldb.c src/dblib/dblib.c fix compute row headers
+-
+-Sat Jan 20 01:30:22 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* ChangeLog src/apps/fisql/edit.c src/apps/fisql/edit.h
+-	* src/apps/fisql/fisql.c src/apps/fisql/handlers.c
+-	* src/apps/fisql/handlers.h src/apps/fisql/interrupt.c
+-	* src/apps/fisql/interrupt.h src/apps/fisql/terminal.c
+-	* src/apps/fisql/terminal.h:
+-	- Fix my name and the program name
+-
+-Sat Jan 20 01:20:39 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: 
+-	- Be slightly less stupid about compute rows.
+-
+-Sat Jan 20 00:54:57 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c:
+-	- do not return bogus nul character in dbgetchar()
+-
+-Sat Jan 20 00:35:45 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c:
+-	- dbspr*() functions get nul termination not line termination
+-	
+-Fri Jan 19 22:39:00 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* doc/fisql.txt: restore compute rows BUGS entry.
+-
+-Fri Jan 19 14:05:13 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: 
+-	- Provide xmalloc() and xrealloc() instead of relying on
+-	  libreadline for these.
+-	
+-Fri Jan 19 13:47:42 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/Makefile.am
+-	* src/apps/fisql/fisql.c
+-	* src/apps/fisql/xgetpass.c(removed)
+-	* src/apps/fisql/xgetpass.h(removed):
+-	- use readpassphrase() in fisql application.
+-
+-Fri Jan 19 13:31:31 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/edit.c src/apps/fisql/fisql.c
+-	* src/apps/fisql/handlers.c src/apps/fisql/handlers.h
+-	* src/apps/fisql/interrupt.c src/apps/fisql/interrupt.h
+-	* src/apps/fisql/terminal.c src/apps/fisql/terminal.h
+-	* src/apps/fisql/xgetpass.c:
+-	- Indent fisql to standard FreeTDS coding style
+-
+-Fri Jan 19 13:19:04 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/apps/fisql/fisql.c: remove obsolete code
+-
+-Fri Jan 19 13:12:56 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* doc/fisql.txt: fisql now works, update doc
+-
+-Fri Jan 19 13:01:53 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* .cvsignore doc/.cvsignore: clean up
+-
+-Fri Jan 19 12:45:27 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c: fix dbspr1row(), fisql now works
+-
+-Fri Jan 19 11:17:13 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/fisql.txt
+-	* src/apps/fisql/edit.c src/apps/fisql/edit.h
+-	* src/apps/fisql/handlers.c src/apps/fisql/handlers.h
+-	* src/apps/fisql/interrupt.c src/apps/fisql/interrupt.h
+-	* src/apps/fisql/terminal.c src/apps/fisql/terminal.h
+-	* src/apps/fisql/xgetpass.c src/apps/fisql/xgetpass.h
+-	* src/apps/fisql/fisql.c
+-	- Added notice of copyright and GPL license
+-
+-Thu Jan 18 23:55:17 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/Makefile.am doc/fisql.txt added man page for fisql
+-	* src/apps/fisql/fisql.c fixed discarding const warnings
+-	* doc/api_status.txt include/sybdb.h src/dblib/dblib.c
+-	-  added dbgettime()
+-
+-Thu Jan 18 17:57:52 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* AUTHORS: credit myself as a contributor
+-
+-Thu Jan 18 17:50:18 EST 2007	Nick Castellano <entropy@freetds.org>
+-	* src/dblib/dblib.c:
+-	- fix dbprrow() to print character data correctly
+-	- fix dbprrow() to not loop endlessly on aggregate rows
+-
+-Thu Jan 18 08:57:10 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/unittests/utf8_2.c: fix error handler
+-
+-Wed Jan 17 09:48:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/fisql/fisql.c: use mkstemp instead of mktemp
+-	* src/tds/util.c: cleanup
+-
+-Tue Jan 16 16:30:42 EDT 2007	Nick Castellano <entropy@freetds.org>
+-	* configure.ac
+-	* src/apps/Makefile.am
+-	* src/apps/fisql: contribute free DB-Libary isql application
+-
+-Tue Jan 16 09:57:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/util.c: fix messages
+-
+-Tue Jan 16 09:48:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* misc/test-other.sh: fix problem with Perl 5.8.8
+-	* src/dblib/dblib.c: fix possible thread problem
+-
+-Tue Jan 16 00:28:28 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/dblib.h src/dblib/bcp.c
+-	* src/dblib/dblib.c src/dblib/unittests/rpc.c
+-	- support variadic form of dbperror
+-
+-Mon Jan 15 14:40:35 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/unittests/common.c
+-	* src/dblib/unittests/rpc.c
+-	* src/dblib/unittests/t0004.c
+-	* src/dblib/unittests/t0005.c
+-	* src/dblib/unittests/t0007.c
+-	* src/dblib/unittests/t0019.c
+-	* src/dblib/unittests/t0020.c
+-	- fail if an unanticipated message/error is received
+-
+-Sun Jan 14 23:16:17 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/tds/config.c src/tds/login.c
+-	- began work on autodetecting the server's TDSVER
+-	- works with libtds, not db-lib
+-
+-Sun Jan 14 20:38:25 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* include/dblib.h include/tds.h
+-	* src/dblib/dblib.c src/dblib/dbutil.c
+-	* src/dblib/unittests/t0001.c src/dblib/unittests/t0012.c
+-	* src/dblib/unittests/timeout.c
+-	* src/tds/net.c TODO
+-	- timeout unit test also works with dbsetinterrupt
+-
+-Sat Jan 13 17:09:05 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/unittests/timeout.c added 
+-	* src/dblib/dblib.c 
+-	* src/dblib/unittests/Makefile.am src/dblib/unittests/t0001.c
+-	* src/tds/login.c src/tds/query.c src/tds/util.c
+-	- new timeout unit test works. 
+-
+-Fri Jan 12 14:28:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: update code to new libTDS timeout code
+-	* src/tds/net.c: handle send/recv errors
+-	* src/tds/util.c: fix msgno if error not found in table
+-
+-Thu Jan 11 10:49:52 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* src/apps/osql 
+-	- fixed incorrect report when drivername is not a file
+-
+-Tue Jan 09 22:44:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: fix option problem
+-
+-Tue Jan  9 00:16:46 EST 2007	JK Lowden <jklowden@schemamania.org>
+-	* src/tds/net.c simpler tds_select, thanks Frediano
+-
+-Sun Jan  7 10:45:23 EST 2007	JK Lowden <jklowden@schemamania.org>
+-	* src/ctlib/ctutil.c works with tdserror()
+-
+-Sun Jan  7 00:41:19 EST 2007	JK Lowden <jklowden@schemamania.org>
+-	* include/tds.h
+-	* src/dblib/dblib.c src/dblib/dbutil.c
+-	* src/tds/net.c src/tds/query.c
+-	* src/tds/token.c src/tds/util.c
+-	- implement new timeout strategy using tds_select() and 
+-	- calling the client library's error handler (via tdserror). 
+-	- db-lib no worse than before, others not yet tested. 
+-
+-Fri Jan 05 14:08:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/token.c: new token
+-	* src/tds/util.c: optimize
+-
+-Fri Jan  5 02:08:54 EST 2007	JK Lowden <jklowden@schemamania.org>
+-	* include/tds.h src/tds/net.c src/tds/util.c
+-	- begin new timeout strategy, not done.
+-
+-Thu Jan  4 18:47:46 EST 2007	JK Lowden <jklowden@freetds.org>
+-	* doc/bsqldb.txt src/apps/bsqldb.c nicer headers
+-	* doc/osql.txt src/apps/osql allow ini location override
+-
+-Tue Jan  2 15:42:09 EST 2007	JK Lowden <jklowden@schemamania.org>
+-	* include/dblib.h include/tds.h
+-	* src/apps/tsql.c
+-	* src/dblib/dblib.c src/dblib/dbutil.c
+-	* src/tds/iconv.c src/tds/login.c src/tds/net.c
+-	* src/tds/token.c src/tds/util.c
+-	- replace tds_client_msg with tdserror()
+-
+-Mon Jan 01 12:56:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c src/tds/query.c:
+-	- remove some warning compiling with SUN compiler
+-	- Happy New Year
+-
+-Fri Dec 29 20:43:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/mem.c: remove warning and optimize
+-
+-Fri Dec 29 20:42:41 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: remove warnings
+-
+-Fri Dec 29 20:05:00 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h: cleanup
+-
+-Fri Dec 29 20:03:30 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/unittests/rpc_ct_param.c:
+-	* src/ctlib/unittests/rpc_ct_setparam.c src/odbc/odbc.c:
+-	- remove warnings
+-
+-Fri Dec 29 17:18:42 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/tds/log.c:
+-	- use localtime_r if available
+-
+-Fri Dec 29 10:06:56 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/log.c:
+-	- avoid locking if no logging
+-
+-Tue Dec 26 15:57:38 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h	src/ctlib/unittests/array_bind.c:
+-	* src/ctlib/unittests/ct_diagall.c:
+-	* src/ctlib/unittests/get_send_data.c:
+-	* src/ctlib/unittests/lang_ct_param.c:
+-	* src/dblib/bcp.c src/dblib/dblib.c:
+-	* src/dblib/dbutil.c src/dblib/rpc.c:
+-	* src/dblib/xact.c src/dblib/unittests/common.h:
+-	* src/dblib/unittests/t0016.c src/odbc/connectparams.c:
+-	* src/odbc/descriptor.c src/odbc/error.c:
+-	* src/odbc/odbc.c src/odbc/odbc_checks.c:
+-	* src/odbc/prepare_query.c src/odbc/unittests/common.h:
+-	* src/odbc/unittests/describecol.c src/pool/config.c:
+-	* src/pool/main.c src/pool/member.c src/pool/stream.c:
+-	* src/pool/user.c src/pool/util.c:
+-	* src/replacements/readpassphrase.c:
+-	* src/replacements/strtok_r.c src/replacements/vasprintf.c:
+-	* src/server/login.c src/server/unittest.c:
+-	* src/tds/config.c src/tds/convert.c src/tds/data.c:
+-	* src/tds/getmac.c src/tds/iconv.c src/tds/locale.c:
+-	* src/tds/login.c src/tds/net.c src/tds/numeric.c:
+-	* src/tds/tds_checks.c src/tds/tdsstring.c src/tds/threadsafe.c:
+-	* src/tds/write.c src/tds/unittests/common.h win32/winlogin.c:
+-	* win32/winsetup.c:
+-	- include stdarg.h always before stdio.h to fix portability
+-	  issues defining va_list
+-
+-Tue Dec 26 13:54:25 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/Makefile.am src/tds/util.c src/tds/log.c (added):
+-	- separate log stuff
+-
+-Sun Dec 24 12:40:19 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/descriptor.c: cleanup
+-
+-Fri Dec 22 09:34:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/convert.c: fix typo error
+-
+-Mon Dec 21 14:07:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/iconv.c: use cp1252 instead of iso8859-1 for mssql
+-
+-Wed Dec 20 22:47:36 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/tds/iconv.c src/tds/token.c log server charset changes
+-	* src/tds/unittests/convert.c permit varbinary
+-
+-Mon Dec 18 10:50:34 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/Makefile.am: distribute enum_cap.h
+-
+-Fri Dec 15 14:41:14 EST 2006	JK Lowden <jklowden@freetds.org>
+-	* src/tds/tds_willconvert.pl allow varbinary
+-
+-Thu Dec 14 22:18:16 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/tds/mem.c src/tds/unittests/t0001.c
+-	- Added tds_capability_set and enumerated capabilities
+-	* src/tds/enum_cap.h added
+-
+-Tue Dec 12 08:45:12 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
+-	- improve describecol test
+-
+-Sun Dec 10 16:04:02 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* doc/htdoc/faq.html minor fixes
+-	* src/apps/tsql.c send *sybase* charset name in login record
+-	* src/tds/net.c src/tds/read.c a little less logging
+-
+-Thu Dec  7 17:06:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/token.c: make get_send_data works
+-
+-Tue Dec  5 11:42:04 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/funccall.c: add a test
+-
+-Fri Dec  1 16:45:59 EST 2006	JK Lowden <jklowden@freetds.org>
+-	* include/sybdb.h src/dblib/bcp.c src/apps/freebcp.c
+-	- Changed freetbcp batch-copied information messages to 
+-	- match the output of Sybase's bcp utility.  
+-
+-Wed Nov 29 15:46:38 EST 2006	JK Lowden <jklowden@freetds.org>
+-	* src/apps/tsql.c fixed broken "go" option handling.
+-
+-Tue Nov 28 11:52:27 EST 2006	JK Lowden <jklowden@freetds.org>
+-	* src/apps/tsql.c fix -o option code
+-	* src/tds/net.c reorganize tds_open_socket()
+-
+-Mon Nov 27 18:31:18 EST 2006	JK Lowden <jklowden@freetds.org>
+-	* src/tds/net.c more detailed log of connect(2)
+-
+-Sun Nov 26 15:26:31 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/apps/tsql.c added connection timer feedback
+-	* src/tds/login.c src/tds/net.c slightly better logging
+-
+-Thu Nov 23 09:43:00 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/genparams.c:
+-	- fix possible problem with very remote servers
+-
+-Thu Oct 26 15:09:48 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/dbutil.c log error message from server
+-	* src/tds/net.c log TDS version
+-
+-Thu Oct 26 14:26:27 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/unittests/common.c src/dblib/unittests/common.h
+-	* src/dblib/unittests/t0001.c
+-	- corrected command-line option handling
+-
+-Sat Oct 21 16:42:08 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/dblib.c src/dblib/unittests/t0022.c:
+-	- dbresults succeeds if metadata or only return status is
+-	- present, cf. ML yesterday.
+-
+-Sat Oct 21 14:22:44 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* autogen.sh: fix some portability issues
+-
+-Wed Oct 18 21:38:57 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c src/odbc/unittests/tables.c:
+-	- fix problem with mssql2005 and SQLTables
+-
+-Mon Oct 16 09:48:31 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c: reduce system calls required
+-
+-Thu Oct 12 11:19:02 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/token.c:
+-	- fix wrong assert
+-	- return correctly RETURNSTATUS under Sybase
+-
+-Wed Oct 11 16:37:04 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/token.c: fix wrong assert using numerics
+-
+-Tue Oct 10 15:52:22 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* doc/osql.txt clarified
+-
+-Fri Oct  6 17:08:43 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/apps/freebcp.c src/apps/freebcp.h doc/freebcp.txt
+-	- applied -0 patch from ML
+-	- by Constantin Vasilyev <vasilyev@ncbi.nlm.nih.gov>
+-
+-Wed Oct  4 19:46:29 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/apps/freebcp.c 
+-	- applied -P from stdin patch 
+-	- from ML Constantin Vasilyev <vasilyev@ncbi.nlm.nih.gov>
+-
+-Wed Oct  4 17:36:43 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/apps/osql GNU sed does not support -E
+-
+-Wed Oct  4 14:48:20 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* doc/Makefile.am doc/osql.txt added osql man page
+-
+-Wed Oct  4 14:12:25 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/apps/Makefile.am add osql as installable script
+-
+-Tue Oct  3 15:40:12 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c test fwrite(3) correctly
+-
+-Tue Sep 26 16:57:42 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c src/dblib/dblib.c
+-	* src/tds/convert.c src/tds/net.c src/tds/token.c
+-	- added more user-level error checking, checking against 
+-	- known list of db-lib error messages
+-	* src/apps/osql added
+-
+-Wed Sep 13 13:55:24 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* samples/Makefile.am samples/unixodbc.freetds.driver.template.in:
+-	- add Setup entry to unixODBC template
+-	- unixODBC templates are not executables
+-
+-Wed Sep 13 13:52:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/mem.c: enable wide table
+-
+-Wed Sep 13 11:47:27 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/token.c:
+-	- fix really broken tds5_process_result
+-
+-Fri Sep 08 11:58:24 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/tds/threadsafe.c:
+-	- fix threadsafe problem on NetBSD
+-
+-Fri Sep 08 11:17:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/token.c: make splint a bit more happy
+-	* src/odbc/odbc.c: small 64bit improvements
+-
+-Thu Sep 07 23:10:29 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/sql2tds.c: fix paramset (Levente Tamási)
+-
+-Fri Sep  1 10:34:20 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h include/tdsstring.h src/ctlib/ct.c:
+-	* src/odbc/connectparams.c src/odbc/odbc.c src/server/login.c:
+-	* src/tds/config.c src/tds/tdsstring.c:
+-	- add dstr_size to DSTR
+-	- add tds_dstr_alloc, tds_dstr_setlen, tds_dstr_buf
+-
+-Wed Aug 30 13:58:56 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds.h src/tds/challenge.c src/tds/login.c:
+-	- make tds_answer_challenge return flags
+-	- tds_dstr fix
+-	* src/dblib/dblib.c: small fix
+-	* src/odbc/odbc.c: constification
+-	* src/tds/query.c:
+-	- some static functions rename
+-	- do not convert string in tds7_build_param_def_from_query
+-	* src/tds/threadsafe.c: cleanup
+-
+-Mon Aug 28 09:36:32 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/cspublic.h:
+-	- applied Norbert Sendetzky patch for ctlib compatibility
+-
+-Fri Aug 25 11:03:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/unittests/Makefile.am src/dblib/unittests/t0017.c:
+-	* src/dblib/unittests/t0017.in.be(added):
+-	- fix big endian problem with t0017 test
+-
+-Fri Aug 25 09:17:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: remove 1024 char limit on tsql_readline
+-
+-Thu Aug 24 21:18:48 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c: applied Christos Zoulas patch for no-tty
+-
+-Thu Aug 24 16:29:17 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/sybdb.h src/dblib/dblib.c:
+-	- do not change compatibility
+-	* src/tds/config.c: small optimization
+-
+-Thu Aug 24 11:37:15 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* m4/sprintf_i64_format.m4: fix 64bit problem for LP64
+-
+-Thu Aug 24 11:17:26 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tds_sysdep_private.h src/apps/tsql.c src/ctlib/Makefile.am:
+-	* src/dblib/Makefile.am src/tds/net.c win32/initnet.c:
+-	* win32/winsetup.c win32/dev-cpp/FreeTDS.dev:
+-	* win32/dev-cpp/Makefile.win win32/msvc6/FreeTDS.dsp:
+-	- initialize socket library on win32
+-
+-Thu Aug 24 08:32:07 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/apps/tsql.c:
+-	- do not print return status if quiet (patch from Christos Zoulas)
+-
+-Wed Aug 23 21:43:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/tsql.txt: applied Christos Zoulas updates
+-	* doc/txt2man: updated
+-
+-Wed Aug 23 17:16:10 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c:
+-	- clean error before reading SO_ERROR, some system need this
+-	* src/tds/util.c src/ctlib/ct.c: cross compile fixes
+-
+-Wed Aug 23 16:25:25 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* m4/ac_tds_func_which_getpwuid_r.m4 m4/sprintf_i64_format.m4:
+-	* configure.ac src/ctlib/cs.c src/apps/tsql.c:
+-	* src/replacements/asprintf.c src/tds/query.c:
+-	- fixes some cross compile issues with hp-ux
+-
+-Mon Aug 21 11:08:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/dblib/dblib.c: remove small buffer overflow
+-
+-Thu Aug 17 11:13:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac include/tds.h src/dblib/unittests/Makefile.am:
+-	* src/tds/net.c src/tds/query.c src/tds/token.c src/tds/util.c:
+-	* m4/acx_pthread.m4(added):
+-	- timeout more precise and use monotonic clock if available
+-	- check pthread support more deeply
+-
+-Wed Aug 16 13:04:48 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/net.c: cleanup, fix possible problem under Linux
+-	* src/tds/read.c: avoid invalid in_pos value on tds_peek
+-
+-Mon Aug 14 19:12:58 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c:
+-	* src/dblib/unittests/common.c:
+-	- fix warnings compiling with SUN cc
+-	* src/dblib/unittests/thread.c: make error more verbose
+-
+-Sun Aug 13 15:02:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c src/odbc/unittests/data.c:
+-	* src/odbc/unittests/transaction.c:
+-	- fix minor issues with 64-bit machines
+-
+-Thu Aug 10 10:10:30 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/ctlib/ct.c: fix possible buffer overflow
+-	* src/replacements/gettimeofday.c: add comment
+-	* src/tds/threadsafe.c: better and simple win implementation
+-	* vms/descrip_mms.template win32/config.h:
+-	* win32/dev-cpp/FreeTDS.dev win32/msvc6/libTDS.dsp:
+-	- update build file
+-
+-Tue Aug 08 19:14:32 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* doc/htdoc/index.html: update link
+-	* src/tds/query.c: add comment
+-
+-Tue Aug 08 16:42:39 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/query.c src/tds/util.c:
+-	- fix timeout problem setting correctly query_start_time
+-
+-Tue Aug 08 14:43:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/timeout2.c(added):
+-	- added a test for timeout problem (cf "Query Time Out" on ML)
+-
+-Mon Aug 07 21:37:39 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdsstring.h src/odbc/odbc_util.c:
+-	* src/replacements/iconv.c src/tds/challenge.c:
+-	* src/tds/config.c src/tds/convert.c:
+-	* src/tds/iconv.c src/tds/mem.c src/tds/net.c:
+-	* src/tds/query.c src/tds/read.c src/tds/tdsstring.c:
+-	* src/tds/token.c src/tds/write.c:
+-	- updated doxygen comments
+-
+-Sun Aug 06 17:54:11 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* freetds.spec.in: fix rpm build on suse
+-
+-Thu Aug 03 20:30:07 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* NEWS include/tds.h src/ctlib/ct.c src/odbc/odbc.c:
+-	* src/tds/mem.c src/tds/query.c src/tds/tds_checks.c:
+-	* src/tds/token.c src/tds/util.c:
+-	- use reference counting for TDSCURSOR to avoid memory errors
+-
+-Thu Aug 03 10:32:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/unittests/iconv_fread.c(added):
+-	* src/tds/iconv.c src/tds/unittests/.cvsignore:
+-	* src/tds/unittests/Makefile.am:
+-	- fix tds_iconv_fread and add a test for it
+-
+-Mon Jul 31 13:27:53 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/bcp.c
+-	- proper error message for using bcp with TDS version 4.2
+-
+-Mon Jul 31 13:23:44 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* include/sybdb.h src/dblib/dblib.c
+-	- proper error message for using bcp with TDS version 4.2
+-
+-Thu Jul 27 15:22:27 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* samples/odbc_rpc.pl	use fetchrow_array
+-	* src/tds/unittests/Makefile.am include parent directory
+-
+-Tue Jul 25 10:16:45 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac m4/ac_nullzero.m4: add test for portability
+-
+-Tue Jul 25 10:10:22 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/paramcore.c: updated
+-
+-Mon Jul 24 11:39:13 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/prepclose.c:
+-	- test with SQLExecDirect
+-
+-Mon Jul 17 15:18:48 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/unittests/build_dsw.pl(removed):
+-	* win32/build_dsw.pl(added) src/dblib/unittests/Makefile.am:
+-	* src/odbc/unittests/Makefile.am:
+-	- add a Makefile target to build projects for msvc6
+-
+-Thu Jul 13 10:20:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c src/odbc/unittests/moreandcount.c:
+-	- remove next_row_count, now useless... rpc.c works the same
+-
+-Wed Jul 12 13:23:43 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/odbc/odbc.c src/tds/token.c:
+-	- use TDS_NO_COUNT instead of bad rows_affected for next_row_count. 
+-	- src/odbc/unittests/rpc.c now works
+-
+-Wed Jul 12 16:15:14 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/test-other.sh: add file log
+-	* src/odbc/unittests/rpc.c: fix uninitialized error
+-
+-Tue Jul 11 17:52:43 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/odbc/odbc.c src/odbc/unittests/rpc.c:
+-	- Better logging
+-
+-Tue Jul 11 17:28:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/unittests/done_handling.c: improve
+-
+-Tue Jul 11 17:27:26 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/paramcore.c:
+-	- fix compatibility with sybase
+-
+-Tue Jul 11 11:56:53 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/online.pl: generate more friendly names
+-
+-Mon Jul 10 17:07:00 EDT 2006	JK Lowden <jklowden@freetds.org>
+-	* src/tds/token.c src/dblib/dblib.c src/dblib/unittests/rpc.c
+-	- dbresults does not return on DONEPROC
+-
+-Sun Jul 09 12:52:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* doc/Makefile.am: fix compatibility problem
+-	* src/odbc/unittests/rpc.c: fix warning
+-
+-Fri Jul  7 19:08:44 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* include/sybdb.h src/dblib/dblib.c src/tds/token.c:
+-	- Better logging
+-
+-Wed Jul 05 14:45:08 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/unittests/Makefile.am src/dblib/unittests/bcp.c:
+-	* src/dblib/unittests/common.c src/dblib/unittests/common.h:
+-	* src/dblib/unittests/dbmorecmds.c:
+-	* src/dblib/unittests/done_handling.c:
+-	* src/dblib/unittests/rpc.c src/dblib/unittests/t0001.c:
+-	* src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c:
+-	* src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c:
+-	* src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c:
+-	* src/dblib/unittests/t0008.c src/dblib/unittests/t0009.c:
+-	* src/dblib/unittests/t0011.c src/dblib/unittests/t0012.c:
+-	* src/dblib/unittests/t0013.c src/dblib/unittests/t0014.c:
+-	* src/dblib/unittests/t0015.c src/dblib/unittests/t0016.c:
+-	* src/dblib/unittests/t0017.c src/dblib/unittests/t0018.c:
+-	* src/dblib/unittests/t0019.c src/dblib/unittests/t0020.c:
+-	* src/dblib/unittests/t0021.c src/dblib/unittests/t0022.c:
+-	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c:
+-	* src/dblib/unittests/thread.c:
+-	* src/dblib/unittests/build_dsw.pl(added):
+-	- put include stuff in common.h
+-	- fix compile with ms dblib
+-	- simplify testing under windows creating project files
+-
+-Wed Jul  5 18:29:21 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/dblib.c src/dblib/rpc.c:
+-	- removed nonprintable characters from TDSDUMP log
+-
+-Wed Jul  5 15:43:24 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/unittests/rpc.c src/odbc/unittests/rpc.c:
+-	- more thorough tests, currently fail
+-
+-Tue Jul 04 17:13:08 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/paramcore.c(added):
+-	* src/odbc/unittests/.cvsignore src/odbc/sql2tds.c:
+-	- test for core using SQLBindParameter, small fix
+-
+-Mon Jul 03 13:09:40 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c:
+-	- assure there is always an error when SQL_ERROR is returned
+-	- fix warning
+-
+-Fri Jun 30 10:31:49 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/odbc/sql2tds.c assert good pointer in case user passed NULL
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/rpc.c
+-	- added new unit test, similar to that used in dblib.
+-
+-Thu Jun 29 17:05:35 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* NEWS src/tds/challenge.c:
+-	- fix small buffer overflow
+-	- reuse buffer
+-
+-Thu Jun 29 14:07:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds.h src/tds/Makefile.am src/tds/challenge.c:
+-	* src/tds/login.c src/tds/token.c:
+-	- add NTLM2 Session Response support
+-
+-Tue Jun 27 15:47:46 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/unittests/done_handling.c:
+-	- improve
+-	- update style
+-	- fix typo
+-
+-Mon Jun 26 16:10:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* phptests/rpc2.php(added):
+-	- test from Ellert van Koperen (cf "SP parameters" and 
+-	  http://kb.vankoperen.nl/freetds-problems.html)
+-
+-Sun Jun 25 10:12:48 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/warning.c:
+-	- tested
+-	- fix portability problem with former Sybase db
+-	- test returned warning
+-
+-Sun Jun 25 09:50:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/warning.c(added):
+-	- added warning test from John K. Hohm (cf 
+-	  "Warning return as copy of last result row" on ML)
+-	* src/odbc/unittests/describecol.c: compile fix
+-
+-Wed Jun 21 17:03:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/describecol.c:
+-	* src/odbc/unittests/describecol.in(added):
+-	- rewrote describecol test
+-
+-Wed Jun 21 09:26:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c: improve column_length
+-	* src/odbc/odbc_util.c: fix for odbc_sql_to_displaysize
+-	* src/tds/iconv.c: invalid iconv_t is only -1, not NULL
+-
+-Tue Jun 20 17:52:19 EDT 2006	Nick Castellano <entropy@freetds.org>
+-	* src/odbc/unittests/array_out.c:
+-	- rename variable to avoid libc	symbol conflict
+-
+-Tue Jun 20 14:38:03 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/tds/convert.c: use macro in sprintf
+-
+-Tue Jun 20 14:34:03 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/tds/mem.c: small macro to allocate columns
+-
+-Tue Jun 20 14:33:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/describecol.c: improved a lot
+-
+-Tue Jun 20 11:15:16 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c: catch error better
+-
+-Mon Jun 19 10:38:36 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* freetds.spec.in misc/test-other.sh src/apps/Makefile.am:
+-	* src/ctlib/Makefile.am src/dblib/Makefile.am src/odbc/Makefile.am:
+-	* src/server/Makefile.am src/tds/Makefile.am:
+-	*  src/tds/unittests/Makefile.am:
+-	- do not make libTDS shared library any more
+-
+-Mon Jun 19 09:57:23 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/ctlib/ct.c src/odbc/sql2tds.c src/odbc/unittests/data.c:
+-	* src/server/unittest.c:
+-	- remove warning compiling with gcc4
+-
+-Thu Jun 15 14:15:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* configure.ac src/ctlib/unittests/cancel.c:
+-	* src/dblib/unittests/common.c src/odbc/Makefile.am:
+-	* src/replacements/readpassphrase.c:
+-	- finished cross mingw32
+-
+-Wed Jun 14 17:34:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/convert_tds2sql.c: fix for date format
+-
+-Wed Jun 14 17:29:13 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* configure.ac: add function
+-	* src/apps/Makefile.am src/dblib/unittests/Makefile.am:
+-	* src/dblib/unittests/bcp.c src/odbc/unittests/Makefile.am:
+-	* src/replacements/Makefile.am src/replacements/gettimeofday.c:
+-	* src/tds/unittests/Makefile.am:
+-	- more fixes for cross mingw32
+-
+-Wed Jun 14 13:26:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds_sysdep_private.h src/apps/Makefile.am:
+-	- fix for cross mingw32
+-	* src/odbc/unittests/describecol.c: report more clearly problems
+-
+-Tue Jun 13 20:17:16 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/common.h src/server/unittest.c:
+-	- small fixes for cross mingw
+-
+-Tue Jun 13 14:38:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/prepclose.c(added) configure.ac:
+-	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
+-	- add test to test error closing connection on SQLPrepare
+-
+-Mon Jun 12 22:02:57 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* m4/sprintf_i64_format.m4: fix for cross mingw32
+-
+-Mon Jun 12 21:52:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/sql2tds.c: fix for possible uninitialized variable
+-
+-Mon Jun 12 21:48:15 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/apps/datacopy.c src/apps/freebcp.c src/apps/freebcp.h:
+-	* src/pool/main.c src/pool/pool.h:
+-	- fix some issues cross compiling for mingw32
+-
+-Mon Jun 12 16:55:59 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/data.c: add test for date to char
+-
+-Fri Jun  9 14:33:31 EDT 2006	Nick Castellano <entropy@freetds.org>
+-	* src/apps/tsql.c: inhibit readline tab completion in tsql
+-
+-Fri Jun 09 11:50:55 EDT 2006	Nick Castellano <entropy@freetds.org>
+-	* locales.conf: use same date format as Sybase in default and en_US
+-
+-Thu Jun 08 10:18:50 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/tds/unittests/t0007.c:
+-	- improved to detect possible date problems
+-
+-Wed Jun 07 14:37:56 EDT 2006	Nick Castellano <entropy@freetds.org>
+-	* src/tds/convert.c: correctly convert dates in January
+-
+-Tue Jun 06 12:02:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* configure.ac src/tds/config.c:
+-	- fix tsql -C for sybase compatibility
+-
+-Tue Jun 06 11:32:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/tds/mem.c: use calloc instead of malloc/memset
+-
+-Mon Jun 05 13:42:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/ctlib/ct.c src/tds/token.c:
+-	- style and cleanup
+-
+-Mon May 29 13:38:05 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* m4/sprintf_i64_format.m4: fix quoting
+-
+-Mon May 29 12:58:38 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* NEWS include/tds.h src/tds/token.c:
+-	- make tds_alloc_get_string static
+-
+-Mon May 15 17:11:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c:
+-	- applied fixes from Charlene Herring (cf. "Problems when
+-	  using odbc : SQLPutData, SQLExecDirect,Decimals" 2006/05/14
+-
+-Sun May 14 14:34:04 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/descriptor.c: fix memory error
+-
+-Sat May 13 10:49:40 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/copydesc.c: improve
+-
+-Mon May 08 11:38:30 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/descriptor.c src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/copydesc.c(added): add test for SQLCopyDesc
+-
+-Fri Apr 21 17:10:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/sql2tds.c: use new tds_convert types
+-
+-Fri Apr 21 09:45:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* doc/htdoc/faq.html: fix html compatibility
+-
+-Thu Apr 20 12:10:28 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/ctlib/unittests/ct_dynamic.c: remove leak in test
+-
+-Tue Apr 17 19:47:57 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/ctlib/ct.c: fix double free
+-
+-Mon Apr 17 10:51:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/convert_tds2sql.c src/odbc/prepare_query.c:
+-	- use new conversion style in ODBC
+-
+-Sun Apr 16 10:11:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds.h src/tds/locale.c src/tds/mem.c:
+-	- TDSLOCALE changes to keep ABI
+-
+-Sat Apr 15 10:18:29 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tdsconvert.h 	* src/tds/convert.c:
+-	- add new type of conversion for copy optimizations
+-
+-Sat Apr 15 10:02:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/describecol.c: fix for older Sybase versions
+-	* src/tds/config.c: optimize option read
+-
+-Sat Apr 15 09:03:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/describecol.c: remove warning
+-
+-Fri Apr 14 15:22:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/describecol.c:
+-	- improved
+-
+-Fri Apr 14 13:55:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/describecol.c:
+-	- add test for precision returned by SQLDescribeCol
+-
+-Wed Apr 12 21:41:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* locales.conf: fix charset typo
+-	* doc/userguide.sgml: fix attributes for locales.conf
+-
+-Wed Apr 12 15:53:18 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds.h include/tds_sysdep_private.h:
+-	* include/tds_sysdep_public.h.in include/tdsconvert.h:
+-	* include/tdsver.h.in:
+-	- avoid ident strings in all objects
+-	* m4/sprintf_i64_format.m4: add Ld format
+-
+-Tue Apr 11 16:33:41 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds_sysdep_public.h.in include/tdsver.h.in:
+-	- small constification
+-
+-Tue Apr 11 13:51:43 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/connect.c: do not fail if not FreeTDS
+-	* src/odbc/unittests/raiserror.c: more verbose
+-
+-Mon Apr 10 18:14:17 EDT 2006	JK Lowden <jklowden@schemamania.org>
+-	* include/tds.h src/apps/tsql.c src/tds/config.c
+-	- report sysconfdir with tsql -C
+-
+-Mon Apr 10 11:59:53 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c: cleanup
+-
+-Fri Apr 07 09:38:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/test-other.sh: update to php 5.1
+-	* phptests/nextres.php: a bit more verbose
+-
+-Thu Apr 06 11:37:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/coverage.sh: less verbose 
+-	* src/dblib/bcp.c: small change
+-
+-Wed Apr 05 08:42:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/full-test.sh: cleanup
+-	* misc/test-auto.sh: allow configuration
+-	* misc/test-other.sh: make output suitable for online.pl
+-	* src/apps/tsql.c:
+-	- improve documentation
+-	- fix problem for multiple options
+-	* src/odbc/odbc.c src/tds/token.c: avoid void message to application
+-
+-Wed Apr 05 07:09:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c: remove some warnings
+-
+-Wed Mar 29 18:25:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* m4/ac_caolan_func_which_gethostbyname_r.m4:
+-	* m4/ac_have_inaddr_none.m4 m4/ac_have_malloc_options.m4:
+-	* m4/ac_raf_func_which_getservbyname_r.m4:
+-	* m4/ac_tds_func_which_gethostbyaddr_r.m4:
+-	* m4/ac_tds_func_which_getpwuid_r.m4:
+-	* m4/ac_tds_func_which_localtime_r.m4:
+-	* m4/ax_cflags_gcc_option.m4 m4/lib-link.m4:
+-	* m4/sprintf_i64_format.m4 m4/type_socklen_t.m4:
+-	- quote as necessary
+-
+-Mon Mar 27 19:01:05 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* configure.ac
+-	* m4/ac_caolan_func_which_gethostbyname_r.m4
+-	* m4/ac_have_inaddr_none.m4
+-	* m4/ac_have_malloc_options.m4
+-	* m4/ac_raf_func_which_getservbyname_r.m4
+-	* m4/ac_tds_func_which_gethostbyaddr_r.m4
+-	* m4/ac_tds_func_which_getpwuid_r.m4
+-	* m4/ac_tds_func_which_localtime_r.m4
+-	* m4/ax_cflags_gcc_option.m4
+-	* m4/sprintf_i64_format.m4
+-	* m4/type_socklen_t.m4
+-	* src/ctlib/unittests/Makefile.am
+-	* src/dblib/unittests/Makefile.am
+-	* src/odbc/unittests/Makefile.am
+-	* src/tds/unittests/Makefile.am
+-	- removed/updated obsolete autoconf macros
+-	* m4/am_iconv.m4 removed 
+-	* m4/README.iconv
+-	* m4/iconv.m4 m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4
+-	- added from GNU libiconv
+-
+-Mon Mar 27 09:48:56 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* doc/htdoc/index.html corrected nightly test link
+-
+-Mon Mar 27 10:17:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/rpc.c: allow again null for fixed types
+-
+-Mon Mar 27 02:20:16 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* configure.ac m4/am_iconv.m4 m4/check_openssl.m4
+-	* src/apps/Makefile.am src/ctlib/Makefile.am src/dblib/Makefile.am
+-	* src/odbc/Makefile.am src/pool/Makefile.am src/replacements/Makefile.am
+-	* src/server/Makefile.am src/tds/Makefile.am
+-	- modernized autotool contructs
+-	* configure.in removed 
+-
+-Sun Mar 26 19:01:43 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/prepare_query.c:
+-	- fixed constant parameters after mssql 2005 patch
+-
+-Fri Mar 24 16:47:26 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* configure.in removed, is now configure.ac 
+-	* acinclude.m4 removed, added m4 directory
+-	* Makefile.am include m4 directory
+-	* m4/ac_caolan_func_which_gethostbyname_r.m4 m4/ac_have_inaddr_none.m4
+-	* m4/ac_have_malloc_options.m4 m4/ac_raf_func_which_getservbyname_r.m4
+-	* m4/ac_tds_func_which_gethostbyaddr_r.m4 
+-	* m4/ac_tds_func_which_getpwuid_r.m4 
+-	* m4/ac_tds_func_which_localtime_r.m4 m4/am_iconv.m4 
+-	* m4/check_openssl.m4 m4/sprintf_i64_format.m4 m4/type_socklen_t.m4
+-	- Split acinclude.m4 into one macro defintion per file.
+-	* m4/ax_cflags_gcc_option.m4 
+-	- Check for gcc features e.g. the declaration-after-statement warning.
+-
+-Fri Mar 24 13:03:36 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* doc/htdoc/docs.html doc/htdoc/index.html updated
+-
+-Fri Mar 24 12:36:02 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* doc/htdoc/software.html fixed broken links added link to RC
+-
+-Fri Mar 24 16:27:27 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/full-test.sh misc/test-auto.sh misc/full-test-ol.sh(removed):
+-	- use an "online" version for test
+-
+-Thu Mar 23 15:53:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/sql2tds.c src/odbc/unittests/earlybind.c:
+-	* src/odbc/unittests/norowset.c src/odbc/unittests/t0004.c:
+-	* src/odbc/unittests/tables.c src/tds/data.c src/tds/tds_checks.c:
+-	- fixes for mssql 2005
+-
+-Thu Mar 23 13:48:23 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/tds/query.c: partially fix problem with mssql2k5
+-
+-Thu Mar 23 11:44:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/full-test-ol.sh misc/online.pl misc/test-auto.sh:
+-	- changed online.pl with James hints
+-	- enable Valgrind tests using online check
+-
+-Tue Mar 21 15:24:04 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/cursor2.c(aded) src/odbc/unittests/Makefile.am:
+-	- added test to check errors using cursor on no row statement
+-
+-Tue Mar 21 13:22:07 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/native.c:
+-	- applied patch from Richard Krehbiel (cf "ODBC datetime literal issue")
+-
+-Tue Mar 21 08:49:44 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* configure.in src/dblib/dblib.c:
+-	- fix declaration after statements
+-
+-Mon Mar 20 15:28:25 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/bcp.c: fix error in bcp_colfmt
+-
+-Mon Mar 20 15:00:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
+-	- remove some double checks
+-	- return correct values from CHECK_PARAMETER
+-	- fix some possible core if dbproc == NULL
+-
+-Mon Mar 20 09:42:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/full-test.sh: added timeout
+-
+-Sun Mar 19 18:34:47 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* misc/test-auto.sh: fix typo in header
+-	* src/dblib/dblib.c: remove double checks
+-
+-Sun Mar 19 18:33:14 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/genparams.c src/odbc/unittests/transaction.c:
+-	- remove warnings on 64bit int
+-
+-Sun Mar 19 09:27:09 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/bcp.c src/dblib/dblib.c more logging repairs
+-
+-Sat Mar 18 12:34:02 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* include/dblib.h src/dblib/bcp.c
+-	- validate parameters.  Unable to run unittest due to down server.
+-
+-Sat Mar 18 01:27:32 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* include/dblib.h src/dblib/dblib.c src/dblib/rpc.c
+-	- test parameters for all public functions (except bcp)
+-
+-Fri Mar 17 01:35:17 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/dblib.c src/dblib/rpc.c
+-	- added a TDSDUMP log entry for every public function
+-
+-Thu Mar 16 09:59:25 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* TODO add rpc error messages
+-	* src/apps/bsqldb.c exit if severity > 10
+-
+-Wed Mar 15 00:41:11 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* doc/freebcp.txt The freebcp manpage was seriously out of date.
+-	* src/apps/freebcp.c give better error message.
+-
+-Thu Mar  9 14:33:37 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tdsodbc.h src/odbc/odbc.c:
+-	- add cursor_type to connection attributes (required for DBD::ODBC)
+-	- removed small TODO on error report
+-
+-Mon Mar  6 12:55:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds.h src/ctlib/ct.c src/odbc/connectparams.c:
+-	* src/pool/util.c src/server/login.c src/server/unittest.c:
+-	* src/tds/config.c src/tds/login.c src/tds/mem.c:
+-	- renamed host_name field to client_host_name
+-	- optimize way strings are allocated
+-
+-Fri Feb 24 15:04:35 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/tds/config.c src/tds/login.c:
+-	- nicer TDSDUMPCONFIG output, including a recap
+-
+-Sun Feb 19 14:56:15 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/odbc.c: fix wrong declaration
+-
+-Thu Feb 16 08:30:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/scroll.c src/odbc/unittests/raiserror.c:
+-	* src/odbc/unittests/cursor1.c:
+-	- remove warning compiling with gcc4
+-	* misc/test-other.sh: fix problem with DBD:ODBC test
+-
+-Mon Feb 13 17:11:30 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/genparams.c: add BIGINT type to test
+-
+-Wed Feb  8 10:48:36 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
+-	* vms/odbc_driver_axp.opt win32/FreeTDS.def:
+-	- start cursor stuff for odbc
+-	- added SQLSetScrollOptions
+-	* src/odbc/unittests/scroll.c: support more fetch types
+-
+-Tue Feb  7 15:42:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/tds.h src/tds/query.c src/ctlib/ct.c NEWS:
+-	- improve cursor support
+-
+-Tue Feb  7 14:22:50 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/scroll.c(added):
+-	* src/odbc/unittests/.cvsignore:
+-	* src/odbc/unittests/Makefile.am:
+-	* src/odbc/unittests/cursor1.c:
+-	- add scroll test for cursor
+-	- build msvc project for odbc unittests
+-	* src/dblib/unittests/Makefile.am: add done_handling test
+-
+-Mon Feb  6 16:50:05 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* include/sybdb.h src/apps/freebcp.c src/dblib/bcp.c:
+-	- implemented BCPKEEPIDENTITY for bcp_control
+-	- make freebcp do not depend on dblib internals
+-
+-Mon Feb  6 16:44:27 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/odbc/unittests/.cvsignore src/odbc/unittests/cursor1.c:
+-	- update cursor1 test
+-
+-Thu Feb  2 15:33:21 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* NEWS: updated
+-	* src/odbc/odbc.c vms/odbc_driver_axp.opt win32/FreeTDS.def:
+-	- compile SQLSetPos function
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/cursor1.c(added):
+-	- added a test for cursors (do not work...)
+-
+-Tue Jan 31 14:27:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/apps/freebcp.c src/dblib/bcp.c:
+-	- fix broken charcater conversion
+-	- use calloc instead of malloc/memset
+-	- support 64bit file on win32
+-
+-Tue Jan 31 09:59:28 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/dblib.c: do more argument check
+-
+-Mon Jan 30 16:29:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/ctlib/unittests/blk_out.c src/ctlib/unittests/ct_cursor.c:
+-	* src/ctlib/unittests/ct_cursors.c src/ctlib/unittests/ct_dynamic.c:
+-	* src/dblib/unittests/t0005.c src/dblib/unittests/t0014.c:
+-	* src/dblib/unittests/t0022.c src/dblib/unittests/thread.c:
+-	- reduce false errors
+-
+-Sat Jan 28 15:49:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/bcp.c:
+-	- update row allocation using new row_free
+-	- fix native format
+-	- correctly check and handle EOF
+-	- change _bcp_build_bcp_record to direct send row (renamed to 
+-	  _bcp_send_bcp_record)
+-	- write error file only if needed
+-	* src/dblib/unittests/t0016.c: improved
+-	* src/dblib/unittests/t0016.in:
+-	- make input same of output
+-	* src/dblib/unittests/t0017.c: get all data
+-	* src/tds/mem.c: reset pointer just freed
+-
+-Sat Jan 28 09:39:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/unittests/t0017.c: reformat output
+-
+-Fri Jan 27 14:34:09 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/bcp.c recognize EOF errors from _bcp_read_hostfile
+-
+-Fri Jan 27 10:43:54 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/dblib/unittests/t0017.c better feedback
+-
+-Thu Jan 26 13:58:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/apps/freebcp.c src/apps/freebcp.h:
+-	- support for NUL in terminators
+-
+-Wed Jan 25 15:33:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* src/dblib/bcp.c: fix return test for fseeko
+-
+-Wed Jan 25 15:01:51 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* acinclude.m4 configure.in src/tds/numeric.c:
+-	- use 64bit sprintf format if available
+-	* misc/test-other.sh: redirect odbc to compiled driver
+-
+-Tue Jan 24 16:01:41 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* NEWS include/tds.h src/apps/tsql.c src/ctlib/blk.c:
+-	* src/ctlib/ct.c src/dblib/bcp.c src/dblib/buffering.h:
+-	* src/dblib/dblib.c src/dblib/rpc.c src/odbc/odbc.c:
+-	* src/odbc/odbc_util.c src/odbc/prepare_query.c:
+-	* src/odbc/sql2tds.c src/pool/stream.c src/server/server.c:
+-	* src/tds/mem.c src/tds/query.c src/tds/tds_checks.c:
+-	* src/tds/token.c src/tds/unittests/dataread.c:
+-	* src/tds/unittests/dynamic1.c src/tds/unittests/t0002.c:
+-	* src/tds/unittests/t0004.c src/tds/unittests/t0005.c:
+-	* src/tds/unittests/t0006.c src/tds/unittests/utf8_1.c:
+-	* src/tds/unittests/utf8_2.c:
+-	- use direct pointer column_data instead of old column_offset
+-
+-Mon Jan 23 17:30:38 EST 2006	JK Lowden <jklowden@schemamania.org>
+-	* src/apps/bsqldb.c bind to printable width, not column size
+-
+-Mon Jan 23 14:04:44 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
+-	* configure.in: start developing 0.65 version
+-$Id: ChangeLog-0.82,v 1.1.2.2 2008/01/10 20:58:43 jklowden Exp $
+diff --git b/INSTALL.CVS a/INSTALL.CVS
+index c23f6b7..d42c3aa 100644
+--- b/INSTALL.CVS
++++ a/INSTALL.CVS
+@@ -16,9 +16,9 @@ connecting to the CVS server.  Then follow these steps:
+ 	
+ 	Autotool versions that work:
+ 	$ (autoconf --version; automake --version; libtool --version) |grep GNU
+-	autoconf (GNU Autoconf) 2.60
+-	automake (GNU automake) 1.9.6
+-	ltmain.sh (GNU libtool) 1.5.18 (1.1220.2.245 2005/05/16 08:55:27)
++	autoconf (GNU Autoconf) 2.59
++	automake (GNU automake) 1.9.5
++	ltmain.sh (GNU libtool) 1.5.14 (1.1220.2.195 2005/02/12 12:12:33)
+ 	
+ 	The above are used to generate the distributions.  
+ 	You may get away with older versions, as far back as 2.53 for autoconf.
+@@ -44,10 +44,10 @@ connecting to the CVS server.  Then follow these steps:
+ 	
+ +++
+ 
+-You are not required to rely on SourceForge's anonymous CVS server, which at
++You are not required to rely on Source Forge's anonymous CVS server, which at
+ the present time (July 2004) runs up to 1 hour behind the development server. 
+ You can fetch the CVS tarball (the basis for a CVS server, not a snapshot) from
+-SourceForge at:
++Source Forge at:
+ 
+ http://cvs.sourceforge.net/cvstarballs/freetds-cvsroot.tar.bz2
+ 
+@@ -62,4 +62,4 @@ the CVS tree via rsync:
+ $ rsync -av rsync://freetds.cvs.sourceforge.net/cvsroot/freetds/* .
+ 	
+ --
+-$Id: INSTALL.CVS,v 1.7.2.1 2008/01/10 20:58:43 jklowden Exp $
++$Id: INSTALL.CVS,v 1.7 2007/04/05 14:17:05 freddy77 Exp $
+diff --git b/NEWS a/NEWS
+index fd44001..851fbce 100644
+--- b/NEWS
++++ a/NEWS
+@@ -1,63 +1,33 @@
+-$Id: NEWS,v 1.43.2.1 2008/01/10 20:58:43 jklowden Exp $
+-
+-Executive Summary of Changes in release 0.82
+---------------------------------------------
+-
+-1.  timeout handling
+-2.  encrypted connections
+-3.  fisql (and odbc utilities)
+-4.  autoconf improvements
+-5.  23,710 lines added or deleted (101,022 total).
+-6.  85 files added
+-7.  21 unit tests added
+-
+-Details
+--------
+-
+-db-lib
+-- timeouts work! 
+-- corrected dbnextrow 
+-- implemented dbsetnull and dbsetinterrupt
+-- improved error reporting and checking
+-- fixed rpc parameter processing, now php works correctly
+-
+-ct-lib
+-- added cs_loc_alloc, cs_loc_drop, cs_locale implementations
+-
+-odbc
+-- cursors (mssql)
+-- fixed database setting 
+-- return error always if odbc returns SQL_ERROR
+-- fixed SQLGetData result
+-
+-utilities
+-- added support for NUL characters inside terminators in freebcp
+-- added row termination and column termination option to tsql
+-- new fisql application
+-- new ODBC utilities
+-
+-documentation
+-- significant updates to TDS protocol documentation
+-- freetds.conf man page
+-- added tenderfoot sample code
+-
+-general
+-- fixed timeout handling
+-- added freetds.conf option for encryption
+-- added protocol version discovery
++$Id: NEWS,v 1.43 2008/01/08 13:29:40 freddy77 Exp $
++* 0.82
++- support NUL characters inside terminators in freebcp
++- cursors under ODBC (mssql)
+ - NTLM2 session response
+-- read table and real column name from wire
+-- experimental Kerberos support using gssapi
++- lot of update to TDS protocol documentation
+ - some optimizations for GCC4
+ - optimized conversions avoiding some memory copy
+ - minor improves to server stuff
+-- improved MingW compile (even cross one)
++- add row termination and column termination option to tsql
++- improve locale stuff on ctlib
++  added cs_loc_alloc, cs_loc_drop, cs_locale implementations
++- improve MingW compile (even cross one)
++- implement dbsetnull on dblib
++- improve dblib error reporting and check
+ - more verbose log for dblib and odbc
++- fix rpc parameter on dblib, now php works correctly
+ - many test added
+   1 test for libTDS
+   1 test for ctlib
+   3 tests for dblib
+   13 tests for odbc
++- fix database setting on odbc
++- fix timeout stuff
++- return always an error if odbc return SQL_ERROR
++- fix SQLGetData result
++- add freetds.conf option for encryption
++- add protocol version discovery
++- read table and real column name from wire
++- experimental Kerberos support using gssapi
+ 
+ libTDS API changes
+ - tds_add_row_column_size removed
+@@ -68,7 +38,7 @@ libTDS API changes
+ - added TDSCURSOR->type and TDSCURSOR->concurrency for mssql support
+ - added fetch_type and i_row parameters to tds_cursor_fetch
+ - added tds_cursor_update and tds_cursor_setname functions
+-- made tds_alloc_get_string static
++- make tds_alloc_get_string static
+ - removed tds_free_cursor
+ - added TDSCURSOR->ref_count
+ - added tds_cursor_deallocated and tds_release_cursor to handle
+@@ -78,8 +48,8 @@ libTDS API changes
+   to trace pointer owner between libTDS and upper libraries
+ - added TDS_COMPILETIME_SETTINGS->sysconfdir
+ - changed DSTR_STRUCT structure to include dstr_size
+-- changed DSTR type
+-- error handler cannot return TDS_INT_EXIT
++- change DSTR type
++- error handler cannot return TDS_INT_EXIT (no more defined)
+ - removed TDSSOCKET->query_timeout_func TDSSOCKET->query_timeout_param,
+   TDSSOCKET->query_start_time
+ - changed TDSLOGIN->host_name to client_host_name
+@@ -113,6 +83,7 @@ libTDS API changes
+ - added TDSSOCKET->tds9_transaction (used internally for TDS9)
+ - added TDSCONNECTION->server_host_name needed for Kerberos support
+ 
++
+ * 0.64
+ - core library
+  - reduced network bandwidth use on Linux and *BSD
+diff --git b/README a/README
+index 2de3e4c..33da879 100644
+--- b/README
++++ a/README
+@@ -1,11 +1,12 @@
+-README for FreeTDS 0.82
+-Thusday 10 January 2008
++$Id: README,v 1.11 2007/04/05 14:17:05 freddy77 Exp $
++README for FreeTDS 0.64
++Saturday 1 July 2006
+ 
+-* to build FreeTDS read the file INSTALL or
+-  the FreeTDS Users Guide (doc/userguide.tgz) and 
++* to build FreeTDS read the file INSTALL,
++* see also the FreeTDS Users Guide,
+   http://www.freetds.org/userguide/
+ 
+-FreeTDS is a free implementation of Sybase's db-lib,
++FreeTDS is a free (open source) implementation of Sybase's db-lib,
+ ct-lib, and ODBC libraries. FreeTDS builds and runs on every flavor of
+ unix-like systems we've heard of, as well as Win32 (with or without
+ Cygwin), VMS, and Mac OS X.  Failure to build on your system is probably
+@@ -26,8 +27,60 @@ TODO		The roadmap, such as it is
+ 
+ Also, doc/api_status.txt shows which functions are implemented.  
+ 
+-For details on what's new in this version, see NEWS.  For unbearable 
+-detail, see ChangeLog-0.82.
++************************************
++** Warning regarding Sybase 12.5! **
++************************************
++
++Do Not Use TDS version 4.2 to connect to Sybase 12.5. Please!  
++
++While we don't like to put the bad news first, neither do we want you to
++hurt your server.  We know that our implementation of TDS 4.2 gives
++Sybase 12.5 a bad case of heartburn.  In short: it crashes the server.  
++
++We don't know what it is about our version of TDS 4.2 that Sybase 12.5
++doesn't like, and we'd like to figure it out eventually.  But in the
++meanwhile, until we can find the problem and fix it, please don't use
++that combination.  Unless you want to help us test it, that is.  
++
++FreeTDS 0.63 works fine with Sybase 12.5 if you use TDS version 5.0.  
++
++If you are using Sybase 12.5 and anything above is not clear to you,
++please see the User Guide.  If it is still not clear after that, please
++write to the FreeTDS mailing list.  We'd rather answer your questions
++while your server is still running.  
++
++Thank you.  We return now to your regularly scheduled README, already in
++progress. 
++
++New in this version
++===================
++
++ct-lib
++------
++
++Ct-lib now sports bcp and cursors.  The largest missing feature is now
++placeholder support compatible with Perl's DBD::Sybase.  
++
++ODBC
++----
++
++ODBC continues to be improved.  It is now compatible with OpenOffice.org, for
++example, and even works with Oracle's OTL libary.  It has better 64-bit
++support.  
++
++Applications
++------------
++
++This version includes two new applications, bsqldb and defncopy.  See their man
++pages for details.  
++
++etc.
++----
++
++Naturally, there have been other improvements as well.  This version compiles
++and runs better than its predecessors.  
++
++
+ 
+ Documentation
+ =============
+@@ -86,6 +139,3 @@ Side note: Brian, as many free software authors, appreciates postcards
+ from all over. So if you live someplace neat (read: not Michigan) and
+ want to send one, email him (brian@bruns.org) for his current snail mail
+ address.
+-
+-$Id: README,v 1.11.2.1 2008/01/10 20:58:43 jklowden Exp $
+-
+diff --git b/TODO a/TODO
+index 9b7c295..6b770b4 100644
+--- b/TODO
++++ a/TODO
+@@ -4,11 +4,11 @@ followed by things that should work before the next release,
+ followed by features that should be added/fixed/reworked (grouped by library).  
+ 
+ Everyone is encouraged to add to the list.  Developers can do it directly; 
+-anyone else can post a patch to SourceForge.  
++anyone else can post a patch to Source Forge.  
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.165.2.1 2008/01/10 20:58:43 jklowden Exp $
++To Do List	$Id: TODO,v 1.165 2007/12/26 20:56:00 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -30,13 +30,20 @@ Broken:
+ 
+ Work in progress:
+ 
++Postponed to 0.65 version
+ . log and call error handler on problems with tds_iconv_init().
+ . iconv
+   - support string conversions for Sybase
++  - add test for locale_charset() to configure.in.  Use it if available
++    instead of nl_langinfo, because it implies we're using GNU iconv
+ . add doc/htdoc/Makefile with "publish" target to commit cvs and update
+   freetds.org
+ . drop txt2man from cvs, skip building man pages without it. 
+ . be able to disable iconv for BCP (see Sybase documentation)
++. userguide
++  - update table of working configurations
++    server (vendor, version, platform) - client (freetds version, platform) 
++    - protocol - charsets - date
+ 
+ For future versions (in priority order within library):
+   All:
+@@ -52,6 +59,7 @@ For future versions (in priority order within library):
+ . Add missing constants needed for python and verify working
+ . Add missing constants needed for Gnome-DB and verify working 
+ . conversion from ucs2 to utf8, provide for 2+ bytes/character
++. tdsping program for testing purposes
+ . Finish off the TDS dissector for ethereal
+ . more solid. handle out of memory conditions (started, we must test all 
+   allocation and all function that return allocated data and be able to 
+@@ -73,8 +81,8 @@ For future versions (in priority order within library):
+   (too complicate, see ctlib bulk, cf "bulk copy and row buffer")
+ . improve cursor support on dblib and ctlib
+ . support for VARIANT type (requested one time, 2003-8-1)
+-. support for NT named pipe (requested long ago for mssql6.5 server, only
+-  for completeness). If the reader knows a library to handle named pipes
++. support for NT named pipe (requested many time ago for mssql6.5 server, only
++  for completeness). If anybody knows a library to handle named pipes
+   compatible with LGPL please tell us.
+ . read on partial packet, do not wait entire one
+ . detect if realloc/free accepts NULL pointers (in configure.in)
+@@ -123,14 +131,6 @@ For future versions (in priority order within library):
+ . report error just before returning SQL_ERROR from inner function?
+ 
+ . test and fix: hidden fields (FOR BROWSE select, see flag test on tds)
+- - what happen if we bind to an hidden field??
+- - if we use SQLGetData??
+- - if we request informations with SQLDescribeCol/SQLColAttribute(s)/
+-   SQLGetDescField??
+- - as you noted returning # columns hidden fields are not counted (there
+-   is however a setting which is a mssql extension which threat hidden
+-   columns as normal)
+- (cfr "SQLNumResultCols() is wrong (+1)" Jan 8 2008)
+ . test: all binding types (input and output)
+ . test: descriptors work
+   - ODBC 2 type returned (datetime)
+diff --git b/doc/userguide.sgml a/doc/userguide.sgml
+index 2a09e0f..d26bb2e 100644
+--- b/doc/userguide.sgml
++++ a/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/01/10 20:58:43 $</date>
+-		<releaseinfo>$Revision: 1.110.2.1 $</releaseinfo>
++		<date>$Date: 2008/01/08 13:29:40 $</date>
++		<releaseinfo>$Revision: 1.110 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -26,7 +26,6 @@
+ 		  <year>2005</year>
+ 		  <year>2006</year>
+ 		  <year>2007</year>
+-		  <year>2008</year>
+ 		  <holder>Brian Bruns and James K. Lowden</holder>
+ 		</copyright>
+ 		<legalnotice><para>
+@@ -56,9 +55,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.110.2.1 $</>
+-<member>$Date: 2008/01/10 20:58:43 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.110.2.1 2008/01/10 20:58:43 jklowden Exp $.</>
++<member>$Revision: 1.110 $</>
++<member>$Date: 2008/01/08 13:29:40 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.110 2008/01/08 13:29:40 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -202,7 +201,7 @@ project on SourceForge.  It is a fork of the
+ 		<sect2 id="Status">
+ 			<title>Status</title>
+ 			<para>
+-The <systemitem class="library">db-lib</systemitem> and <systemitem class="library">ct-lib</systemitem> <acronym>API</>s have been usable for several years.  They have been successfully  substituted for Sybase's own libraries in a variety of venues, including <productname>Perl</productname> and <productname>PHP</productname>.  That is not to say that these drivers are complete; they're not.  But they faithfully implement a useful &mdash; and widely used &mdash; subset of their <acronym>API</>s.  
++The <systemitem class="library">db-lib</systemitem> and <systemitem class="library">ct-lib</systemitem> <acronym>API</>s have been usable for several years.  They have been successfully  substituted for Sybase's own libraries in a variety of venues, including <productname>Perl</productname> and <productname>PHP</productname>.  That is not to say that these drivers are complete; they're not.  But they faithfully implement an important subset of their <acronym>API</>s, enough to be useful.  This 0.64 version boasts support for server-side cursors in <systemitem class="library">ct-lib</systemitem>.  
+ 			</para>
+ 			<para>
+ In addition to the core <systemitem class="library">db-lib</systemitem> <acronym>API</>, <productname>FreeTDS</productname>  includes a full implementation of <systemitem class="library">db-lib</systemitem>'s <acronym>bcp</> functions, as well as <command>freebcp</>, a replacement for Sybase's <application>bcp</application> utility.  
+@@ -568,7 +567,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/01/10 20:58:43 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/01/08 13:29:40 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -942,7 +941,8 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ 	<entry>instance</entry>
+ 	<entry>instance name</entry>
+ 	<entry>none</entry>
+-	<entry><para>Name of Microsoft SQL Server <emphasis>instance</> to connect to. The port will be detected automatically.</para></entry>
++	<entry><para>Name of Microsoft SQL Server <emphasis>instance</> to connect to. The port will be detected automatically.
++		<note><para>This requires an extra round-trip with server and may thus slightly delay making the connection.</para></note></para></entry>
+ 	</row>
+ 	<row>
+ 	<entry>debug flags</entry>
+@@ -1512,7 +1512,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<entry><literal>Server</></entry>
+ 	<entry>A server name or (ip) address</entry>
+ 	<entry>none</entry>
+-	<entry>Hostname of a server. Used in an ODBC-only configuration. To specify a Microsoft SQL Server instance, use the form <literal>server\instance</literal>.  </entry>
++	<entry>Hostname of a server. Used in an ODBC-only configuration. As of version 0.64 you can specify a Microsoft SQL Server instance in the form of <literal>server\instance</literal>.  </entry>
+ 	</row>
+ 	<row>
+ 	<entry><literal>Port</></entry>
+
+commit b8d8661289abc8745b33e8e24da31decdf21c1bd
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 13:22:19 2008 +0000
+
+    fix SQLGetData problem
+
+diff --git b/src/odbc/unittests/Makefile.am a/src/odbc/unittests/Makefile.am
+index 8146c2a..8f38676 100644
+--- b/src/odbc/unittests/Makefile.am
++++ a/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.68.2.2 2008/01/10 13:22:19 freddy77 Exp $
++# $Id: Makefile.am,v 1.68.2.1 2008/01/10 08:52:46 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -20,7 +20,7 @@ TESTS		=	\
+ 			paramcore$(EXEEXT) timeout2$(EXEEXT) timeout3$(EXEEXT) \
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+-			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT)
++			attributes$(EXEEXT) hidden$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -78,7 +78,6 @@ cursor4_SOURCES	= cursor4.c common.c common.h
+ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
+ hidden_SOURCES	= hidden.c common.c common.h
+-blob1_SOURCES	= blob1.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+
+commit 9fbbe664420fa49e8611bfede300a90dd293229e
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 13:13:46 2008 +0000
+
+    fix SQLGetData problem
+
+diff --git b/ChangeLog a/ChangeLog
+index d054e6f..ecb6523 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,8 +1,3 @@
+-Thu Jan 10 14:12:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+-	* src/odbc/unittests/Makefile.am src/odbc/unittests/blob1.c(added):
+-	- fix problem with SQLGetData and blobs
+-
+ Thu Jan 10 09:51:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am:
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 60c8e00..7d33b27 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.2 2008/01/10 13:13:46 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.1 2008/01/10 08:52:45 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4583,12 +4583,12 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		if (*pcbValue < 0)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 
+-		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
++		if (is_variable_type(colinfo->column_type)) {
+ 			/* calc how many bytes was readed */
+ 			int readed = cbValueMax;
+ 
+ 			/* FIXME test on destination char ??? */
+-			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR /* is_char_type(nSybType) */ && readed > 0)
++			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && is_char_type(nSybType) && readed > 0)
+ 				--readed;
+ 			if (readed > *pcbValue)
+ 				readed = *pcbValue;
+diff --git b/src/odbc/unittests/.cvsignore a/src/odbc/unittests/.cvsignore
+index d7c663e..1316adb 100644
+--- b/src/odbc/unittests/.cvsignore
++++ a/src/odbc/unittests/.cvsignore
+@@ -63,4 +63,3 @@ cursor4
+ cursor5
+ attributes
+ hidden
+-blob1
+diff --git b/src/odbc/unittests/blob1.c a/src/odbc/unittests/blob1.c
+deleted file mode 100755
+index b8c45b0..0000000
+--- b/src/odbc/unittests/blob1.c
++++ /dev/null
+@@ -1,224 +0,0 @@
+-/* Testing large objects */
+-/* Test from Sebastien Flaesch */
+-
+-#include "common.h"
+-
+-static char software_version[] = "$Id: blob1.c,v 1.1.2.2 2008/01/10 13:13:46 freddy77 Exp $";
+-static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+-
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO && rcode != SQL_NO_DATA && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+-#define NBYTES 10000
+-
+-static int failed = 0;
+-
+-static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+-{
+-	SQLRETURN rcode = 0;
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
+-
+-static void
+-fill_chars(char *buf, size_t len, unsigned int start, unsigned int step)
+-{
+-	size_t n;
+-
+-	for (n = 0; n < len; ++n)
+-		buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1));
+-}
+-
+-static int
+-check_chars(const char *buf, size_t len, unsigned int start, unsigned int step)
+-{
+-	size_t n;
+-
+-	for (n = 0; n < len; ++n)
+-		if (buf[n] != 'a' + ((start+n) * step % ('z' - 'a' + 1)))
+-			return 0;
+-
+-	return 1;
+-}
+-
+-static int
+-readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+-{
+-	SQLRETURN rcode;
+-	char buf[4096];
+-	SQLLEN len, total = 0;
+-	int i = 0;
+-	int check;
+-
+-	printf(">> readBlob field %d\n", pos);
+-	while (1) {
+-		i++;
+-		rcode = SQLGetData(stmth, pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len);
+-		if (!SQL_SUCCEEDED(rcode) || len <= 0)
+-			break;
+-		if (len > (SQLLEN) sizeof(buf))
+-			len = (SQLLEN) sizeof(buf);
+-		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+-		if (pos == 1)
+-			check = check_chars(buf, len, 123 + total, 1);
+-		else
+-			check =	check_chars(buf, len, 987 + total, 25);
+-		if (!check) {
+-			fprintf(stderr, "Wrong buffer content\n");
+-			failed = 1;
+-		}
+-		total += len;
+-	}
+-	printf(">>   total bytes read = %d \n", (int) total);
+-	if (total != 10000)
+-		failed = 1;
+-	return rcode;
+-}
+-
+-int
+-main(int argc, char **argv)
+-{
+-	SQLRETURN rcode;
+-	SQLHSTMT m_hstmt = NULL;
+-	int i;
+-
+-	int key;
+-	SQLINTEGER vind0;
+-	char buf1[NBYTES];
+-	SQLINTEGER vind1;
+-	char buf2[NBYTES];
+-	SQLINTEGER vind2;
+-	int cnt = 2;
+-
+-	use_odbc_version3 = 1;
+-	Connect();
+-
+-	Command(Statement, "IF OBJECT_ID('tt') IS NOT NULL DROP TABLE tt");
+-	Command(Statement, "CREATE TABLE tt ( k INT, t TEXT, b IMAGE, v INT )");
+-
+-	/* Insert rows ... */
+-
+-	for (i = 0; i < cnt; i++) {
+-
+-		m_hstmt = NULL;
+-		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+-
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "insert into tt values ( ?, ?, ?, ? )", SQL_NTS);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+-
+-		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 1");
+-
+-		SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 2");
+-
+-		SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3");
+-
+-		SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4");
+-
+-		key = i;
+-		vind0 = 0;
+-
+-		fill_chars(buf1, NBYTES, 123, 1);
+-		vind1 = SQL_LEN_DATA_AT_EXEC(NBYTES);
+-
+-		fill_chars(buf2, NBYTES, 987, 25);
+-		vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES);
+-
+-		printf(">> insert... %d\n", i);
+-		rcode = SQLExecute(m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLExecute StmtH");
+-		while (rcode == SQL_NEED_DATA) {
+-			char *p;
+-
+-			rcode = SQLParamData(m_hstmt, (SQLPOINTER) & p);
+-			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
+-			printf(">> SQLParamData: ptr = %p  rcode = %d\n", (void *) p, rcode);
+-			if (rcode == SQL_NEED_DATA) {
+-				SQLRETURN rcode = SQLPutData(m_hstmt, p, NBYTES);
+-
+-				CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+-				printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
+-			}
+-		}
+-
+-		rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFreeHandle StmtH");
+-
+-	}
+-
+-	/* No fetch rows ... */
+-
+-	for (i = 0; i < cnt; i++) {
+-
+-		m_hstmt = NULL;
+-		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+-
+-		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+-
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM tt WHERE k = ?", SQL_NTS);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+-
+-		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 1");
+-
+-		SQLBindCol(m_hstmt, 1, SQL_C_BINARY, NULL, 0, &vind1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2");
+-		SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3");
+-		SQLBindCol(m_hstmt, 3, SQL_C_LONG, &key, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1");
+-
+-		vind0 = 0;
+-		vind1 = SQL_DATA_AT_EXEC;
+-		vind2 = SQL_DATA_AT_EXEC;
+-
+-		rcode = SQLExecute(m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLExecute StmtH");
+-
+-		rcode = SQLFetchScroll(m_hstmt, SQL_FETCH_NEXT, 0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFetchScroll StmtH");
+-		printf(">> fetch... %d  rcode = %d\n", i, rcode);
+-
+-		rcode = readBlob(m_hstmt, 1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
+-		rcode = readBlob(m_hstmt, 2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
+-
+-		rcode = SQLCloseCursor(m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH");
+-
+-		rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFreeHandle StmtH");
+-	}
+-
+-	Disconnect();
+-
+-	return failed ? 1 : 0;
+-}
+-
+
+commit d3d27cd44a61133054de7ee4fa93690d4245c6a1
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 13:11:08 2008 +0000
+
+    file blob1.c was added on branch BRANCH0_82 on 2008-01-10 13:13:46 +0000
+
+commit 0b60151b80495fbe39b6b027189a871f889ea980
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 08:52:45 2008 +0000
+
+    fix SQLNumResultCols() is wrong (+1) problem
+
+diff --git b/ChangeLog a/ChangeLog
+index ecb6523..edcfcba 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,8 +1,3 @@
+-Thu Jan 10 09:51:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* TODO src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+-	* src/odbc/unittests/Makefile.am:
+-	- small fix for hidden fields (ignore them entirely)
+-
+ Wed Jan  9  7:50:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac: preparing 0.82
+ 
+diff --git b/src/odbc/odbc.c a/src/odbc/odbc.c
+index 7d33b27..7180d23 100644
+--- b/src/odbc/odbc.c
++++ a/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464.2.1 2008/01/10 08:52:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.464 2008/01/06 10:48:43 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -2652,7 +2652,7 @@ odbc_ird_check(TDS_STMT * stmt)
+ 		return;
+ 
+ 	/* check columns number */
+-	assert(ird->header.sql_desc_count <= cols || ird->header.sql_desc_count == 0);
++	assert(ird->header.sql_desc_count == cols || ird->header.sql_desc_count == 0);
+ 
+ 
+ 	/* check all columns */
+@@ -2717,10 +2717,6 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		return SQL_SUCCESS;
+ 	num_cols = res_info->num_cols;
+ 
+-	/* ignore hidden columns... TODO correct? */
+-	while (num_cols > 0 && res_info->columns[num_cols - 1]->column_hidden == 1)
+-		--num_cols;
+-
+ 	if (desc_alloc_records(ird, num_cols) != SQL_SUCCESS) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		return SQL_ERROR;
+diff --git b/src/odbc/unittests/.cvsignore a/src/odbc/unittests/.cvsignore
+index 1316adb..d6eea5a 100644
+--- b/src/odbc/unittests/.cvsignore
++++ a/src/odbc/unittests/.cvsignore
+@@ -62,4 +62,3 @@ cursor3
+ cursor4
+ cursor5
+ attributes
+-hidden
+diff --git b/src/odbc/unittests/Makefile.am a/src/odbc/unittests/Makefile.am
+index 8f38676..e68b0a4 100644
+--- b/src/odbc/unittests/Makefile.am
++++ a/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.68.2.1 2008/01/10 08:52:46 freddy77 Exp $
++# $Id: Makefile.am,v 1.68 2007/12/19 14:36:05 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -20,7 +20,7 @@ TESTS		=	\
+ 			paramcore$(EXEEXT) timeout2$(EXEEXT) timeout3$(EXEEXT) \
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+-			attributes$(EXEEXT) hidden$(EXEEXT)
++			attributes$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -77,7 +77,6 @@ cursor3_SOURCES	= cursor3.c common.c common.h
+ cursor4_SOURCES	= cursor4.c common.c common.h
+ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
+-hidden_SOURCES	= hidden.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git b/src/odbc/unittests/hidden.c a/src/odbc/unittests/hidden.c
+deleted file mode 100755
+index 66be442..0000000
+--- b/src/odbc/unittests/hidden.c
++++ /dev/null
+@@ -1,96 +0,0 @@
+-/* Testing result column numbers having hidden columns */
+-/* Test from Sebastien Flaesch */
+-
+-#include "common.h"
+-
+-static char software_version[] = "$Id: hidden.c,v 1.1.2.1 2008/01/10 08:52:46 freddy77 Exp $";
+-static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+-
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_NO_DATA \
+-     && rcode != SQL_SUCCESS \
+-     && rcode != SQL_SUCCESS_WITH_INFO  \
+-     && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+-static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+-{
+-	SQLRETURN rcode = 0;
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
+-
+-int
+-main(int argc, char **argv)
+-{
+-	SQLRETURN rcode;
+-	SQLHSTMT m_hstmt1;
+-	SQLSMALLINT cnt = 0;
+-	int failed = 0;
+-
+-	use_odbc_version3 = 1;
+-	Connect();
+-
+-	Command(Statement, "CREATE TABLE #t1 ( k INT, c CHAR(10), vc VARCHAR(10) )");
+-	Command(Statement, "CREATE TABLE #tmp1 (i NUMERIC(10,0) IDENTITY PRIMARY KEY, b VARCHAR(20) NULL, c INT NOT NULL)");
+-
+-	/* test hidden column with FOR BROWSE */
+-	ResetStatement();
+-
+-	m_hstmt1 = Statement;
+-
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c, b FROM #tmp1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect");
+-
+-	rcode = SQLNumResultCols(m_hstmt1, &cnt);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLNumResultCols 1");
+-
+-	if (cnt != 2) {
+-		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+-		failed = 1;
+-	}
+-	ResetStatement();
+-
+-	/* test hidden column with cursors*/
+-	CheckCursor();
+-
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+-
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLPrepare 1");
+-
+-	rcode = SQLExecute(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecute 1");
+-
+-	rcode = SQLNumResultCols(m_hstmt1, &cnt);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLNumResultCols 1");
+-
+-	if (cnt != 3) {
+-		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+-		failed = 1;
+-	}
+-
+-	Disconnect();
+-
+-	return failed ? 1: 0;
+-}
+
+commit bf3e39dbca6bef460127ccd1e1d8995e4594dfe9
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 01:01:38 2008 +0000
+
+    file ChangeLog-0.82 was added on branch BRANCH0_82 on 2008-01-10 20:58:43 +0000
+
+commit 298297ad5f7523d814293426ece4eb93b68e2304
+Author: freddy77 <freddy77>
+Date:   Wed Jan 9 06:50:55 2008 +0000
+
+    start preparing release
+
+diff --git b/ChangeLog a/ChangeLog
+index edcfcba..69bc581 100644
+--- b/ChangeLog
++++ a/ChangeLog
+@@ -1,6 +1,3 @@
+-Wed Jan  9  7:50:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac: preparing 0.82
+-
+ Tue Jan  8 10:31:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/Makefile.am added freetds.conf.5
+ 	* src/dblib/bcp.c applied BCPKEEPIDENTIY patch from [email]
+diff --git b/configure.ac a/configure.ac
+index d2d0fed..2ba93f3 100644
+--- b/configure.ac
++++ a/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29.2.1 2008/01/09 06:50:55 freddy77 Exp $
++dnl $Id: configure.ac,v 1.29 2008/01/01 23:09:46 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.82RC1)
++AC_INIT(FreeTDS, 0.65.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29.2.1 $)
++AC_REVISION($Revision: 1.29 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+
+======== fast forward to latest
+commit a6da12218e249babe568d2879324e4ac80b5f8db
+Author: freddy77 <freddy77>
+Date:   Wed Jan 9 06:51:45 2008 +0000
+
+    avoid clash
+
+diff --git a/configure.ac b/configure.ac
+index 2ba93f3..96ec6c5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.29 2008/01/01 23:09:46 freddy77 Exp $
++dnl $Id: configure.ac,v 1.30 2008/01/09 06:51:45 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -12,10 +12,10 @@ dnl ------------------------------------------------------------
+ # ------------------------------------------------------------
+ # Initialization
+ # ------------------------------------------------------------
+-AC_INIT(FreeTDS, 0.65.dev.esyscmd(echo -n $(date +"%Y%m%d")))
++AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.29 $)
++AC_REVISION($Revision: 1.30 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+
+commit 1d1d90ef07268fa4a231f07390ae1677a83e0a33
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 01:01:31 2008 +0000
+
+    truncated because of release
+
+diff --git a/ChangeLog b/ChangeLog
+index 69bc581..ad8d878 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,36 +1,5 @@
+-Tue Jan  8 10:31:43 EST 2008	JK Lowden <jklowden@freetds.org>
+-	* doc/Makefile.am added freetds.conf.5
+-	* src/dblib/bcp.c applied BCPKEEPIDENTIY patch from [email]
+-
+-Tue Jan  8 14:28:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* NEWS doc/README.releasing doc/userguide.sgml:
+-	- updates for new release
+-
+-Tue Jan  8 10:33:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/unittests/genparams.c: relax for no-dm
+-
+-Mon Jan  7 19:32:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
+-	- fix millisecond round off for TIMESTAMP
+-	- improve genparams test to catch this problem
+-	- make genparams works with MS ODBC
+-
+-Mon Jan  7 15:04:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* include/tdssrv.h src/server/login.c src/server/server.c:
+-	* src/server/unittest.c:
+-	- small improves
+-	* src/pool/user.c: style update
+-
+-Sun Jan  6 11:48:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/odbc/odbc.c: even SQLExecDirect support parameters!
+-	* src/odbc/unittests/genparams.c: improve
+-
+-Sat Jan  5 12:23:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* src/tds/query.c:
+-	- add parameterized flag calling sp_cursoropen if needed
+-
+-Wed Jan  2 00:08:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	* configure.ac src/apps/Makefile.am:
+-	- remove GNU style
+-	* src/dblib/dblib.c: make it compile
+-
++Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
++	* ChangeLog  truncated because of release
++	- ChangeLog-0.82 added because of release
++	
++$Id: ChangeLog,v 1.2455 2008/01/10 01:01:31 jklowden Exp $
+
+commit 2b04c9b9720eec10e4822ebfb479bec00de49492
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 01:01:38 2008 +0000
+
+    ChangeLog-0.82 added because of release
+
+diff --git a/ChangeLog-0.82 b/ChangeLog-0.82
+new file mode 100644
+index 0000000..c17b0cf
+--- /dev/null
++++ b/ChangeLog-0.82
+@@ -0,0 +1,2289 @@
++Tue Jan  8 10:31:43 EST 2008	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am added freetds.conf.5
++	* src/dblib/bcp.c applied BCPKEEPIDENTIY patch 
++	- from Jonathan Olson <jpolsonaz@mac.com>
++
++Tue Jan  8 14:28:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS doc/README.releasing doc/userguide.sgml:
++	- updates for new release
++
++Tue Jan  8 10:33:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: relax for no-dm
++
++Mon Jan  7 19:32:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
++	- fix millisecond round off for TIMESTAMP
++	- improve genparams test to catch this problem
++	- make genparams works with MS ODBC
++
++Mon Jan  7 15:04:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdssrv.h src/server/login.c src/server/server.c:
++	* src/server/unittest.c:
++	- small improves
++	* src/pool/user.c: style update
++
++Sun Jan  6 11:48:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: even SQLExecDirect support parameters!
++	* src/odbc/unittests/genparams.c: improve
++
++Sat Jan  5 12:23:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c:
++	- add parameterized flag calling sp_cursoropen if needed
++
++Wed Jan  2 00:08:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/apps/Makefile.am:
++	- remove GNU style
++	* src/dblib/dblib.c: make it compile
++
++
++Mon Dec 31 15:05:16 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c fixed DBPRPAD, maybe
++
++Mon Dec 31 11:29:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh src/odbc/odbc.c:
++	- relax test for cursor
++
++Mon Dec 31 11:06:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c src/odbc/unittests/attributes.c:
++	* src/odbc/unittests/describecol.c src/tds/convert.c:
++	* src/tds/login.c src/tds/mem.c:
++	- minor signed/unsigned fixes
++	* src/dblib/bcp.c: minor performance improve
++	* src/dblib/dblib.c: fix date portability
++
++Fri Dec 28 17:57:08 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/token.c minor change
++	* src/tds/convert.c simpler tds_strftime
++	* src/dblib/unittests/done_handling.c no spurious messages
++
++Wed Dec 28 15:11:48 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: accepted patch #1854381
++
++Wed Dec 28 14:44:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild misc/test-other.sh:
++	- make amd64 works
++	* misc/test-auto.sh: add --help option
++	* src/tds/convert.c:
++	- fix overflow in tds_convert_char
++	- minor fixes for tds_strftime
++
++Thu Dec 27 14:43:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/.cvsignore: ignore autogenerated
++	* include/tds.h src/replacements/vasprintf.c src/tds/convert.c:
++	* src/tds/login.c src/tds/query.c src/tds/read.c:
++	- remove some warnings
++
++Thu Dec 27 11:20:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c: make unixODBC happy
++	* win32/config.h: define TDS_I64_FORMAT
++
++Thu Dec 27 10:19:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/buffering.h:
++	- remove warning if compiled with NDEBUG defined
++
++Wed Dec 26 21:57:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/attributes.c: make it works
++
++Wed Dec 26 19:44:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/freetds.conf.5: typo fix
++	* src/ctlib/unittests/common.c: make tests compile
++	* src/odbc/odbc.c: add diagnostic for truncate
++
++Tue Dec 25 00:55:02 EST 2007	JK Lowden <jklowden@freetds.org>
++	* freetds.conf doc/Makefile.am doc/freetds.conf.5 (added)
++	- shortened default freetds.conf and moved documentation
++	- to a proper man page.  Merry Christmas! 
++
++Mon Dec 24 11:34:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: removed unused fields
++
++Sun Dec 23 16:08:29 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c 
++	* src/ctlib/cs.c src/ctlib/unittests/common.c
++	* src/dblib/dblib.c
++	* src/tds/config.c src/tds/unittests/convert.c
++	- added STD_DATETIME_FMT to allow for WIN32 shortcomings
++
++Fri Dec 21 16:20:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/ct.c src/odbc/odbc.c src/tds/query.c:
++	- make odbc cursor test work using sp_cursoropen with parameters
++
++Fri Dec 21 11:38:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
++	* src/odbc/unittests/cursor5.c:
++	- cursor tests should work
++
++Fri Dec 21 10:05:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/replacements.h src/replacements/vasprintf.c:
++	* win32/config.h:
++	- applied modified patch #1848920
++
++Thu Dec 20 22:56:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/setnull.c src/dblib/unittests/thread.c:
++	- remove warnings
++
++Thu Dec 20 17:46:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- improve cursor attribute setting
++	- fix a small issue with unixODBC and 64 bit
++
++Wed Dec 19 16:08:17 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
++	- remove warnings
++
++Wed Dec 19 15:35:22 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/attributes.c(added) src/odbc/unittests/attributes.in(added):
++	* src/odbc/unittests/Makefile.am: add a test for statement attributes
++	* src/odbc/unittests/describecol.c: fix possible core
++
++Tue Dec 18 09:09:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/cursor3.c(added):
++	* src/odbc/unittests/cursor4.c(added) src/odbc/unittests/cursor5.c(added):
++	- merged test from Sebastien FLAESCH
++
++Sun Dec 16 19:08:38 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/api_status.txt 
++	- set useless db-lib functions' status to 'never'
++
++Sun Dec 16 16:58:35 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/bsqlodbc.txt doc/osql.txt
++	* doc/userguide.sgml
++	- updated for next release
++
++Fri Dec 14 11:23:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh: fix some strange echo portability
++	* src/dblib/unittests/null.c src/dblib/unittests/null2.c:
++	- make ignore less verbose
++
++Thu Dec 13 23:45:55 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am build bsqlodbc out-of-tree
++	* src/dblib/unittests/null.c prettier & correct, passes
++
++Thu Dec 13 21:12:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/buffering.h: fix null2
++
++Thu Dec 13 19:04:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/Makefile.am:
++	- fix bsqlodbc compile if not standard sql.h path
++
++Wed Dec 12 07:27:07 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: fix for 64bit
++
++Tue Dec 11 11:09:52 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: remove warning
++	* misc/freetds_autobuild: fix if password empty
++
++Tue Dec 11 00:02:16 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml minor touchups 
++	* src/dblib/dblib.c src/dblib/unittests/setnull.c
++	- unittests/setnull.c passes.
++
++Mon Dec 10 14:05:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: remove warning
++
++Mon Dec 10 00:08:45 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/userguide.sgml some improvements
++	doc/grep_sample_code doc/images/caution.gif 
++	doc/images/warning.gif
++	doc/images/callouts/1.gif doc/images/callouts/2.gif
++	doc/images/callouts/3.gif doc/images/callouts/4.gif
++	doc/images/callouts/5.gif doc/images/callouts/6.gif
++	doc/images/callouts/7.gif doc/images/callouts/8.gif
++	doc/images/callouts/9.gif doc/images/callouts/10.gif
++	- added from http://tldp.org/LDP/abs/images/
++
++Sun Dec  9 19:51:11 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml added tenderfoot tutorial
++
++Fri Dec  7 00:26:01 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/dblib/dblib.c
++	* src/dblib/dbutil.c src/tds/util.c
++	- pass errno via tdserror.  
++
++Thu Dec  6 21:41:23 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/convert.c tds_willconvert returns size
++
++Thu Dec  6 21:32:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix for 64bit machines
++	* src/dblib/unittests/setnull.c: improve
++
++Thu Dec  6 19:59:59 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/replacements.h src/apps/bsqldb.c:
++	* src/dblib/unittests/setnull.c:
++	- use basename from MingW if available
++	* src/dblib/dblib.c: fix malloc portability problem
++
++Thu Dec  6 10:18:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/rpc.c src/dblib/unittests/setnull.c:
++	- fix compile problems
++
++Thu Dec  6 01:00:42 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/buffering.h src/dblib/dblib.c:
++	- dbgetnull tolerates negative varlen, looks pretty good
++
++Wed Dec  5 10:38:55 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c:
++	- t0011 passes but copy_data_to_host_var likely wrong
++
++Tue Dec  4 20:19:38 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/buffering.h src/dblib/dblib.c:
++	- removed _db_set_null and associated mallocs
++	- dblib/unittest/t0011.c failing mysteriously
++
++Mon Dec  3 23:18:55 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c src/dblib/unittests/setnull.c:
++	- corrected dbsetnull()
++
++Mon Dec  3 18:45:22 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/unittests/rpc.c
++	* src/dblib/unittests/setnull.c src/dblib/unittests/t0001.c
++	* src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c
++	* src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c
++	* src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c
++	* src/dblib/unittests/t0008.c src/dblib/unittests/t0011.c
++	* src/dblib/unittests/t0015.c src/dblib/unittests/t0018.c
++	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c
++	* src/dblib/unittests/thread.c src/dblib/unittests/timeout.c:
++	- dbbind uses zero, not -1 to indicate sufficient space.  
++
++Mon Dec  3 17:57:54 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c: don't cast malloc and don't assume it worked. 
++
++Mon Dec  3 19:54:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/Makefile.am: remove GNU make pattern
++
++Mon Dec  3 15:35:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c:
++	- do not call dbcolptr for compute result but call new dbacolptr
++	- dbcolptr return TDSCOLUMN* to optimize it
++
++Mon Dec  3 11:53:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: remove a warning
++
++Mon Dec  3 10:18:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/dblib/unittests/.cvsignore:
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/setnull.c(added):
++	- add a test for setnull
++
++Sun Dec  2 17:58:40 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/api_status.txt
++	* include/dblib.h include/sybdb.h include/tds.h
++	* src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c
++	- full implementation of dbsetnull().
++	- Replaced _DB_GETCOLINFO macro with dbcolptr(). 
++
++Sat Dec  1 14:05:54 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/unittests/null.c
++	- correct TDS 5.0 bcp offset table calcuation in presence of NULLs.
++
++Fri Nov 30 09:54:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: missing new line
++
++Thu Nov 29 09:03:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/null2.c: improve
++
++Wed Nov 28 15:15:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac:
++	- include windows.h under windows
++	- include sql.h directly to avoid MingW problems
++	* include/dblib.h src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
++	- avoid core checking for parameters if argument are expected
++	* src/dblib/unittests/null.c src/dblib/unittests/null2.c:
++	- avoid invalid references to deallocated stack
++
++Wed Nov 28 09:48:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: remove warnings
++
++Wed Nov 28 00:27:36 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c fixed TDS 5.0 null-column bug, cf. ML
++	* doc/tds.html Added BCP, made 4.01 strict, validated. 
++
++Tue Nov 27 16:12:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/null2.c(added):
++	- test dbbind/dbnullbind with NULLs
++	* src/dblib/unittests/null.c: add note
++
++Tue Nov 27 13:37:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0022.c:
++	- compile with Sybase libraries
++	* src/dblib/unittests/t0008.c: more verbose
++
++Mon Nov 26 21:02:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array_out.c: fix silly core
++
++Mon Nov 26 19:11:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tdsodbc.h src/odbc/odbc.c:
++	* src/odbc/unittests/array_out.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/describecol.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/insert_speed.c src/odbc/unittests/timeout.c:
++	* src/odbc/unittests/timeout3.c src/odbc/unittests/type.c:
++	- minor fixes for 64bit
++
++Mon Nov 26 16:47:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/apps/fisql/fisql.c:
++	- do not use functions not availables
++
++Mon Nov 26 09:43:03 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/tds/unittests/iconv_fread.c
++	- small changes
++
++Mon Nov 26 09:51:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/bcp.c: fix printf
++
++Mon Nov 26 07:24:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
++	* src/odbc/unittests/const_params.c src/odbc/unittests/cursor1.c:
++	* src/odbc/unittests/describecol.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/insert_speed.c src/odbc/unittests/raiserror.c:
++	* src/odbc/unittests/rpc.c src/odbc/unittests/scroll.c:
++	* src/tds/challenge.c:
++	- fix minor issues with 64bit
++
++Thu Nov 22 09:43:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/ctlib/Makefile.am src/dblib/Makefile.am:
++	* src/odbc/Makefile.am:
++	- do not filter symbols under MacOsX (avoid libtool problems)
++
++Wed Nov 21 11:31:37 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/blk.c: correctly test result of cs_convert
++	* src/dblib/rpc.c: minor edits
++	* src/dblib/unittests/bcp.c src/dblib/unittests/bcp.h:
++	- test works for TDS 7.0.
++
++Tue Nov 20 23:08:15 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/unittests/bcp.c:
++	* src/dblib/dblib.c src/tds/convert.c src/tds/net.c:
++	- small changes
++
++Thu Nov 15 14:32:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/.cvsignore src/dblib/dblib.c:
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/null.c:
++	- fix problem with empty string and TEXT
++	- add a test to test empty/NULL behavior of dbdatlen/dbdata
++
++Thu Nov 15 10:18:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: return error if no username given and no Kerberos
++
++Tue Nov 13 10:13:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/challenge.c src/tds/gssapi.c:
++	* src/tds/login.c src/tds/token.c:
++	- port ntlm to new authentication code
++	- move all ntlm stuff to challenge.c
++
++Mon Nov 12 17:15:03 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h src/dblib/bcp.c
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/dblib/rpc.c
++	* src/tds/log.c src/tds/login.c
++	- trying to convince Doxygen not to ignore functions, 
++	- e.g. dbinit 
++
++Mon Nov 12 13:38:04 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/dbutil.c
++	* src/dblib/dblib.c src/dblib/rpc.c src/dblib/bcp.c
++	- added DBDEAD test to all public functions
++
++Mon Nov 12 14:32:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac: cleanup
++	* src/tds/gssapi.c: compute fqdn name in service name
++
++Mon Nov 12 12:34:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds.h src/tds/gssapi.c:
++	* src/tds/login.c src/tds/mem.c src/tds/token.c:
++	- new TDSAUTHENTICATION structure
++	- new --enable-krb5 to enable Kerberos authentication
++	  (disable by default)
++
++Fri Nov 09 11:29:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: remove some leaks
++
++Mon Nov 05 11:05:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: use pipes to avoid infinite counter
++
++Mon Nov 05 09:29:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: fix log avoidance for long logins
++
++Sun Nov 04 09:16:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/gssapi.c: small cleanup
++
++Sat Nov 03 14:31:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/config.c src/tds/mem.c:
++	- add server_host_name to TDSCONNECTION
++	* src/tds/gssapi.c: some improves
++
++Fri Nov 02 11:33:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/gssapi.c: add small comment
++
++Tue Oct 30 16:45:41 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am src/tds/gssapi.c src/tds/login.c:
++	- include developing code for GSSAPI
++
++Tue Oct 30 16:36:29 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/login.c src/ctlib/ct.c src/tds/read.c:
++	* src/tds/token.c:
++	- finish merging tds9 code as developing
++
++Tue Oct 30 16:02:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- make odbc row_count 64bit
++
++Tue Oct 30 13:14:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c src/tds/query.c:
++	- more merge for tds9
++
++Tue Oct 30 11:31:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c:
++	* src/server/server.c src/tds/token.c:
++	- merge partially tds9 patch
++
++Tue Oct 30 11:15:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- avoid wrong assert if error and tdserror called
++	* src/tds/query.c: limit data length to maximun allowed
++
++Wed Oct 24 17:55:56 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* include/sqldb.h define dbfreelogin
++	* src/dblib/unittests/common.h add commentary
++
++Tue Oct 23 19:41:03 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/net.c src/tds/util.c
++	- ct-lib seems OK with EINTR (sqsh works) but db-lib
++	- applications get a weird message. 
++
++Tue Oct 23 18:08:00 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/net.c 
++	- return from tds_select as if timed out on EINTR. 
++	- sqsh still unhappy when ^C pressed on long-running query. 
++
++Thu Oct 18 16:48:23 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix core
++
++Thu Oct 18 13:49:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c src/tds/token.c:
++	- more free(NULL)
++
++Tue Oct 16 16:59:06 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c src/ctlib/blk.c src/ctlib/cs.c src/ctlib/ct.c:
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
++	* src/dblib/unittests/rpc.c src/odbc/error.c src/odbc/odbc.c:
++	* src/odbc/sql2tds.c src/odbc/unittests/binary_test.c:
++	* src/pool/config.c src/tds/locale.c src/tds/login.c:
++	* src/tds/mem.c src/tds/query.c src/tds/token.c:
++	* src/tds/vstrbuild.c src/tds/unittests/dataread.c:
++	- do not check for free(NULL)
++
++Wed Oct 10 13:59:37 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c 
++	- added some error checking for malloc/realloc, more needed
++
++Tue Oct 09 13:40:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: fix small memory leak
++
++Mon Sep 24 13:12:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: limit size preparing queries
++
++Mon Sep 24 12:01:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/server/query.c src/server/server.c:
++	- small server improve
++
++Thu Sep 20 17:32:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/sybdb.h src/dblib/dblib.c src/dblib/dbopen.c:
++	- apply constify patch #1786200
++
++Thu Sep 20 17:02:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: do not strip empty lines
++
++Mon Sep 17 17:22:32 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c correct freebcp -L behavior 
++	* src/tds/net.c TDSECONN on no socket failure 
++	* src/tds/util.c change iconv messages
++
++Mon Sep 17 17:52:09 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update for tds9
++	* src/server/login.c: remove warning
++
++Mon Sep 17 12:13:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c:
++	- improve for very large query (from 9.2 to 0.3 seconds on my 
++	  test machine)
++
++Mon Sep 17 10:42:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update
++	* src/ctlib/unittests/get_send_data.c: small fix
++	* include/sybdb.h src/dblib/dblib.c src/dblib/unittests/t0022.c:
++	- small update for future tds9
++	* src/pool/main.c src/pool/user.c src/server/login.c:
++	- improve portability and possible remote leakage
++
++Thu Sep 13 12:42:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c:
++	- make it works even if login is quite long
++
++Thu Sep 13 08:57:26 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/dynamic1.c: use tds_set_param_type
++
++Thu Sep 06 13:15:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update for tds9
++	* src/tds/read.c: work if initial in_pos is != 0
++
++Sat Aug 25 12:32:01 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
++	- use ODBC_API instead of SQL_API to allow combined compile
++
++Fri Aug 24 11:50:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/login.c:
++	* src/tds/query.c src/tds/token.c:
++	- small changes for TDS 9.0
++
++Mon Aug 16 10:09:42 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/Makefile.am src/tds/net.c:
++	* src/tds/unittests/Makefile.am:
++	- remove other warnings
++
++Mon Aug 16 08:29:38 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/convert.c win32/initnet.c:	
++	- remove some warnings compiling with MingW
++
++Sat Aug 11 08:51:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c vms/config_h.vms vms/descrip_mms.template:
++	- applied Craig A. Berry patch #1772080 for VMS systems
++
++Fri Aug 10 11:17:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS: updated
++
++Fri Aug 10 11:14:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/dev-cpp/Makefile.win: add missing file
++
++Thu Aug 09 14:52:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: small fixes
++
++Thu Aug 09 10:26:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: document port override syntax
++
++Thu Aug 09 09:49:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/htdoc/basic_jdbc_question.html doc/htdoc/contrib.html:
++	* doc/htdoc/docs.html doc/htdoc/index.html doc/htdoc/news.html:
++	* doc/htdoc/software.html doc/htdoc/support.html:
++	* doc/htdoc/vague_jdbc_question.html doc/htdoc/which_api.html:
++	- make xhtml compatible
++
++Wed Aug 08 15:24:16 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/Makefile.am win32/version.rc.in:
++	- fix odbc cross compile using MingW
++
++Wed Aug 08 11:34:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild:
++	- improved adding test for server:port and server\instance case
++
++Wed Aug 08 11:10:36 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: fix bug #1759652 (cannot use server\INSTANCE)
++
++Tue Aug 07 15:34:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: improve cursor updates
++	* src/odbc/unittests/cursor1.c: improved and fixed
++
++Tue Aug 07 11:55:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: use table name for update
++
++Tue Aug 07 11:19:33 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/odbc.c src/odbc/unittests/getdata.c:
++	- fix bug #1758831
++	- additional fixes and checks for SQLGetData
++
++Tue Aug 07 10:29:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: update links
++
++Fri Aug 03 13:15:42 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: lookup server name correctly for instances
++
++Thu Aug 02 13:31:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/sqlfront.h: small compatiblity improve with ms
++
++Fri Jul 13 18:56:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/getdata.c: portability fix
++
++Thu Jul 12 16:31:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix for SQLGetData using empty fields
++	* src/odbc/unittests/getdata.c:
++	- improve test to catch previous problem
++
++Sat Jul 07 19:55:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/sprintf_i64_format.m4: improve portability
++
++Sat Jul 07 19:09:59 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- check cbValueMax in SQLGetData even if DM present
++
++Tue Jul 03 17:12:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/compute.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/typeinfo.c:
++	- relax test for Sybase
++	* src/tds/token.c: fix length computation
++
++Tue Jul 03 15:37:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c:
++	* src/odbc/odbc.c src/tds/mem.c src/tds/token.c:
++	- add table_column_name to read real column name (if available),
++	  read from wire and use when needed
++
++Sun Jul 01 12:10:31 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsstring.h src/odbc/connectparams.c:
++	* src/odbc/descriptor.c src/odbc/odbc.c src/tds/config.c:
++	* src/tds/tdsstring.c:
++	- added tds_dstr_dup to duplicate DSTR
++	- use tds_dstr_dup
++	- improve tds_dstr_set
++
++Wed Jun 27 16:51:30 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: add Column Info token
++	* src/odbc/unittests/timeout2.c: portability fix
++
++Mon Jun 25 11:47:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/api_status.txt include/cspublic.h include/ctlib.h:
++	* src/ctlib/cs.c src/ctlib/ct.c:
++	- applied patch #1729392, it adds support for ctlib locale
++
++Mon Jun 25 10:20:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: review cursors
++
++Thu Jun 21 09:19:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: test for Sybase 15
++	* src/odbc/unittests/data.c: bigint for Sybase
++	* src/tds/data.c src/tds/mem.c src/tds/read.c src/tds/tds_checks.c:
++	- add support for Sybase bigint
++	- do not check decault capabilities if not necessary
++
++Tue Jun 19 15:30:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/ct.c src/odbc/odbc_util.c:
++	* src/pool/stream.c src/tds/data.c src/tds/net.c:
++	* src/tds/tds_checks.c src/tds/tds_checks.h src/tds/token.c:
++	- fix problem with Sybase LONGCHAR
++
++Tue Jun 19 14:06:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/t0007.c src/odbc/unittests/prepare_results.c:
++	- more verbose
++	- fix for possible Sybase conversion
++	* src/odbc/odbc.c: additional check if no dm
++
++Mon Jun 18 15:20:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c:
++	- patch #1736289 for bcp/bulk insert problem
++
++Mon Jun 18 14:02:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c src/tds/locale.c:
++	- use correct charset based on locale
++
++Mon Jun 18 13:58:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: remove warning
++
++Sun Jun 17 19:38:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c src/odbc/unittests/timeout3.c:
++	- fix small thread problem
++	- fix possible deadlock
++
++Sun Jun 17 09:45:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c src/odbc/unittests/genparams.c:
++	- fix thread and small portability
++
++Sun Jun 17 09:08:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/dblib.h src/dblib/buffering.h src/dblib/dblib.c:
++	- patch #1717123 for dbsetnull implementation (removed warnings)
++
++Sun Jun 17 08:16:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c:
++	- patch #1703363 for delimiters (modified)
++
++Wed Jun 13 09:26:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/fisql/fisql.c: compile even if readline is not available
++
++Mon Jun  4 17:09:03 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am skip bsqlodb if ODBC disabled
++
++Mon Jun 04 10:03:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/.cvsignore src/dblib/unittests/Makefile.am:
++	* src/dblib/unittests/hang.c(added) src/tds/net.c:
++	- fix problem with tds_select (detected by Perception Technologies)
++
++Fri Jun 01 10:52:46 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: avoid overflow leading to memory errors
++
++Thu May 31 17:02:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- fixes, partially from Brent of Perception Technologies Ltd
++
++Thu May 31 10:54:14 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* TODO add recent potential bug reports
++
++Thu May 31 14:21:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/ac_nullzero.m4: fix cross compile test
++
++Wed May 30 09:55:52 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/threadsafe.c:
++	- implement gethostbyname_r with getaddrinfo (for UnixWare 7 and others)
++
++Tue May 29 10:48:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac win32/config.h: cleanup
++
++Fri May 25 11:07:04 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c:
++	- remove a FIXME
++	* src/odbc/odbc.c:
++	- fix bug #1716594 ("SQLFreeStmt with SQL_CLOSE shouldn't 
++	  unprepare statement")
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/freeclose.c(added)
++	* src/odbc/unittests/.cvsignore:
++	- add a test for bug #1716594
++
++Mon May 21 14:01:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- fix cursor updates, this undo part of change of src/odbc/odbc.c
++	  from 1.331 to 1.332, log:
++	  Wed Jul 21 16:50:11 CET 2004
++	   : some fix for SQLFetch and multiple rows
++	  but tests works
++	* src/odbc/unittests/cursor1.c: improve
++
++Mon May 21 10:40:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c: improve test
++
++Thu May 17 12:32:33 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_checks.c:
++	* src/odbc/odbc_util.c:
++	- avoid core
++	- fix and check invalid values of num_param_rows and curr_param_row
++
++Thu May 17 09:18:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/warning.c: improve and comments
++
++Wed May 16 14:23:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	* src/odbc/sql2tds.c:
++	- support row binding in RPC
++	- reuse new odbc_get_octet_len
++
++Wed May 16 14:23:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: minor updates
++
++Mon May 14 16:04:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: remove copy error
++
++Mon May 14 10:16:37 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c src/tds/mem.c src/tds/token.c src/tds/util.c:
++	- give proper errors on protocol autodiscovery
++
++Wed May 09 10:31:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: finish ODBC timeout
++
++Fri May 03 14:54:58 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/const_params.c:
++	- reset statement to be sure to cleanup
++
++Wed May 02 16:54:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- use query timeout from freetds.conf
++
++Mon Apr 30 15:14:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: use default linkage for static functions
++
++Mon Apr 30 15:02:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c: fix strange link error using gcc 4.1
++
++Mon Apr 23 09:56:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: fix portability issue
++
++Fri Apr 20 15:26:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
++	* src/odbc/unittests/scroll.c:
++	- make valgrind more happy if Sybase is used
++
++Fri Apr 20 11:13:40 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/timeout4.c(added):
++	- add a test for timeout
++	- fix timeout on prepare (not detected)
++	- fix timeout if connection broken
++
++Thu Apr 19 11:11:55 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
++	* src/odbc/unittests/scroll.c:
++	- give only warning for Sybase
++
++Thu Apr 19 10:45:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- say we not still support cursors for sybase
++
++Wed Apr 18 16:28:29 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy include/tdsodbc.h src/odbc/odbc.c:
++	* src/odbc/odbc_util.c src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- fix cursor updates
++
++Mon Apr 16 22:08:07 EDT 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqlodbc.c ODBC3 conformant 
++
++Sun Apr 15 10:01:36 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix leak
++
++Fri Apr 13 17:27:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: cursor update
++
++Fri Apr 13 17:22:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/query.c:
++	- add cursor update to libTDS
++
++Fri Apr 13 10:08:07 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c:
++	- catch all error
++	- fix some memory problems
++
++Thu Apr 12 15:33:15 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/funccall.c:
++	- add test from ML
++
++Thu Apr 12 15:07:09 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* freetds.spec.in: fix odbc directory
++	* src/dblib/unittests/Makefile.am: fix for make distcheck
++	* src/odbc/unittests/raiserror.c src/odbc/unittests/warning.c:
++	- relax if dm used
++
++Thu Apr 12 09:47:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/copydesc.c:
++	- test and fix a problem with SQLAllocHandle
++	* src/odbc/unittests/connect2.c: add test for not existing dbs
++
++Thu Apr 12 09:05:56 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/array_bind.c src/ctlib/unittests/ct_diagall.c:
++	* src/ctlib/unittests/ct_diagclient.c:
++	- fix buffer overflow leading in core
++
++Wed Apr 11 14:55:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/odbc/unittests/common.c:
++	- remove warning compiling with MingW
++
++Wed Apr 11 13:52:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c src/odbc/odbc.c:
++	* src/odbc/unittests/connect2.c:
++	- finish and fix test for change_database
++
++Wed Apr 11 11:47:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/connect2.c: fix test
++	* src/odbc/unittests/describecol.in: relax test
++
++Wed Apr 11 09:09:13 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/connect2.c src/odbc/unittests/Makefile.am:
++	- add a test for change_database
++
++Tue Apr 10 16:00:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	- fixes for describecol test
++
++Tue Apr 10 15:16:28 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/coverage.sh: remove system files
++	* src/odbc/unittests/describecol.in: relax test
++
++Fri Apr 06 10:52:25 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdssrv.h src/server/login.c src/server/unittest.c:
++	- remove warning
++
++Fri Apr 06 10:29:31 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS src/odbc/unittests/funccall.c src/tds/mem.c:
++	* src/tds/query.c:
++	- added some notes
++
++Thu Apr 05 16:16:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* INSTALL INSTALL.CVS NEWS README doc/userguide.sgml:
++	- merge from 0.64
++
++Wed Apr 04 13:39:27 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS: updated
++
++Wed Apr 04 11:53:20 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h include/tdsodbc.h src/ctlib/ct.c src/dblib/rpc.c:
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c src/tds/mem.c:
++	* src/tds/token.c src/tds/unittests/dynamic1.c:
++	- removed unused paramter from tds_alloc_param_data
++	- fix possible problem in prepare_rpc
++
++Wed Apr 04 11:39:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* vms/descrip_mms.template: add log.c
++	* src/server/query.c: use constants
++
++Wed Apr 04 09:14:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: improve slow check
++
++Tue Apr 03 16:23:17 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/dev-cpp/FreeTDS.dev win32/dev-cpp/Makefile.win:
++	- updated adding log.c
++
++Mon Apr 02 17:06:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: add encryption parameter
++
++Thu Mar 29 16:32:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c: initial fix for bcp state
++
++Thu Mar 29 16:25:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/server/login.c src/tds/config.c:
++	* src/tds/login.c:
++	- added encryption setting in freetds.conf
++
++Thu Mar 29 12:17:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac: check includes for ODBC
++
++Thu Mar 29 09:44:11 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: add test for money
++
++Wed Mar 28 14:43:34 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* freetds.spec.in src/odbc/unittests/Makefile.am:
++	- fix test-dist test
++
++Mon Mar 26 13:27:51 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/.cvsignore src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	* win32/build_dsw.pl:
++	- distribute projects for vc6 unittests
++
++Mon Mar 26 10:05:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/htdoc/news.html: validate page
++
++Sun Mar 24 09:23:21 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c:
++	- avoid dangerous casts
++
++Tue Mar 20 16:24:26 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/gettimeofday.c src/apps/datacopy.c:
++	- remove warning
++
++Mon Mar 19 11:01:05 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/replacements.h: fix warning for win32
++
++Sun Mar 18 12:37:47 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/odbc/unittests/timeout2.c:
++	* src/odbc/unittests/timeout3.c:
++	- fix cross-compile for win32
++
++Sun Mar 18 12:09:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/Makefile.am 	src/apps/bsqlodbc.c src/apps/tsql.c:
++	* src/apps/fisql/Makefile.am 	win32/winsetup.c:
++	- fix cross-compile for win32
++
++Fri Mar 16 16:32:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/Makefile.am src/tds/Makefile.am:
++	- full libTDS privatization
++	* src/server/unittest.c: use mnemonic
++
++Wed Mar 14 17:18:23 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: update
++	* include/tdssrv.h src/pool/user.c src/server/login.c:
++	* src/server/query.c src/server/server.c src/server/unittest.c:
++	- update server stuff, at least login works
++	* src/tds/tdsstring.c: fix possible mising NUL terminator
++	* src/apps/tsql.c: fix wrong error handler result
++
++Wed Mar 14 09:47:24 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html include/tds.h: update documentation
++
++Tue Mar 13 17:24:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/pool/user.c src/server/login.c:
++	* src/server/unittest.c src/tds/login.c src/tds/query.c:
++	- use mnemonic for packet types
++
++Tue Mar 13 16:45:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: added known tokens
++
++Tue Mar 13 14:18:03 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: updated from code
++
++Mon Mar 12 14:27:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/ctlib.h include/dblib.h include/des.h include/md4.h:
++	* include/md5.h include/replacements.h include/tdsiconv.h:
++	* include/tdsstring.h include/replacements/readpassphrase.h:
++	* src/server/Makefile.am:
++	- privatize functions using gcc visibility if available
++	- privatize server library
++
++Mon Mar 12 13:31:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/blk_in2.c(added) src/ctlib/unittests/Makefile.am:
++	- added test from ML to test cancel and bulk together
++
++Mon Mar 12 10:52:12 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: improved, added types
++
++Fri Feb 16 14:52:10 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: improve documentation
++
++Mon Feb 12 14:29:53 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: Increase size of dbprrow() conversion buffer to 8K.
++
++Mon Feb 12 10:53:54 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/timeout3.c:
++	- use thread instead of fork
++
++Wed Feb  7 01:11:27 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqlodbc.c don't exit on SQL_SUCCESS_WITH_INFO
++
++Wed Feb  7 00:04:15 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c exit noisily on severe errors
++	* src/dblib/dblib.c src/tds/token.c 
++	- fix timeout with buffering problem per yesterday's ML. 
++
++Tue Feb  6 17:14:50 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- Sybase docs for dbsqlok() says: "If the command buffer contains
++	  multiple commands, a run-time error will not cause dbsqlok to
++	  fail.  Instead, failure will occur with the dbresults call that
++	  processes the command causing the run-time error."
++	* src/apps/fisql/fisql.c:
++	- Correct result set processing.
++	
++Tue Feb  6 14:11:02 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: Don't print or store column separator after final result column
++
++Tue Feb 06 10:18:00 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/Makefile.am:
++	- use -module option only for darwin
++
++Tue Feb 06 09:53:14 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c:
++	- make more functions static
++	- remove warning
++	* src/tds/net.c: remove warning
++
++Mon Feb  5 21:48:58 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am src/apps/bsqlodbc.c src/apps/osql
++	- added bsqlodbc as general batch script processor. 
++
++Mon Feb 05 09:41:02 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh phptests/null.php:
++	- fixed PHP check, updated test to PHP 5.2
++
++Fri Feb 02 11:51:19 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/timeout3.c(added):
++	- added a test for connection timeout
++	- fix timeout connection in odbc
++
++Mon Jan 29 12:02:39 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/apps/fisql/fisql.c:
++	* src/tds/net.c:
++	- remove some warnings
++
++Fri Jan 26 18:19:57 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/fisql/fisql.c:
++	- remove warning
++	- reuse malloc
++	- fix compile error including config.h
++	* src/dblib/dblib.c: remove warning
++
++Fri Jan 26 18:06:44 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/error.c src/odbc/odbc.c:
++	- remove warning compiling
++
++Wed Jan 24 14:14:55 EST 2007	Nick Castellano <entropy@freetds.org>
++	* doc/fisql.txt: compute rows in fisql work now, remove BUGS entry
++
++Wed Jan 24 14:11:56 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: indent
++
++Wed Jan 24 14:08:09 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: good enough compute layout
++
++Wed Jan 24 12:24:30 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: almost correct compute layout
++
++Wed Jan 24 11:32:56 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: minor compute layout fixes, still more to do
++
++Tue Jan 23 17:15:33 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: better compute results, layout needs fixing
++
++Tue Jan 23 11:24:40 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: fix off-by-one bug in dbbylist()
++
++Mon Jan 22 15:54:02 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: fix :r with unreadable file
++
++Mon Jan 22 15:50:31 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: print line separator after compute results
++
++Mon Jan 22 00:56:12 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/odbc/connectparams.c src/odbc/error.c
++	* src/odbc/odbc.c
++	- added log entry for API functions
++	* src/odbc/unittests/common.c always use '/' separator
++
++Sat Jan 20 15:24:03 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h include/sybdb.h src/dblib/dblib.c
++	- moved DBOPTION to dblib.h and removed unused members.
++
++Sat Jan 20 01:29:36 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/defncopy.txt doc/fisql.txt cleanup formatting
++	* src/apps/bsqldb.c src/dblib/dblib.c fix compute row headers
++
++Sat Jan 20 01:30:22 EST 2007	Nick Castellano <entropy@freetds.org>
++	* ChangeLog src/apps/fisql/edit.c src/apps/fisql/edit.h
++	* src/apps/fisql/fisql.c src/apps/fisql/handlers.c
++	* src/apps/fisql/handlers.h src/apps/fisql/interrupt.c
++	* src/apps/fisql/interrupt.h src/apps/fisql/terminal.c
++	* src/apps/fisql/terminal.h:
++	- Fix my name and the program name
++
++Sat Jan 20 01:20:39 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: 
++	- Be slightly less stupid about compute rows.
++
++Sat Jan 20 00:54:57 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- do not return bogus nul character in dbgetchar()
++
++Sat Jan 20 00:35:45 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- dbspr*() functions get nul termination not line termination
++	
++Fri Jan 19 22:39:00 EST 2007	Nick Castellano <entropy@freetds.org>
++	* doc/fisql.txt: restore compute rows BUGS entry.
++
++Fri Jan 19 14:05:13 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: 
++	- Provide xmalloc() and xrealloc() instead of relying on
++	  libreadline for these.
++	
++Fri Jan 19 13:47:42 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/Makefile.am
++	* src/apps/fisql/fisql.c
++	* src/apps/fisql/xgetpass.c(removed)
++	* src/apps/fisql/xgetpass.h(removed):
++	- use readpassphrase() in fisql application.
++
++Fri Jan 19 13:31:31 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/edit.c src/apps/fisql/fisql.c
++	* src/apps/fisql/handlers.c src/apps/fisql/handlers.h
++	* src/apps/fisql/interrupt.c src/apps/fisql/interrupt.h
++	* src/apps/fisql/terminal.c src/apps/fisql/terminal.h
++	* src/apps/fisql/xgetpass.c:
++	- Indent fisql to standard FreeTDS coding style
++
++Fri Jan 19 13:19:04 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/apps/fisql/fisql.c: remove obsolete code
++
++Fri Jan 19 13:12:56 EST 2007	Nick Castellano <entropy@freetds.org>
++	* doc/fisql.txt: fisql now works, update doc
++
++Fri Jan 19 13:01:53 EST 2007	Nick Castellano <entropy@freetds.org>
++	* .cvsignore doc/.cvsignore: clean up
++
++Fri Jan 19 12:45:27 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c: fix dbspr1row(), fisql now works
++
++Fri Jan 19 11:17:13 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/fisql.txt
++	* src/apps/fisql/edit.c src/apps/fisql/edit.h
++	* src/apps/fisql/handlers.c src/apps/fisql/handlers.h
++	* src/apps/fisql/interrupt.c src/apps/fisql/interrupt.h
++	* src/apps/fisql/terminal.c src/apps/fisql/terminal.h
++	* src/apps/fisql/xgetpass.c src/apps/fisql/xgetpass.h
++	* src/apps/fisql/fisql.c
++	- Added notice of copyright and GPL license
++
++Thu Jan 18 23:55:17 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/fisql.txt added man page for fisql
++	* src/apps/fisql/fisql.c fixed discarding const warnings
++	* doc/api_status.txt include/sybdb.h src/dblib/dblib.c
++	-  added dbgettime()
++
++Thu Jan 18 17:57:52 EST 2007	Nick Castellano <entropy@freetds.org>
++	* AUTHORS: credit myself as a contributor
++
++Thu Jan 18 17:50:18 EST 2007	Nick Castellano <entropy@freetds.org>
++	* src/dblib/dblib.c:
++	- fix dbprrow() to print character data correctly
++	- fix dbprrow() to not loop endlessly on aggregate rows
++
++Thu Jan 18 08:57:10 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/utf8_2.c: fix error handler
++
++Wed Jan 17 09:48:45 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/fisql/fisql.c: use mkstemp instead of mktemp
++	* src/tds/util.c: cleanup
++
++Tue Jan 16 16:30:42 EDT 2007	Nick Castellano <entropy@freetds.org>
++	* configure.ac
++	* src/apps/Makefile.am
++	* src/apps/fisql: contribute free DB-Libary isql application
++
++Tue Jan 16 09:57:35 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/util.c: fix messages
++
++Tue Jan 16 09:48:43 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh: fix problem with Perl 5.8.8
++	* src/dblib/dblib.c: fix possible thread problem
++
++Tue Jan 16 00:28:28 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/bcp.c
++	* src/dblib/dblib.c src/dblib/unittests/rpc.c
++	- support variadic form of dbperror
++
++Mon Jan 15 14:40:35 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/common.c
++	* src/dblib/unittests/rpc.c
++	* src/dblib/unittests/t0004.c
++	* src/dblib/unittests/t0005.c
++	* src/dblib/unittests/t0007.c
++	* src/dblib/unittests/t0019.c
++	* src/dblib/unittests/t0020.c
++	- fail if an unanticipated message/error is received
++
++Sun Jan 14 23:16:17 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/tds/config.c src/tds/login.c
++	- began work on autodetecting the server's TDSVER
++	- works with libtds, not db-lib
++
++Sun Jan 14 20:38:25 EST 2007	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h include/tds.h
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0012.c
++	* src/dblib/unittests/timeout.c
++	* src/tds/net.c TODO
++	- timeout unit test also works with dbsetinterrupt
++
++Sat Jan 13 17:09:05 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/timeout.c added 
++	* src/dblib/dblib.c 
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/t0001.c
++	* src/tds/login.c src/tds/query.c src/tds/util.c
++	- new timeout unit test works. 
++
++Fri Jan 12 14:28:32 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: update code to new libTDS timeout code
++	* src/tds/net.c: handle send/recv errors
++	* src/tds/util.c: fix msgno if error not found in table
++
++Thu Jan 11 10:49:52 EST 2007	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql 
++	- fixed incorrect report when drivername is not a file
++
++Tue Jan 09 22:44:08 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: fix option problem
++
++Tue Jan  9 00:16:46 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* src/tds/net.c simpler tds_select, thanks Frediano
++
++Sun Jan  7 10:45:23 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* src/ctlib/ctutil.c works with tdserror()
++
++Sun Jan  7 00:41:19 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* include/tds.h
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/tds/net.c src/tds/query.c
++	* src/tds/token.c src/tds/util.c
++	- implement new timeout strategy using tds_select() and 
++	- calling the client library's error handler (via tdserror). 
++	- db-lib no worse than before, others not yet tested. 
++
++Fri Jan 05 14:08:53 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/token.c: new token
++	* src/tds/util.c: optimize
++
++Fri Jan  5 02:08:54 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* include/tds.h src/tds/net.c src/tds/util.c
++	- begin new timeout strategy, not done.
++
++Thu Jan  4 18:47:46 EST 2007	JK Lowden <jklowden@freetds.org>
++	* doc/bsqldb.txt src/apps/bsqldb.c nicer headers
++	* doc/osql.txt src/apps/osql allow ini location override
++
++Tue Jan  2 15:42:09 EST 2007	JK Lowden <jklowden@schemamania.org>
++	* include/dblib.h include/tds.h
++	* src/apps/tsql.c
++	* src/dblib/dblib.c src/dblib/dbutil.c
++	* src/tds/iconv.c src/tds/login.c src/tds/net.c
++	* src/tds/token.c src/tds/util.c
++	- replace tds_client_msg with tdserror()
++
++Mon Jan 01 12:56:50 CET 2007    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/tds/query.c:
++	- remove some warning compiling with SUN compiler
++	- Happy New Year
++
++Fri Dec 29 20:43:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: remove warning and optimize
++
++Fri Dec 29 20:42:41 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: remove warnings
++
++Fri Dec 29 20:05:00 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h: cleanup
++
++Fri Dec 29 20:03:30 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/rpc_ct_param.c:
++	* src/ctlib/unittests/rpc_ct_setparam.c src/odbc/odbc.c:
++	- remove warnings
++
++Fri Dec 29 17:18:42 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/tds/log.c:
++	- use localtime_r if available
++
++Fri Dec 29 10:06:56 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/log.c:
++	- avoid locking if no logging
++
++Tue Dec 26 15:57:38 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h	src/ctlib/unittests/array_bind.c:
++	* src/ctlib/unittests/ct_diagall.c:
++	* src/ctlib/unittests/get_send_data.c:
++	* src/ctlib/unittests/lang_ct_param.c:
++	* src/dblib/bcp.c src/dblib/dblib.c:
++	* src/dblib/dbutil.c src/dblib/rpc.c:
++	* src/dblib/xact.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/t0016.c src/odbc/connectparams.c:
++	* src/odbc/descriptor.c src/odbc/error.c:
++	* src/odbc/odbc.c src/odbc/odbc_checks.c:
++	* src/odbc/prepare_query.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/describecol.c src/pool/config.c:
++	* src/pool/main.c src/pool/member.c src/pool/stream.c:
++	* src/pool/user.c src/pool/util.c:
++	* src/replacements/readpassphrase.c:
++	* src/replacements/strtok_r.c src/replacements/vasprintf.c:
++	* src/server/login.c src/server/unittest.c:
++	* src/tds/config.c src/tds/convert.c src/tds/data.c:
++	* src/tds/getmac.c src/tds/iconv.c src/tds/locale.c:
++	* src/tds/login.c src/tds/net.c src/tds/numeric.c:
++	* src/tds/tds_checks.c src/tds/tdsstring.c src/tds/threadsafe.c:
++	* src/tds/write.c src/tds/unittests/common.h win32/winlogin.c:
++	* win32/winsetup.c:
++	- include stdarg.h always before stdio.h to fix portability
++	  issues defining va_list
++
++Tue Dec 26 13:54:25 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am src/tds/util.c src/tds/log.c (added):
++	- separate log stuff
++
++Sun Dec 24 12:40:19 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/descriptor.c: cleanup
++
++Fri Dec 22 09:34:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: fix typo error
++
++Mon Dec 21 14:07:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/iconv.c: use cp1252 instead of iso8859-1 for mssql
++
++Wed Dec 20 22:47:36 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/tds/iconv.c src/tds/token.c log server charset changes
++	* src/tds/unittests/convert.c permit varbinary
++
++Mon Dec 18 10:50:34 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am: distribute enum_cap.h
++
++Fri Dec 15 14:41:14 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/tds/tds_willconvert.pl allow varbinary
++
++Thu Dec 14 22:18:16 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/tds/mem.c src/tds/unittests/t0001.c
++	- Added tds_capability_set and enumerated capabilities
++	* src/tds/enum_cap.h added
++
++Tue Dec 12 08:45:12 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	- improve describecol test
++
++Sun Dec 10 16:04:02 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/faq.html minor fixes
++	* src/apps/tsql.c send *sybase* charset name in login record
++	* src/tds/net.c src/tds/read.c a little less logging
++
++Thu Dec  7 17:06:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: make get_send_data works
++
++Tue Dec  5 11:42:04 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/funccall.c: add a test
++
++Fri Dec  1 16:45:59 EST 2006	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h src/dblib/bcp.c src/apps/freebcp.c
++	- Changed freetbcp batch-copied information messages to 
++	- match the output of Sybase's bcp utility.  
++
++Wed Nov 29 15:46:38 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c fixed broken "go" option handling.
++
++Tue Nov 28 11:52:27 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c fix -o option code
++	* src/tds/net.c reorganize tds_open_socket()
++
++Mon Nov 27 18:31:18 EST 2006	JK Lowden <jklowden@freetds.org>
++	* src/tds/net.c more detailed log of connect(2)
++
++Sun Nov 26 15:26:31 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/apps/tsql.c added connection timer feedback
++	* src/tds/login.c src/tds/net.c slightly better logging
++
++Thu Nov 23 09:43:00 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c:
++	- fix possible problem with very remote servers
++
++Thu Oct 26 15:09:48 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dbutil.c log error message from server
++	* src/tds/net.c log TDS version
++
++Thu Oct 26 14:26:27 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/common.c src/dblib/unittests/common.h
++	* src/dblib/unittests/t0001.c
++	- corrected command-line option handling
++
++Sat Oct 21 16:42:08 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/dblib.c src/dblib/unittests/t0022.c:
++	- dbresults succeeds if metadata or only return status is
++	- present, cf. ML yesterday.
++
++Sat Oct 21 14:22:44 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* autogen.sh: fix some portability issues
++
++Wed Oct 18 21:38:57 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/tables.c:
++	- fix problem with mssql2005 and SQLTables
++
++Mon Oct 16 09:48:31 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: reduce system calls required
++
++Thu Oct 12 11:19:02 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c:
++	- fix wrong assert
++	- return correctly RETURNSTATUS under Sybase
++
++Wed Oct 11 16:37:04 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix wrong assert using numerics
++
++Tue Oct 10 15:52:22 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* doc/osql.txt clarified
++
++Fri Oct  6 17:08:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/freebcp.c src/apps/freebcp.h doc/freebcp.txt
++	- applied -0 patch from ML
++	- by Constantin Vasilyev <vasilyev@ncbi.nlm.nih.gov>
++
++Wed Oct  4 19:46:29 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/apps/freebcp.c 
++	- applied -P from stdin patch 
++	- from ML Constantin Vasilyev <vasilyev@ncbi.nlm.nih.gov>
++
++Wed Oct  4 17:36:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql GNU sed does not support -E
++
++Wed Oct  4 14:48:20 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/osql.txt added osql man page
++
++Wed Oct  4 14:12:25 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am add osql as installable script
++
++Tue Oct  3 15:40:12 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c test fwrite(3) correctly
++
++Tue Sep 26 16:57:42 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/dblib.c
++	* src/tds/convert.c src/tds/net.c src/tds/token.c
++	- added more user-level error checking, checking against 
++	- known list of db-lib error messages
++	* src/apps/osql added
++
++Wed Sep 13 13:55:24 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* samples/Makefile.am samples/unixodbc.freetds.driver.template.in:
++	- add Setup entry to unixODBC template
++	- unixODBC templates are not executables
++
++Wed Sep 13 13:52:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: enable wide table
++
++Wed Sep 13 11:47:27 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c:
++	- fix really broken tds5_process_result
++
++Fri Sep 08 11:58:24 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/tds/threadsafe.c:
++	- fix threadsafe problem on NetBSD
++
++Fri Sep 08 11:17:55 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/token.c: make splint a bit more happy
++	* src/odbc/odbc.c: small 64bit improvements
++
++Thu Sep 07 23:10:29 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c: fix paramset (Levente Tamási)
++
++Fri Sep  1 10:34:20 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h include/tdsstring.h src/ctlib/ct.c:
++	* src/odbc/connectparams.c src/odbc/odbc.c src/server/login.c:
++	* src/tds/config.c src/tds/tdsstring.c:
++	- add dstr_size to DSTR
++	- add tds_dstr_alloc, tds_dstr_setlen, tds_dstr_buf
++
++Wed Aug 30 13:58:56 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/challenge.c src/tds/login.c:
++	- make tds_answer_challenge return flags
++	- tds_dstr fix
++	* src/dblib/dblib.c: small fix
++	* src/odbc/odbc.c: constification
++	* src/tds/query.c:
++	- some static functions rename
++	- do not convert string in tds7_build_param_def_from_query
++	* src/tds/threadsafe.c: cleanup
++
++Mon Aug 28 09:36:32 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/cspublic.h:
++	- applied Norbert Sendetzky patch for ctlib compatibility
++
++Fri Aug 25 11:03:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/t0017.c:
++	* src/dblib/unittests/t0017.in.be(added):
++	- fix big endian problem with t0017 test
++
++Fri Aug 25 09:17:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: remove 1024 char limit on tsql_readline
++
++Thu Aug 24 21:18:48 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: applied Christos Zoulas patch for no-tty
++
++Thu Aug 24 16:29:17 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/sybdb.h src/dblib/dblib.c:
++	- do not change compatibility
++	* src/tds/config.c: small optimization
++
++Thu Aug 24 11:37:15 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/sprintf_i64_format.m4: fix 64bit problem for LP64
++
++Thu Aug 24 11:17:26 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/apps/tsql.c src/ctlib/Makefile.am:
++	* src/dblib/Makefile.am src/tds/net.c win32/initnet.c:
++	* win32/winsetup.c win32/dev-cpp/FreeTDS.dev:
++	* win32/dev-cpp/Makefile.win win32/msvc6/FreeTDS.dsp:
++	- initialize socket library on win32
++
++Thu Aug 24 08:32:07 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c:
++	- do not print return status if quiet (patch from Christos Zoulas)
++
++Wed Aug 23 21:43:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tsql.txt: applied Christos Zoulas updates
++	* doc/txt2man: updated
++
++Wed Aug 23 17:16:10 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- clean error before reading SO_ERROR, some system need this
++	* src/tds/util.c src/ctlib/ct.c: cross compile fixes
++
++Wed Aug 23 16:25:25 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* m4/ac_tds_func_which_getpwuid_r.m4 m4/sprintf_i64_format.m4:
++	* configure.ac src/ctlib/cs.c src/apps/tsql.c:
++	* src/replacements/asprintf.c src/tds/query.c:
++	- fixes some cross compile issues with hp-ux
++
++Mon Aug 21 11:08:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: remove small buffer overflow
++
++Thu Aug 17 11:13:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds.h src/dblib/unittests/Makefile.am:
++	* src/tds/net.c src/tds/query.c src/tds/token.c src/tds/util.c:
++	* m4/acx_pthread.m4(added):
++	- timeout more precise and use monotonic clock if available
++	- check pthread support more deeply
++
++Wed Aug 16 13:04:48 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: cleanup, fix possible problem under Linux
++	* src/tds/read.c: avoid invalid in_pos value on tds_peek
++
++Mon Aug 14 19:12:58 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c src/dblib/bcp.c src/dblib/dblib.c:
++	* src/dblib/unittests/common.c:
++	- fix warnings compiling with SUN cc
++	* src/dblib/unittests/thread.c: make error more verbose
++
++Sun Aug 13 15:02:40 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/data.c:
++	* src/odbc/unittests/transaction.c:
++	- fix minor issues with 64-bit machines
++
++Thu Aug 10 10:10:30 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: fix possible buffer overflow
++	* src/replacements/gettimeofday.c: add comment
++	* src/tds/threadsafe.c: better and simple win implementation
++	* vms/descrip_mms.template win32/config.h:
++	* win32/dev-cpp/FreeTDS.dev win32/msvc6/libTDS.dsp:
++	- update build file
++
++Tue Aug 08 19:14:32 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/htdoc/index.html: update link
++	* src/tds/query.c: add comment
++
++Tue Aug 08 16:42:39 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c src/tds/util.c:
++	- fix timeout problem setting correctly query_start_time
++
++Tue Aug 08 14:43:50 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/timeout2.c(added):
++	- added a test for timeout problem (cf "Query Time Out" on ML)
++
++Mon Aug 07 21:37:39 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsstring.h src/odbc/odbc_util.c:
++	* src/replacements/iconv.c src/tds/challenge.c:
++	* src/tds/config.c src/tds/convert.c:
++	* src/tds/iconv.c src/tds/mem.c src/tds/net.c:
++	* src/tds/query.c src/tds/read.c src/tds/tdsstring.c:
++	* src/tds/token.c src/tds/write.c:
++	- updated doxygen comments
++
++Sun Aug 06 17:54:11 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* freetds.spec.in: fix rpm build on suse
++
++Thu Aug 03 20:30:07 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* NEWS include/tds.h src/ctlib/ct.c src/odbc/odbc.c:
++	* src/tds/mem.c src/tds/query.c src/tds/tds_checks.c:
++	* src/tds/token.c src/tds/util.c:
++	- use reference counting for TDSCURSOR to avoid memory errors
++
++Thu Aug 03 10:32:37 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/iconv_fread.c(added):
++	* src/tds/iconv.c src/tds/unittests/.cvsignore:
++	* src/tds/unittests/Makefile.am:
++	- fix tds_iconv_fread and add a test for it
++
++Mon Jul 31 13:27:53 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c
++	- proper error message for using bcp with TDS version 4.2
++
++Mon Jul 31 13:23:44 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h src/dblib/dblib.c
++	- proper error message for using bcp with TDS version 4.2
++
++Thu Jul 27 15:22:27 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* samples/odbc_rpc.pl	use fetchrow_array
++	* src/tds/unittests/Makefile.am include parent directory
++
++Tue Jul 25 10:16:45 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac m4/ac_nullzero.m4: add test for portability
++
++Tue Jul 25 10:10:22 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/paramcore.c: updated
++
++Mon Jul 24 11:39:13 CET 2006    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/prepclose.c:
++	- test with SQLExecDirect
++
++Mon Jul 17 15:18:48 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/build_dsw.pl(removed):
++	* win32/build_dsw.pl(added) src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/Makefile.am:
++	- add a Makefile target to build projects for msvc6
++
++Thu Jul 13 10:20:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/unittests/moreandcount.c:
++	- remove next_row_count, now useless... rpc.c works the same
++
++Wed Jul 12 13:23:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/odbc/odbc.c src/tds/token.c:
++	- use TDS_NO_COUNT instead of bad rows_affected for next_row_count. 
++	- src/odbc/unittests/rpc.c now works
++
++Wed Jul 12 16:15:14 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/test-other.sh: add file log
++	* src/odbc/unittests/rpc.c: fix uninitialized error
++
++Tue Jul 11 17:52:43 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/odbc/odbc.c src/odbc/unittests/rpc.c:
++	- Better logging
++
++Tue Jul 11 17:28:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/done_handling.c: improve
++
++Tue Jul 11 17:27:26 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/paramcore.c:
++	- fix compatibility with sybase
++
++Tue Jul 11 11:56:53 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/online.pl: generate more friendly names
++
++Mon Jul 10 17:07:00 EDT 2006	JK Lowden <jklowden@freetds.org>
++	* src/tds/token.c src/dblib/dblib.c src/dblib/unittests/rpc.c
++	- dbresults does not return on DONEPROC
++
++Sun Jul 09 12:52:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* doc/Makefile.am: fix compatibility problem
++	* src/odbc/unittests/rpc.c: fix warning
++
++Fri Jul  7 19:08:44 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* include/sybdb.h src/dblib/dblib.c src/tds/token.c:
++	- Better logging
++
++Wed Jul 05 14:45:08 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/bcp.c:
++	* src/dblib/unittests/common.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/dbmorecmds.c:
++	* src/dblib/unittests/done_handling.c:
++	* src/dblib/unittests/rpc.c src/dblib/unittests/t0001.c:
++	* src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c:
++	* src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c:
++	* src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c:
++	* src/dblib/unittests/t0008.c src/dblib/unittests/t0009.c:
++	* src/dblib/unittests/t0011.c src/dblib/unittests/t0012.c:
++	* src/dblib/unittests/t0013.c src/dblib/unittests/t0014.c:
++	* src/dblib/unittests/t0015.c src/dblib/unittests/t0016.c:
++	* src/dblib/unittests/t0017.c src/dblib/unittests/t0018.c:
++	* src/dblib/unittests/t0019.c src/dblib/unittests/t0020.c:
++	* src/dblib/unittests/t0021.c src/dblib/unittests/t0022.c:
++	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c:
++	* src/dblib/unittests/thread.c:
++	* src/dblib/unittests/build_dsw.pl(added):
++	- put include stuff in common.h
++	- fix compile with ms dblib
++	- simplify testing under windows creating project files
++
++Wed Jul  5 18:29:21 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/dblib.c src/dblib/rpc.c:
++	- removed nonprintable characters from TDSDUMP log
++
++Wed Jul  5 15:43:24 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/unittests/rpc.c src/odbc/unittests/rpc.c:
++	- more thorough tests, currently fail
++
++Tue Jul 04 17:13:08 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/paramcore.c(added):
++	* src/odbc/unittests/.cvsignore src/odbc/sql2tds.c:
++	- test for core using SQLBindParameter, small fix
++
++Mon Jul 03 13:09:40 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c:
++	- assure there is always an error when SQL_ERROR is returned
++	- fix warning
++
++Fri Jun 30 10:31:49 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* src/odbc/sql2tds.c assert good pointer in case user passed NULL
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/rpc.c
++	- added new unit test, similar to that used in dblib.
++
++Thu Jun 29 17:05:35 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS src/tds/challenge.c:
++	- fix small buffer overflow
++	- reuse buffer
++
++Thu Jun 29 14:07:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/tds/Makefile.am src/tds/challenge.c:
++	* src/tds/login.c src/tds/token.c:
++	- add NTLM2 Session Response support
++
++Tue Jun 27 15:47:46 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/done_handling.c:
++	- improve
++	- update style
++	- fix typo
++
++Mon Jun 26 16:10:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* phptests/rpc2.php(added):
++	- test from Ellert van Koperen (cf "SP parameters" and 
++	  http://kb.vankoperen.nl/freetds-problems.html)
++
++Sun Jun 25 10:12:48 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/warning.c:
++	- tested
++	- fix portability problem with former Sybase db
++	- test returned warning
++
++Sun Jun 25 09:50:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/warning.c(added):
++	- added warning test from John K. Hohm (cf 
++	  "Warning return as copy of last result row" on ML)
++	* src/odbc/unittests/describecol.c: compile fix
++
++Wed Jun 21 17:03:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c:
++	* src/odbc/unittests/describecol.in(added):
++	- rewrote describecol test
++
++Wed Jun 21 09:26:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: improve column_length
++	* src/odbc/odbc_util.c: fix for odbc_sql_to_displaysize
++	* src/tds/iconv.c: invalid iconv_t is only -1, not NULL
++
++Tue Jun 20 17:52:19 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* src/odbc/unittests/array_out.c:
++	- rename variable to avoid libc	symbol conflict
++
++Tue Jun 20 14:38:03 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/convert.c: use macro in sprintf
++
++Tue Jun 20 14:34:03 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/mem.c: small macro to allocate columns
++
++Tue Jun 20 14:33:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c: improved a lot
++
++Tue Jun 20 11:15:16 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: catch error better
++
++Mon Jun 19 10:38:36 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* freetds.spec.in misc/test-other.sh src/apps/Makefile.am:
++	* src/ctlib/Makefile.am src/dblib/Makefile.am src/odbc/Makefile.am:
++	* src/server/Makefile.am src/tds/Makefile.am:
++	*  src/tds/unittests/Makefile.am:
++	- do not make libTDS shared library any more
++
++Mon Jun 19 09:57:23 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/ct.c src/odbc/sql2tds.c src/odbc/unittests/data.c:
++	* src/server/unittest.c:
++	- remove warning compiling with gcc4
++
++Thu Jun 15 14:15:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.ac src/ctlib/unittests/cancel.c:
++	* src/dblib/unittests/common.c src/odbc/Makefile.am:
++	* src/replacements/readpassphrase.c:
++	- finished cross mingw32
++
++Wed Jun 14 17:34:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/convert_tds2sql.c: fix for date format
++
++Wed Jun 14 17:29:13 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.ac: add function
++	* src/apps/Makefile.am src/dblib/unittests/Makefile.am:
++	* src/dblib/unittests/bcp.c src/odbc/unittests/Makefile.am:
++	* src/replacements/Makefile.am src/replacements/gettimeofday.c:
++	* src/tds/unittests/Makefile.am:
++	- more fixes for cross mingw32
++
++Wed Jun 14 13:26:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds_sysdep_private.h src/apps/Makefile.am:
++	- fix for cross mingw32
++	* src/odbc/unittests/describecol.c: report more clearly problems
++
++Tue Jun 13 20:17:16 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/common.h src/server/unittest.c:
++	- small fixes for cross mingw
++
++Tue Jun 13 14:38:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/prepclose.c(added) configure.ac:
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	- add test to test error closing connection on SQLPrepare
++
++Mon Jun 12 22:02:57 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* m4/sprintf_i64_format.m4: fix for cross mingw32
++
++Mon Jun 12 21:52:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/sql2tds.c: fix for possible uninitialized variable
++
++Mon Jun 12 21:48:15 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/apps/datacopy.c src/apps/freebcp.c src/apps/freebcp.h:
++	* src/pool/main.c src/pool/pool.h:
++	- fix some issues cross compiling for mingw32
++
++Mon Jun 12 16:55:59 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/data.c: add test for date to char
++
++Fri Jun  9 14:33:31 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* src/apps/tsql.c: inhibit readline tab completion in tsql
++
++Fri Jun 09 11:50:55 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* locales.conf: use same date format as Sybase in default and en_US
++
++Thu Jun 08 10:18:50 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/unittests/t0007.c:
++	- improved to detect possible date problems
++
++Wed Jun 07 14:37:56 EDT 2006	Nick Castellano <entropy@freetds.org>
++	* src/tds/convert.c: correctly convert dates in January
++
++Tue Jun 06 12:02:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.ac src/tds/config.c:
++	- fix tsql -C for sybase compatibility
++
++Tue Jun 06 11:32:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/mem.c: use calloc instead of malloc/memset
++
++Mon Jun 05 13:42:24 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/ct.c src/tds/token.c:
++	- style and cleanup
++
++Mon May 29 13:38:05 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* m4/sprintf_i64_format.m4: fix quoting
++
++Mon May 29 12:58:38 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS include/tds.h src/tds/token.c:
++	- make tds_alloc_get_string static
++
++Mon May 15 17:11:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c:
++	- applied fixes from Charlene Herring (cf. "Problems when
++	  using odbc : SQLPutData, SQLExecDirect,Decimals" 2006/05/14
++
++Sun May 14 14:34:04 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/descriptor.c: fix memory error
++
++Sat May 13 10:49:40 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/copydesc.c: improve
++
++Mon May 08 11:38:30 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/descriptor.c src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/copydesc.c(added): add test for SQLCopyDesc
++
++Fri Apr 21 17:10:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/sql2tds.c: use new tds_convert types
++
++Fri Apr 21 09:45:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* doc/htdoc/faq.html: fix html compatibility
++
++Thu Apr 20 12:10:28 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/unittests/ct_dynamic.c: remove leak in test
++
++Tue Apr 17 19:47:57 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/ct.c: fix double free
++
++Mon Apr 17 10:51:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/prepare_query.c:
++	- use new conversion style in ODBC
++
++Sun Apr 16 10:11:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/tds/locale.c src/tds/mem.c:
++	- TDSLOCALE changes to keep ABI
++
++Sat Apr 15 10:18:29 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsconvert.h 	* src/tds/convert.c:
++	- add new type of conversion for copy optimizations
++
++Sat Apr 15 10:02:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c: fix for older Sybase versions
++	* src/tds/config.c: optimize option read
++
++Sat Apr 15 09:03:34 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c: remove warning
++
++Fri Apr 14 15:22:02 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c:
++	- improved
++
++Fri Apr 14 13:55:09 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/describecol.c:
++	- add test for precision returned by SQLDescribeCol
++
++Wed Apr 12 21:41:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* locales.conf: fix charset typo
++	* doc/userguide.sgml: fix attributes for locales.conf
++
++Wed Apr 12 15:53:18 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h include/tds_sysdep_private.h:
++	* include/tds_sysdep_public.h.in include/tdsconvert.h:
++	* include/tdsver.h.in:
++	- avoid ident strings in all objects
++	* m4/sprintf_i64_format.m4: add Ld format
++
++Tue Apr 11 16:33:41 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds_sysdep_public.h.in include/tdsver.h.in:
++	- small constification
++
++Tue Apr 11 13:51:43 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/connect.c: do not fail if not FreeTDS
++	* src/odbc/unittests/raiserror.c: more verbose
++
++Mon Apr 10 18:14:17 EDT 2006	JK Lowden <jklowden@schemamania.org>
++	* include/tds.h src/apps/tsql.c src/tds/config.c
++	- report sysconfdir with tsql -C
++
++Mon Apr 10 11:59:53 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: cleanup
++
++Fri Apr 07 09:38:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/test-other.sh: update to php 5.1
++	* phptests/nextres.php: a bit more verbose
++
++Thu Apr 06 11:37:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/coverage.sh: less verbose 
++	* src/dblib/bcp.c: small change
++
++Wed Apr 05 08:42:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test.sh: cleanup
++	* misc/test-auto.sh: allow configuration
++	* misc/test-other.sh: make output suitable for online.pl
++	* src/apps/tsql.c:
++	- improve documentation
++	- fix problem for multiple options
++	* src/odbc/odbc.c src/tds/token.c: avoid void message to application
++
++Wed Apr 05 07:09:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: remove some warnings
++
++Wed Mar 29 18:25:54 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* m4/ac_caolan_func_which_gethostbyname_r.m4:
++	* m4/ac_have_inaddr_none.m4 m4/ac_have_malloc_options.m4:
++	* m4/ac_raf_func_which_getservbyname_r.m4:
++	* m4/ac_tds_func_which_gethostbyaddr_r.m4:
++	* m4/ac_tds_func_which_getpwuid_r.m4:
++	* m4/ac_tds_func_which_localtime_r.m4:
++	* m4/ax_cflags_gcc_option.m4 m4/lib-link.m4:
++	* m4/sprintf_i64_format.m4 m4/type_socklen_t.m4:
++	- quote as necessary
++
++Mon Mar 27 19:01:05 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* configure.ac
++	* m4/ac_caolan_func_which_gethostbyname_r.m4
++	* m4/ac_have_inaddr_none.m4
++	* m4/ac_have_malloc_options.m4
++	* m4/ac_raf_func_which_getservbyname_r.m4
++	* m4/ac_tds_func_which_gethostbyaddr_r.m4
++	* m4/ac_tds_func_which_getpwuid_r.m4
++	* m4/ac_tds_func_which_localtime_r.m4
++	* m4/ax_cflags_gcc_option.m4
++	* m4/sprintf_i64_format.m4
++	* m4/type_socklen_t.m4
++	* src/ctlib/unittests/Makefile.am
++	* src/dblib/unittests/Makefile.am
++	* src/odbc/unittests/Makefile.am
++	* src/tds/unittests/Makefile.am
++	- removed/updated obsolete autoconf macros
++	* m4/am_iconv.m4 removed 
++	* m4/README.iconv
++	* m4/iconv.m4 m4/lib-ld.m4 m4/lib-link.m4 m4/lib-prefix.m4
++	- added from GNU libiconv
++
++Mon Mar 27 09:48:56 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/index.html corrected nightly test link
++
++Mon Mar 27 10:17:42 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/rpc.c: allow again null for fixed types
++
++Mon Mar 27 02:20:16 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* configure.ac m4/am_iconv.m4 m4/check_openssl.m4
++	* src/apps/Makefile.am src/ctlib/Makefile.am src/dblib/Makefile.am
++	* src/odbc/Makefile.am src/pool/Makefile.am src/replacements/Makefile.am
++	* src/server/Makefile.am src/tds/Makefile.am
++	- modernized autotool contructs
++	* configure.in removed 
++
++Sun Mar 26 19:01:43 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/prepare_query.c:
++	- fixed constant parameters after mssql 2005 patch
++
++Fri Mar 24 16:47:26 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* configure.in removed, is now configure.ac 
++	* acinclude.m4 removed, added m4 directory
++	* Makefile.am include m4 directory
++	* m4/ac_caolan_func_which_gethostbyname_r.m4 m4/ac_have_inaddr_none.m4
++	* m4/ac_have_malloc_options.m4 m4/ac_raf_func_which_getservbyname_r.m4
++	* m4/ac_tds_func_which_gethostbyaddr_r.m4 
++	* m4/ac_tds_func_which_getpwuid_r.m4 
++	* m4/ac_tds_func_which_localtime_r.m4 m4/am_iconv.m4 
++	* m4/check_openssl.m4 m4/sprintf_i64_format.m4 m4/type_socklen_t.m4
++	- Split acinclude.m4 into one macro defintion per file.
++	* m4/ax_cflags_gcc_option.m4 
++	- Check for gcc features e.g. the declaration-after-statement warning.
++
++Fri Mar 24 13:03:36 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/docs.html doc/htdoc/index.html updated
++
++Fri Mar 24 12:36:02 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/htdoc/software.html fixed broken links added link to RC
++
++Fri Mar 24 16:27:27 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test.sh misc/test-auto.sh misc/full-test-ol.sh(removed):
++	- use an "online" version for test
++
++Thu Mar 23 15:53:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/earlybind.c:
++	* src/odbc/unittests/norowset.c src/odbc/unittests/t0004.c:
++	* src/odbc/unittests/tables.c src/tds/data.c src/tds/tds_checks.c:
++	- fixes for mssql 2005
++
++Thu Mar 23 13:48:23 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/tds/query.c: partially fix problem with mssql2k5
++
++Thu Mar 23 11:44:32 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test-ol.sh misc/online.pl misc/test-auto.sh:
++	- changed online.pl with James hints
++	- enable Valgrind tests using online check
++
++Tue Mar 21 15:24:04 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/cursor2.c(aded) src/odbc/unittests/Makefile.am:
++	- added test to check errors using cursor on no row statement
++
++Tue Mar 21 13:22:07 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/native.c:
++	- applied patch from Richard Krehbiel (cf "ODBC datetime literal issue")
++
++Tue Mar 21 08:49:44 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.in src/dblib/dblib.c:
++	- fix declaration after statements
++
++Mon Mar 20 15:28:25 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c: fix error in bcp_colfmt
++
++Mon Mar 20 15:00:45 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/rpc.c:
++	- remove some double checks
++	- return correct values from CHECK_PARAMETER
++	- fix some possible core if dbproc == NULL
++
++Mon Mar 20 09:42:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/full-test.sh: added timeout
++
++Sun Mar 19 18:34:47 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* misc/test-auto.sh: fix typo in header
++	* src/dblib/dblib.c: remove double checks
++
++Sun Mar 19 18:33:14 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/genparams.c src/odbc/unittests/transaction.c:
++	- remove warnings on 64bit int
++
++Sun Mar 19 09:27:09 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/bcp.c src/dblib/dblib.c more logging repairs
++
++Sat Mar 18 12:34:02 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* include/dblib.h src/dblib/bcp.c
++	- validate parameters.  Unable to run unittest due to down server.
++
++Sat Mar 18 01:27:32 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* include/dblib.h src/dblib/dblib.c src/dblib/rpc.c
++	- test parameters for all public functions (except bcp)
++
++Fri Mar 17 01:35:17 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/dblib.c src/dblib/rpc.c
++	- added a TDSDUMP log entry for every public function
++
++Thu Mar 16 09:59:25 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* TODO add rpc error messages
++	* src/apps/bsqldb.c exit if severity > 10
++
++Wed Mar 15 00:41:11 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* doc/freebcp.txt The freebcp manpage was seriously out of date.
++	* src/apps/freebcp.c give better error message.
++
++Thu Mar  9 14:33:37 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- add cursor_type to connection attributes (required for DBD::ODBC)
++	- removed small TODO on error report
++
++Mon Mar  6 12:55:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/ctlib/ct.c src/odbc/connectparams.c:
++	* src/pool/util.c src/server/login.c src/server/unittest.c:
++	* src/tds/config.c src/tds/login.c src/tds/mem.c:
++	- renamed host_name field to client_host_name
++	- optimize way strings are allocated
++
++Fri Feb 24 15:04:35 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/tds/config.c src/tds/login.c:
++	- nicer TDSDUMPCONFIG output, including a recap
++
++Sun Feb 19 14:56:15 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/odbc.c: fix wrong declaration
++
++Thu Feb 16 08:30:00 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/scroll.c src/odbc/unittests/raiserror.c:
++	* src/odbc/unittests/cursor1.c:
++	- remove warning compiling with gcc4
++	* misc/test-other.sh: fix problem with DBD:ODBC test
++
++Mon Feb 13 17:11:30 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/genparams.c: add BIGINT type to test
++
++Wed Feb  8 10:48:36 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
++	* vms/odbc_driver_axp.opt win32/FreeTDS.def:
++	- start cursor stuff for odbc
++	- added SQLSetScrollOptions
++	* src/odbc/unittests/scroll.c: support more fetch types
++
++Tue Feb  7 15:42:56 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/tds.h src/tds/query.c src/ctlib/ct.c NEWS:
++	- improve cursor support
++
++Tue Feb  7 14:22:50 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/scroll.c(added):
++	* src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/cursor1.c:
++	- add scroll test for cursor
++	- build msvc project for odbc unittests
++	* src/dblib/unittests/Makefile.am: add done_handling test
++
++Mon Feb  6 16:50:05 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* include/sybdb.h src/apps/freebcp.c src/dblib/bcp.c:
++	- implemented BCPKEEPIDENTITY for bcp_control
++	- make freebcp do not depend on dblib internals
++
++Mon Feb  6 16:44:27 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/cursor1.c:
++	- update cursor1 test
++
++Thu Feb  2 15:33:21 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS: updated
++	* src/odbc/odbc.c vms/odbc_driver_axp.opt win32/FreeTDS.def:
++	- compile SQLSetPos function
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/cursor1.c(added):
++	- added a test for cursors (do not work...)
++
++Tue Jan 31 14:27:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/apps/freebcp.c src/dblib/bcp.c:
++	- fix broken charcater conversion
++	- use calloc instead of malloc/memset
++	- support 64bit file on win32
++
++Tue Jan 31 09:59:28 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/dblib.c: do more argument check
++
++Mon Jan 30 16:29:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/ctlib/unittests/blk_out.c src/ctlib/unittests/ct_cursor.c:
++	* src/ctlib/unittests/ct_cursors.c src/ctlib/unittests/ct_dynamic.c:
++	* src/dblib/unittests/t0005.c src/dblib/unittests/t0014.c:
++	* src/dblib/unittests/t0022.c src/dblib/unittests/thread.c:
++	- reduce false errors
++
++Sat Jan 28 15:49:55 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c:
++	- update row allocation using new row_free
++	- fix native format
++	- correctly check and handle EOF
++	- change _bcp_build_bcp_record to direct send row (renamed to 
++	  _bcp_send_bcp_record)
++	- write error file only if needed
++	* src/dblib/unittests/t0016.c: improved
++	* src/dblib/unittests/t0016.in:
++	- make input same of output
++	* src/dblib/unittests/t0017.c: get all data
++	* src/tds/mem.c: reset pointer just freed
++
++Sat Jan 28 09:39:10 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/unittests/t0017.c: reformat output
++
++Fri Jan 27 14:34:09 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/bcp.c recognize EOF errors from _bcp_read_hostfile
++
++Fri Jan 27 10:43:54 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/dblib/unittests/t0017.c better feedback
++
++Thu Jan 26 13:58:51 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/apps/freebcp.c src/apps/freebcp.h:
++	- support for NUL in terminators
++
++Wed Jan 25 15:33:20 CET 2006    Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* src/dblib/bcp.c: fix return test for fseeko
++
++Wed Jan 25 15:01:51 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* acinclude.m4 configure.in src/tds/numeric.c:
++	- use 64bit sprintf format if available
++	* misc/test-other.sh: redirect odbc to compiled driver
++
++Tue Jan 24 16:01:41 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* NEWS include/tds.h src/apps/tsql.c src/ctlib/blk.c:
++	* src/ctlib/ct.c src/dblib/bcp.c src/dblib/buffering.h:
++	* src/dblib/dblib.c src/dblib/rpc.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c src/odbc/prepare_query.c:
++	* src/odbc/sql2tds.c src/pool/stream.c src/server/server.c:
++	* src/tds/mem.c src/tds/query.c src/tds/tds_checks.c:
++	* src/tds/token.c src/tds/unittests/dataread.c:
++	* src/tds/unittests/dynamic1.c src/tds/unittests/t0002.c:
++	* src/tds/unittests/t0004.c src/tds/unittests/t0005.c:
++	* src/tds/unittests/t0006.c src/tds/unittests/utf8_1.c:
++	* src/tds/unittests/utf8_2.c:
++	- use direct pointer column_data instead of old column_offset
++
++Mon Jan 23 17:30:38 EST 2006	JK Lowden <jklowden@schemamania.org>
++	* src/apps/bsqldb.c bind to printable width, not column size
++
++Mon Jan 23 14:04:44 CET 2006	Frediano Ziglio <freddyz77_A_lycos_D_com>
++	* configure.in: start developing 0.65 version
++$Id: ChangeLog-0.82,v 1.1 2008/01/10 01:01:38 jklowden Exp $
+
+commit b10c0ecf799e3db6bf8e2617fd29aba4e5000e57
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 01:02:20 2008 +0000
+
+    formatting
+
+diff --git a/ChangeLog b/ChangeLog
+index ad8d878..1bfbe78 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,5 +1,5 @@
+ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+-	- ChangeLog-0.82 added because of release
++	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2455 2008/01/10 01:01:31 jklowden Exp $
++$Id: ChangeLog,v 1.2456 2008/01/10 01:02:20 jklowden Exp $
+
+commit b9bbaa400d6a758e9dd6896035f971fc41dacf7b
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 08:47:37 2008 +0000
+
+    fix SQLNumResultCols() is wrong (+1) problem
+
+diff --git a/ChangeLog b/ChangeLog
+index 1bfbe78..d1d80dd 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,5 +1,10 @@
++Thu Jan 10 09:46:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am:
++	- small fix for hidden fields (ignore them entirely)
++
+ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2456 2008/01/10 01:02:20 jklowden Exp $
++$Id: ChangeLog,v 1.2457 2008/01/10 08:47:37 freddy77 Exp $
+diff --git a/TODO b/TODO
+index 6b770b4..49074e8 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to Source Forge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.165 2007/12/26 20:56:00 freddy77 Exp $
++To Do List	$Id: TODO,v 1.166 2008/01/10 08:47:37 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -131,6 +131,14 @@ For future versions (in priority order within library):
+ . report error just before returning SQL_ERROR from inner function?
+ 
+ . test and fix: hidden fields (FOR BROWSE select, see flag test on tds)
++ - what happen if we bind to an hidden field??
++ - if we use SQLGetData??
++ - if we request informations with SQLDescribeCol/SQLColAttribute(s)/
++   SQLGetDescField??
++ - as you noted returning # columns hidden fields are not counted (there
++   is however a setting which is a mssql extension which threat hidden
++   columns as normal)
++ (cfr "SQLNumResultCols() is wrong (+1)" Jan 8 2008)
+ . test: all binding types (input and output)
+ . test: descriptors work
+   - ODBC 2 type returned (datetime)
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 7180d23..a19f734 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.464 2008/01/06 10:48:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.465 2008/01/10 08:47:37 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -2652,7 +2652,7 @@ odbc_ird_check(TDS_STMT * stmt)
+ 		return;
+ 
+ 	/* check columns number */
+-	assert(ird->header.sql_desc_count == cols || ird->header.sql_desc_count == 0);
++	assert(ird->header.sql_desc_count <= cols || ird->header.sql_desc_count == 0);
+ 
+ 
+ 	/* check all columns */
+@@ -2717,6 +2717,10 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		return SQL_SUCCESS;
+ 	num_cols = res_info->num_cols;
+ 
++	/* ignore hidden columns... TODO correct? */
++	while (num_cols > 0 && res_info->columns[num_cols - 1]->column_hidden == 1)
++		--num_cols;
++
+ 	if (desc_alloc_records(ird, num_cols) != SQL_SUCCESS) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		return SQL_ERROR;
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index d6eea5a..1316adb 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -62,3 +62,4 @@ cursor3
+ cursor4
+ cursor5
+ attributes
++hidden
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index e68b0a4..14726b2 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.68 2007/12/19 14:36:05 freddy77 Exp $
++# $Id: Makefile.am,v 1.69 2008/01/10 08:47:38 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -20,7 +20,7 @@ TESTS		=	\
+ 			paramcore$(EXEEXT) timeout2$(EXEEXT) timeout3$(EXEEXT) \
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+-			attributes$(EXEEXT)
++			attributes$(EXEEXT) hidden$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -77,6 +77,7 @@ cursor3_SOURCES	= cursor3.c common.c common.h
+ cursor4_SOURCES	= cursor4.c common.c common.h
+ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
++hidden_SOURCES	= hidden.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+
+commit 49951943657f47fb003342a116ec3e77a833bed4
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 08:54:46 2008 +0000
+
+    fix SQLNumResultCols() is wrong (+1) problem
+
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+new file mode 100755
+index 0000000..d9b6b25
+--- /dev/null
++++ b/src/odbc/unittests/hidden.c
+@@ -0,0 +1,96 @@
++/* Testing result column numbers having hidden columns */
++/* Test from Sebastien Flaesch */
++
++#include "common.h"
++
++static char software_version[] = "$Id: hidden.c,v 1.2 2008/01/10 08:54:46 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++#define CHECK_RCODE(t,h,m) \
++   if ( rcode != SQL_NO_DATA \
++     && rcode != SQL_SUCCESS \
++     && rcode != SQL_SUCCESS_WITH_INFO  \
++     && rcode != SQL_NEED_DATA ) { \
++      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
++      getErrorInfo(t,h); \
++      exit(1); \
++   }
++
++static void
++getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
++{
++	SQLRETURN rcode = 0;
++	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
++	SQLINTEGER naterror = 0;
++	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
++	SQLSMALLINT msgtextl = 0;
++
++	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
++			      (SQLHANDLE) sqlhandle,
++			      (SQLSMALLINT) 1,
++			      (SQLCHAR *) sqlstate,
++			      (SQLINTEGER *) & naterror,
++			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
++	fprintf(stderr, "Diagnostic info:\n");
++	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
++	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
++	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
++}
++
++int
++main(int argc, char **argv)
++{
++	SQLRETURN rcode;
++	SQLHSTMT m_hstmt1;
++	SQLSMALLINT cnt = 0;
++	int failed = 0;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	Command(Statement, "CREATE TABLE #t1 ( k INT, c CHAR(10), vc VARCHAR(10) )");
++	Command(Statement, "CREATE TABLE #tmp1 (i NUMERIC(10,0) IDENTITY PRIMARY KEY, b VARCHAR(20) NULL, c INT NOT NULL)");
++
++	/* test hidden column with FOR BROWSE */
++	ResetStatement();
++
++	m_hstmt1 = Statement;
++
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c, b FROM #tmp1", SQL_NTS);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect");
++
++	rcode = SQLNumResultCols(m_hstmt1, &cnt);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLNumResultCols 1");
++
++	if (cnt != 2) {
++		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
++		failed = 1;
++	}
++	ResetStatement();
++
++	/* test hidden column with cursors*/
++	CheckCursor();
++
++	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
++	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++
++	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLPrepare 1");
++
++	rcode = SQLExecute(m_hstmt1);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecute 1");
++
++	rcode = SQLNumResultCols(m_hstmt1, &cnt);
++	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLNumResultCols 1");
++
++	if (cnt != 3) {
++		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
++		failed = 1;
++	}
++
++	Disconnect();
++
++	return failed ? 1: 0;
++}
+
+commit ea3ce27c24032abbdd44c8453cc23d291b466583
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 13:11:07 2008 +0000
+
+    fix SQLGetData problem
+
+diff --git a/ChangeLog b/ChangeLog
+index d1d80dd..bb41c3d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jan 10 14:10:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/blob1.c(added):
++	- fix problem with SQLGetData and blobs
++
+ Thu Jan 10 09:46:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am:
+@@ -7,4 +12,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2457 2008/01/10 08:47:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2458 2008/01/10 13:11:07 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a19f734..a638dc7 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.465 2008/01/10 08:47:37 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.466 2008/01/10 13:11:07 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4583,12 +4583,12 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		if (*pcbValue < 0)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 
+-		if (is_variable_type(colinfo->column_type)) {
++		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ 			/* calc how many bytes was readed */
+ 			int readed = cbValueMax;
+ 
+ 			/* FIXME test on destination char ??? */
+-			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && is_char_type(nSybType) && readed > 0)
++			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && readed > 0)
+ 				--readed;
+ 			if (readed > *pcbValue)
+ 				readed = *pcbValue;
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index 1316adb..d7c663e 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -63,3 +63,4 @@ cursor4
+ cursor5
+ attributes
+ hidden
++blob1
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+new file mode 100755
+index 0000000..838a507
+--- /dev/null
++++ b/src/odbc/unittests/blob1.c
+@@ -0,0 +1,224 @@
++/* Testing large objects */
++/* Test from Sebastien Flaesch */
++
++#include "common.h"
++
++static char software_version[] = "$Id: blob1.c,v 1.1 2008/01/10 13:11:08 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++#define CHECK_RCODE(t,h,m) \
++   if ( rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO && rcode != SQL_NO_DATA && rcode != SQL_NEED_DATA ) { \
++      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
++      getErrorInfo(t,h); \
++      exit(1); \
++   }
++
++#define NBYTES 10000
++
++static int failed = 0;
++
++static void
++getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
++{
++	SQLRETURN rcode = 0;
++	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
++	SQLINTEGER naterror = 0;
++	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
++	SQLSMALLINT msgtextl = 0;
++
++	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
++			      (SQLHANDLE) sqlhandle,
++			      (SQLSMALLINT) 1,
++			      (SQLCHAR *) sqlstate,
++			      (SQLINTEGER *) & naterror,
++			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
++	fprintf(stderr, "Diagnostic info:\n");
++	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
++	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
++	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
++}
++
++static void
++fill_chars(char *buf, size_t len, unsigned int start, unsigned int step)
++{
++	size_t n;
++
++	for (n = 0; n < len; ++n)
++		buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1));
++}
++
++static int
++check_chars(const char *buf, size_t len, unsigned int start, unsigned int step)
++{
++	size_t n;
++
++	for (n = 0; n < len; ++n)
++		if (buf[n] != 'a' + ((start+n) * step % ('z' - 'a' + 1)))
++			return 0;
++
++	return 1;
++}
++
++static int
++readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
++{
++	SQLRETURN rcode;
++	char buf[4096];
++	SQLLEN len, total = 0;
++	int i = 0;
++	int check;
++
++	printf(">> readBlob field %d\n", pos);
++	while (1) {
++		i++;
++		rcode = SQLGetData(stmth, pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len);
++		if (!SQL_SUCCEEDED(rcode) || len <= 0)
++			break;
++		if (len > (SQLLEN) sizeof(buf))
++			len = (SQLLEN) sizeof(buf);
++		printf(">>     step %d: %d bytes readed\n", i, (int) len);
++		if (pos == 1)
++			check = check_chars(buf, len, 123 + total, 1);
++		else
++			check =	check_chars(buf, len, 987 + total, 25);
++		if (!check) {
++			fprintf(stderr, "Wrong buffer content\n");
++			failed = 1;
++		}
++		total += len;
++	}
++	printf(">>   total bytes read = %d \n", (int) total);
++	if (total != 10000)
++		failed = 1;
++	return rcode;
++}
++
++int
++main(int argc, char **argv)
++{
++	SQLRETURN rcode;
++	SQLHSTMT m_hstmt = NULL;
++	int i;
++
++	int key;
++	SQLINTEGER vind0;
++	char buf1[NBYTES];
++	SQLINTEGER vind1;
++	char buf2[NBYTES];
++	SQLINTEGER vind2;
++	int cnt = 2;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	Command(Statement, "IF OBJECT_ID('tt') IS NOT NULL DROP TABLE tt");
++	Command(Statement, "CREATE TABLE tt ( k INT, t TEXT, b IMAGE, v INT )");
++
++	/* Insert rows ... */
++
++	for (i = 0; i < cnt; i++) {
++
++		m_hstmt = NULL;
++		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
++
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "insert into tt values ( ?, ?, ?, ? )", SQL_NTS);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
++
++		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 1");
++
++		SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 2");
++
++		SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3");
++
++		SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4");
++
++		key = i;
++		vind0 = 0;
++
++		fill_chars(buf1, NBYTES, 123, 1);
++		vind1 = SQL_LEN_DATA_AT_EXEC(NBYTES);
++
++		fill_chars(buf2, NBYTES, 987, 25);
++		vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES);
++
++		printf(">> insert... %d\n", i);
++		rcode = SQLExecute(m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLExecute StmtH");
++		while (rcode == SQL_NEED_DATA) {
++			char *p;
++
++			rcode = SQLParamData(m_hstmt, (SQLPOINTER) & p);
++			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
++			printf(">> SQLParamData: ptr = %p  rcode = %d\n", (void *) p, rcode);
++			if (rcode == SQL_NEED_DATA) {
++				SQLRETURN rcode = SQLPutData(m_hstmt, p, NBYTES);
++
++				CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++				printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++			}
++		}
++
++		rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFreeHandle StmtH");
++
++	}
++
++	/* No fetch rows ... */
++
++	for (i = 0; i < cnt; i++) {
++
++		m_hstmt = NULL;
++		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
++
++		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
++		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM tt WHERE k = ?", SQL_NTS);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
++
++		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 1");
++
++		SQLBindCol(m_hstmt, 1, SQL_C_BINARY, NULL, 0, &vind1);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2");
++		SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3");
++		SQLBindCol(m_hstmt, 3, SQL_C_LONG, &key, 0, &vind0);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1");
++
++		vind0 = 0;
++		vind1 = SQL_DATA_AT_EXEC;
++		vind2 = SQL_DATA_AT_EXEC;
++
++		rcode = SQLExecute(m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLExecute StmtH");
++
++		rcode = SQLFetchScroll(m_hstmt, SQL_FETCH_NEXT, 0);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFetchScroll StmtH");
++		printf(">> fetch... %d  rcode = %d\n", i, rcode);
++
++		rcode = readBlob(m_hstmt, 1);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
++		rcode = readBlob(m_hstmt, 2);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
++
++		rcode = SQLCloseCursor(m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH");
++
++		rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFreeHandle StmtH");
++	}
++
++	Disconnect();
++
++	return failed ? 1 : 0;
++}
++
+
+commit 53181ec91693d58dfee70e7c1ce4bc66b05de712
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 13:21:12 2008 +0000
+
+    fix SQLGetData problem
+
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 14726b2..830c6c5 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.69 2008/01/10 08:47:38 freddy77 Exp $
++# $Id: Makefile.am,v 1.70 2008/01/10 13:21:12 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -20,7 +20,7 @@ TESTS		=	\
+ 			paramcore$(EXEEXT) timeout2$(EXEEXT) timeout3$(EXEEXT) \
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+-			attributes$(EXEEXT) hidden$(EXEEXT)
++			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -78,6 +78,7 @@ cursor4_SOURCES	= cursor4.c common.c common.h
+ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
+ hidden_SOURCES	= hidden.c common.c common.h
++blob1_SOURCES	= blob1.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+
+commit e88fe96932f46fb3b1db41e1c967373ec153a831
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 15:26:51 2008 +0000
+
+    updates for new version
+
+diff --git a/ChangeLog b/ChangeLog
+index bb41c3d..1a6b943 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 10 16:25:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/README.releasing misc/freetds_autobuild: updates
++
+ Thu Jan 10 14:10:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/blob1.c(added):
+@@ -12,4 +15,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2458 2008/01/10 13:11:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2459 2008/01/10 15:26:51 freddy77 Exp $
+diff --git a/doc/README.releasing b/doc/README.releasing
+index cae6dc0..a4c60df 100644
+--- a/doc/README.releasing
++++ b/doc/README.releasing
+@@ -2,11 +2,12 @@ It's pretty simple, basically:
+ 
+ 0) Form a branch in cvs:
+ 
+-	$ cvs tag -b BRANCH0_xx	
+-   
+-   Use the form BRANCH0_xx, where xx is the release number.  This affects only
++	$ cvs tag branch-0_xx
++	$ cvs tag -b Branch-0_xx
++ 
++   Use the form Branch-0_xx, where xx is the release number.  This affects only
+    the repository, not the working directory.  
+-   
++ 
+ 1) Change the version number in configure.ac and UG.  
+ 2) Update web pages regarding purpose and status of rc.  
+ 3) Put out a release candidates until everyone's happy.  
+@@ -50,4 +51,4 @@ less important per step ;-)
+     convention for naming - .tar.gz for tar and gzip, rather than .tgz.
+ 
+ --
+-$Id: README.releasing,v 1.10 2008/01/08 13:29:40 freddy77 Exp $
++$Id: README.releasing,v 1.11 2008/01/10 15:26:51 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 7217a27..a78d6f4 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -9,7 +9,7 @@ export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:$HOME
+ 
+ GROUPDIR=/home/groups/f/fr/freetds/htdocs
+ # directory to compile
+-FTDSDIR=freetds65
++FTDSDIR=freetds82
+ # output directory on server
+ OUTDIR=out
+ # additional flags for Autogen (current version)
+
+commit 637220d3666abf47363cb5217e96796bbc6ba3ab
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 15:29:03 2008 +0000
+
+    use temporary tables
+
+diff --git a/ChangeLog b/ChangeLog
+index 1a6b943..238d403 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jan 10 16:28:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c src/odbc/unittests/cursor3.c:
++	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
++	- use temporary tables
++
+ Thu Jan 10 16:25:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/README.releasing misc/freetds_autobuild: updates
+ 
+@@ -15,4 +20,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2459 2008/01/10 15:26:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2460 2008/01/10 15:29:03 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 838a507..9e4be47 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.1 2008/01/10 13:11:08 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.2 2008/01/10 15:29:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -111,8 +111,7 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "IF OBJECT_ID('tt') IS NOT NULL DROP TABLE tt");
+-	Command(Statement, "CREATE TABLE tt ( k INT, t TEXT, b IMAGE, v INT )");
++	Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b IMAGE, v INT )");
+ 
+ 	/* Insert rows ... */
+ 
+@@ -122,7 +121,7 @@ main(int argc, char **argv)
+ 		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ 		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "insert into tt values ( ?, ?, ?, ? )", SQL_NTS);
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ? )", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+ 
+ 		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+@@ -181,7 +180,7 @@ main(int argc, char **argv)
+ 		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM tt WHERE k = ?", SQL_NTS);
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+ 
+ 		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index 791783a..d44fe3c 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,7 +1,7 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.3 2007/12/21 10:39:10 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.4 2008/01/10 15:29:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLHDBC m_hdbc;
+@@ -69,12 +69,11 @@ main(int argc, char **argv)
+ 
+ 	m_hdbc = Connection;
+ 
+-	exec_direct(0, "DROP TABLE t1");
+-	exec_direct(1, "CREATE TABLE t1 ( k INT, c VARCHAR(20))");
+-	exec_direct(1, "INSERT INTO t1 VALUES (1, 'aaa')");
+-	exec_direct(1, "INSERT INTO t1 VALUES (2, 'bbbbb')");
+-	exec_direct(1, "INSERT INTO t1 VALUES (3, 'ccccccccc')");
+-	exec_direct(1, "INSERT INTO t1 VALUES (4, 'dd')");
++	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
++	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
++	exec_direct(1, "INSERT INTO #t1 VALUES (2, 'bbbbb')");
++	exec_direct(1, "INSERT INTO #t1 VALUES (3, 'ccccccccc')");
++	exec_direct(1, "INSERT INTO #t1 VALUES (4, 'dd')");
+ 
+ 	m_hstmt1 = NULL;
+ 	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+@@ -114,10 +113,10 @@ main(int argc, char **argv)
+ 	rcode = SQLSetCursorName(m_hstmt2, (SQLCHAR *) "c2", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SetCursorName c2");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM t1", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Prepare 1");
+ 
+-	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "SELECT * FROM t1", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "Prepare 2");
+ 
+ 	rcode = SQLExecute(m_hstmt1);
+@@ -152,8 +151,6 @@ main(int argc, char **argv)
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLFreeHandle 2");
+ 
+-	exec_direct(1, "DROP TABLE t1");
+-
+ 	Disconnect();
+ 
+ 	return 0;
+diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c
+index b352644..ef67014 100755
+--- a/src/odbc/unittests/cursor4.c
++++ b/src/odbc/unittests/cursor4.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.3 2007/12/21 10:39:10 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.4 2008/01/10 15:29:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLHDBC m_hdbc;
+@@ -72,9 +72,8 @@ main(int argc, char **argv)
+ 
+ 	m_hdbc = Connection;
+ 
+-	exec_direct(0, "DROP TABLE t1");
+-	exec_direct(1, "CREATE TABLE t1 ( k INT, c VARCHAR(20))");
+-	exec_direct(1, "INSERT INTO t1 VALUES (1, 'aaa')");
++	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
++	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
+ 
+ 	m_hstmt1 = NULL;
+ 	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+@@ -86,7 +85,7 @@ main(int argc, char **argv)
+ 	rcode = SQLSetCursorName(m_hstmt1, (SQLCHAR *) "c112", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SetCursorName c112");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM t1 FOR UPDATE", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1 FOR UPDATE", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Prepare 2");
+ 
+ 	exec_direct(1, "BEGIN TRANSACTION");
+@@ -97,14 +96,14 @@ main(int argc, char **argv)
+ 	rcode = SQLFetch(m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFetch 1");
+ 
+-	exec_direct(1, "UPDATE t1 SET c = 'xxx' WHERE CURRENT OF c112");
++	exec_direct(1, "UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");
+ 
+ 	rcode = SQLCloseCursor(m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLCloseCursor 2");
+ 
+ 	exec_direct(1, "COMMIT TRANSACTION");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c FROM t1 WHERE k = 1", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c FROM #t1 WHERE k = 1", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 2");
+ 
+ 	rcode = SQLFetch(m_hstmt1);
+@@ -118,8 +117,6 @@ main(int argc, char **argv)
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle 1");
+ 
+-	exec_direct(1, "DROP TABLE t1");
+-
+ 	Disconnect();
+ 
+ 	return 0;
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index c7be7e4..53f380b 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.2 2007/12/21 10:39:10 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.3 2008/01/10 15:29:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -76,15 +76,14 @@ main(int argc, char **argv)
+ 	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle StmtH 2");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "drop table mytab1", SQL_NTS);
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "create table mytab1 (k int, c char(30))", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "create table #mytab1 (k int, c char(30))", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.1");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into mytab1 values (1,'aaa')", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (1,'aaa')", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.2");
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into mytab1 values (2,'bbb')", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (2,'bbb')", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.3");
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into mytab1 values (3,'ccc')", SQL_NTS);
++	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (3,'ccc')", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.4");
+ 
+ /*
+@@ -95,7 +94,7 @@ main(int argc, char **argv)
+ 	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLSetStmtAttr 1");
+ 
+-	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "select k, c from mytab1 order by k", SQL_NTS);
++	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "select k, c from #mytab1 order by k", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLPrepare 3");
+ 
+ 	rcode = SQLBindCol(m_hstmt2, 1, SQL_C_LONG, &v_int_3, 0, &v_ind_3_1);
+@@ -126,9 +125,6 @@ main(int argc, char **argv)
+ 	rcode = SQLCloseCursor(m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLCloseCursor StmtH 2");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "drop table mytab1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.3");
+-
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle StmtH 1");
+ 
+
+commit 7f82734a2bd3cb45de9711bc31a48a2ae3b7113d
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 16:05:59 2008 +0000
+
+    add a test for SQLCancel which seems broken
+
+diff --git a/ChangeLog b/ChangeLog
+index 238d403..30115b3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jan 10 17:04:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/cancel.c(added):
++	- add test for SQLCancel
++
+ Thu Jan 10 16:28:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c src/odbc/unittests/cursor3.c:
+ 	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
+@@ -20,4 +25,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2460 2008/01/10 15:29:03 freddy77 Exp $
++$Id: ChangeLog,v 1.2461 2008/01/10 16:05:59 freddy77 Exp $
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index d7c663e..ae23946 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -64,3 +64,4 @@ cursor5
+ attributes
+ hidden
+ blob1
++cancel
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 830c6c5..7fca97b 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.70 2008/01/10 13:21:12 freddy77 Exp $
++# $Id: Makefile.am,v 1.71 2008/01/10 16:05:59 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -20,7 +20,8 @@ TESTS		=	\
+ 			paramcore$(EXEEXT) timeout2$(EXEEXT) timeout3$(EXEEXT) \
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+-			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT)
++			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
++			cancel$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -79,6 +80,7 @@ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
+ hidden_SOURCES	= hidden.c common.c common.h
+ blob1_SOURCES	= blob1.c common.c common.h
++cancel_SOURCES = cancel.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+new file mode 100644
+index 0000000..b01630f
+--- /dev/null
++++ b/src/odbc/unittests/cancel.c
+@@ -0,0 +1,96 @@
++/* Testing SQLCancel() */
++
++#include "common.h"
++#include <signal.h>
++
++#ifdef HAVE_ALARM
++
++#define CHECK_RCODE(t,h,m) \
++   if ( rcode != SQL_NO_DATA \
++     && rcode != SQL_SUCCESS \
++     && rcode != SQL_SUCCESS_WITH_INFO  \
++     && rcode != SQL_NEED_DATA ) { \
++      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
++      getErrorInfo(t,h); \
++      exit(1); \
++   }
++
++static SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
++
++static void
++getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
++{
++	SQLRETURN rcode = 0;
++	SQLINTEGER naterror = 0;
++	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
++	SQLSMALLINT msgtextl = 0;
++
++	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
++			      (SQLHANDLE) sqlhandle,
++			      (SQLSMALLINT) 1,
++			      (SQLCHAR *) sqlstate,
++			      (SQLINTEGER *) & naterror,
++			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
++	fprintf(stderr, "Diagnostic info:\n");
++	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
++	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
++	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
++}
++
++static void
++exit_forced(int s)
++{
++	exit(1);
++}
++
++static void
++sigalrm_handler(int s)
++{
++	SQLRETURN rcode;
++
++	printf(">>>> SQLCancel() ...\n");
++	rcode = SQLCancel(Statement);
++	printf(">>>> ... SQLCancel done rcode = %d\n", rcode);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLCancel failed");
++
++	alarm(4);
++	signal(SIGALRM, exit_forced);
++}
++
++int
++main(int argc, char **argv)
++{
++	SQLRETURN rcode;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	printf(">> Select tab1...\n");
++	alarm(4);
++	signal(SIGALRM, sigalrm_handler);
++	rcode = SQLExecDirect(Statement, (SQLCHAR *) "WAITFOR DELAY '000:05:00'", SQL_NTS);
++	if (rcode != SQL_ERROR) {
++		fprintf(stderr, "SQLExecDirect should return error\n");
++		return 1;
++	}
++	getErrorInfo(SQL_HANDLE_STMT, Statement);
++	if (strcmp(sqlstate, "HY008") != 0) {
++		fprintf(stderr, "Unexpected sql state returned\n");
++		return 1;
++	}
++	printf(">> ...  done rcode = %d\n", rcode);
++	signal(SIGINT, NULL);
++
++	Disconnect();
++	return 0;
++}
++
++#else
++int
++main(void)
++{
++	printf("Not possible for this platform.\n");
++	return 0;
++}
++#endif
++
+
+commit 4457549eba093983d80f1cfdcfa44e35310c2ce0
+Author: freddy77 <freddy77>
+Date:   Thu Jan 10 21:19:47 2008 +0000
+
+    memory fixes
+
+diff --git a/ChangeLog b/ChangeLog
+index 30115b3..1fa8966 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jan 10 22:19:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cancel.c src/odbc/unittests/hidden.c:
++	- memory fixes
++
+ Thu Jan 10 17:04:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
+ 	* src/odbc/unittests/cancel.c(added):
+@@ -25,4 +29,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2461 2008/01/10 16:05:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2462 2008/01/10 21:19:47 freddy77 Exp $
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index b01630f..6aa5e3f 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -25,6 +25,7 @@ getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+ 	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+ 	SQLSMALLINT msgtextl = 0;
+ 
++	msgtext[0] = 0;
+ 	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+ 			      (SQLHANDLE) sqlhandle,
+ 			      (SQLSMALLINT) 1,
+@@ -76,6 +77,7 @@ main(int argc, char **argv)
+ 	getErrorInfo(SQL_HANDLE_STMT, Statement);
+ 	if (strcmp(sqlstate, "HY008") != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
++		Disconnect();
+ 		return 1;
+ 	}
+ 	printf(">> ...  done rcode = %d\n", rcode);
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+index d9b6b25..71124a6 100755
+--- a/src/odbc/unittests/hidden.c
++++ b/src/odbc/unittests/hidden.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.2 2008/01/10 08:54:46 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.3 2008/01/10 21:19:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -70,6 +70,7 @@ main(int argc, char **argv)
+ 
+ 	/* test hidden column with cursors*/
+ 	CheckCursor();
++	m_hstmt1 = Statement;
+ 
+ 	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+
+commit e28c151956bedc82ff4a97b8a90e083a026dcb1e
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 22:57:33 2008 +0000
+
+    moved some preprocessor logic to the header file
+
+diff --git a/ChangeLog b/ChangeLog
+index 1fa8966..f508d56 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Thu Jan 10 17:55:41 EST 2008	JK Lowden <jklowden@freetds.org>
++	* include/tds_sysdep_private.h src/tds/net.c
++	- moved some preprocessor logic to the header file
++	* INSTALL.CVS NEWS TODO doc/userguide.sgml
++	- updated documentation
++
+ Thu Jan 10 22:19:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cancel.c src/odbc/unittests/hidden.c:
+ 	- memory fixes
+@@ -29,4 +35,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2462 2008/01/10 21:19:47 freddy77 Exp $
++$Id: ChangeLog,v 1.2463 2008/01/10 22:57:33 jklowden Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 9b6fcb0..8adfb9b 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.23 2007/01/29 11:02:43 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.24 2008/01/10 22:57:33 jklowden Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -34,6 +34,12 @@
+ 
+ #define TDS_ADDITIONAL_SPACE 0
+ 
++#ifdef MSG_NOSIGNAL
++# define TDS_NOSIGNAL MSG_NOSIGNAL
++#else
++# define TDS_NOSIGNAL 0L
++#endif
++
+ #ifdef __cplusplus
+ extern "C"
+ {
+@@ -47,10 +53,11 @@ extern "C"
+ #endif				/* __INCvxWorksh */
+ 
+ #if defined(DOS32X)
+-#define READSOCKET(a,b,c)	recv((a), (b), (c), 0L)
+-#define WRITESOCKET(a,b,c)	send((a), (b), (c), 0L)
++#define READSOCKET(a,b,c)	recv((a), (b), (c), TDS_NOSIGNAL)
++#define WRITESOCKET(a,b,c)	send((a), (b), (c), TDS_NOSIGNAL)
+ #define CLOSESOCKET(a)		closesocket((a))
+ #define IOCTLSOCKET(a,b,c)	ioctlsocket((a), (b), (char*)(c))
++#define SOCKLEN_T int
+ #define select select_s
+ typedef int pid_t;
+ #define strcasecmp stricmp
+@@ -62,10 +69,11 @@ typedef int pid_t;
+ 
+ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+ #include <windows.h>
+-#define READSOCKET(a,b,c)	recv((a), (b), (c), 0L)
+-#define WRITESOCKET(a,b,c)	send((a), (b), (c), 0L)
++#define READSOCKET(a,b,c)	recv((a), (b), (c), TDS_NOSIGNAL)
++#define WRITESOCKET(a,b,c)	send((a), (b), (c), TDS_NOSIGNAL)
+ #define CLOSESOCKET(a)		closesocket((a))
+ #define IOCTLSOCKET(a,b,c)	ioctlsocket((a), (b), (c))
++#define SOCKLEN_T int
+ int  _tds_socket_init(void);
+ #define INITSOCKET()	_tds_socket_init()
+ void _tds_socket_done(void);
+@@ -120,21 +128,33 @@ typedef DWORD pid_t;
+ #endif /* !DONESOCKET */
+ 
+ #ifndef READSOCKET
+-#define READSOCKET(a,b,c)	read((a), (b), (c))
++# ifdef MSG_NOSIGNAL
++#  define READSOCKET(s,b,l)	recv((s), (b), (l), MSG_NOSIGNAL)
++# else
++#  define READSOCKET(s,b,l)	read((s), (b), (l))
++# endif
+ #endif /* !READSOCKET */
+ 
+ #ifndef WRITESOCKET
+-#define WRITESOCKET(a,b,c)	write((a), (b), (c))
++# ifdef MSG_NOSIGNAL
++#  define WRITESOCKET(s,b,l)	send((s), (b), (l), MSG_NOSIGNAL)
++# else
++#  define WRITESOCKET(s,b,l)	write((s), (b), (l))
++# endif
+ #endif /* !WRITESOCKET */
+ 
+ #ifndef CLOSESOCKET
+-#define CLOSESOCKET(a)		close((a))
++#define CLOSESOCKET(s)		close((s))
+ #endif /* !CLOSESOCKET */
+ 
+ #ifndef IOCTLSOCKET
+-#define IOCTLSOCKET(a,b,c)	ioctl((a), (b), (c))
++#define IOCTLSOCKET(s,b,l)	ioctl((s), (b), (l))
+ #endif /* !IOCTLSOCKET */
+ 
++#ifndef SOCKLEN_T
++# define SOCKLEN_T socklen_t
++#endif
++
+ #ifndef TDS_SDIR_SEPARATOR
+ #define TDS_SDIR_SEPARATOR "/"
+ #endif /* !TDS_SDIR_SEPARATOR */
+diff --git a/src/tds/net.c b/src/tds/net.c
+index c551127..741f9b4 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -99,7 +99,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.71 2007/12/12 06:27:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.72 2008/01/10 22:57:33 jklowden Exp $");
+ 
+ static int tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout_seconds);
+ 
+@@ -165,18 +165,12 @@ int
+ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout)
+ {
+ 	struct sockaddr_in sin;
+-#if !defined(DOS32X)
+ 	ioctl_nonblocking_t ioctl_nonblocking;
+-	int retval;
+-#endif
+-	int len;
++	SOCKLEN_T optlen;
++	
++	int retval, len;
+ 	int tds_error = TDSECONN;
+ 	char ip[20];
+-#if defined(DOS32X) || defined(WIN32)
+-	int optlen;
+-#else
+-	socklen_t optlen;
+-#endif
+ 
+ 	memset(&sin, 0, sizeof(sin));
+ 
+@@ -270,8 +264,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 			goto not_available;
+ 		}
+ 	}
+-
+-#endif
++#endif	/* not DOS32X */
+ 
+ 	/* check socket error */
+ 	optlen = sizeof(len);
+@@ -436,11 +429,9 @@ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfi
+ 		if ((len = tds_select(tds, &rfds, NULL, NULL, tds->query_timeout)) > 0) {
+ 			len = 0;
+ 			if (FD_ISSET(tds->s, &rfds)) {
+-#ifndef MSG_NOSIGNAL
++
+ 				len = READSOCKET(tds->s, buf + got, buflen);
+-#else
+-				len = recv(tds->s, buf + got, buflen, MSG_NOSIGNAL);
+-#endif
++
+ 				if (len < 0 && sock_errno == EAGAIN)
+ 					continue;
+ 				/* detect connection close */
+@@ -656,10 +647,8 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *p, int len, unsigned char la
+ 				/* In case the kernel does not support MSG_MORE, try again without it */
+ 				if (nput < 0 && errno == EINVAL && !last)
+ 					nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
+-#elif !defined(MSG_NOSIGNAL)
+-				nput = WRITESOCKET(tds->s, p, remaining);
+ #else
+-				nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
++				nput = WRITESOCKET(tds->s, p, remaining);
+ #endif
+ 				if (nput < 0 && sock_errno == EAGAIN)
+ 					continue;
+
+commit 998e0c0a7e8a6305acb7a20748dba6fe9c212081
+Author: jklowden <jklowden>
+Date:   Thu Jan 10 22:57:39 2008 +0000
+
+    updated documentation
+
+diff --git a/INSTALL.CVS b/INSTALL.CVS
+index d42c3aa..53d62d6 100644
+--- a/INSTALL.CVS
++++ b/INSTALL.CVS
+@@ -16,9 +16,9 @@ connecting to the CVS server.  Then follow these steps:
+ 	
+ 	Autotool versions that work:
+ 	$ (autoconf --version; automake --version; libtool --version) |grep GNU
+-	autoconf (GNU Autoconf) 2.59
+-	automake (GNU automake) 1.9.5
+-	ltmain.sh (GNU libtool) 1.5.14 (1.1220.2.195 2005/02/12 12:12:33)
++	autoconf (GNU Autoconf) 2.60
++	automake (GNU automake) 1.9.6
++	ltmain.sh (GNU libtool) 1.5.18 (1.1220.2.245 2005/05/16 08:55:27)
+ 	
+ 	The above are used to generate the distributions.  
+ 	You may get away with older versions, as far back as 2.53 for autoconf.
+@@ -44,10 +44,10 @@ connecting to the CVS server.  Then follow these steps:
+ 	
+ +++
+ 
+-You are not required to rely on Source Forge's anonymous CVS server, which at
++You are not required to rely on SourceForge's anonymous CVS server, which at
+ the present time (July 2004) runs up to 1 hour behind the development server. 
+ You can fetch the CVS tarball (the basis for a CVS server, not a snapshot) from
+-Source Forge at:
++SourceForge at:
+ 
+ http://cvs.sourceforge.net/cvstarballs/freetds-cvsroot.tar.bz2
+ 
+@@ -62,4 +62,4 @@ the CVS tree via rsync:
+ $ rsync -av rsync://freetds.cvs.sourceforge.net/cvsroot/freetds/* .
+ 	
+ --
+-$Id: INSTALL.CVS,v 1.7 2007/04/05 14:17:05 freddy77 Exp $
++$Id: INSTALL.CVS,v 1.8 2008/01/10 22:57:39 jklowden Exp $
+diff --git a/NEWS b/NEWS
+index 851fbce..bc2fdf3 100644
+--- a/NEWS
++++ b/NEWS
+@@ -1,33 +1,63 @@
+-$Id: NEWS,v 1.43 2008/01/08 13:29:40 freddy77 Exp $
+-* 0.82
+-- support NUL characters inside terminators in freebcp
+-- cursors under ODBC (mssql)
++$Id: NEWS,v 1.44 2008/01/10 22:57:39 jklowden Exp $
++
++Executive Summary of Changes in release 0.82
++--------------------------------------------
++
++1.  timeout handling
++2.  encrypted connections
++3.  fisql (and odbc utilities)
++4.  autoconf improvements
++5.  23,710 lines added or deleted (101,022 total).
++6.  85 files added
++7.  21 unit tests added
++
++Details
++-------
++
++db-lib
++- timeouts work! 
++- corrected dbnextrow 
++- implemented dbsetnull and dbsetinterrupt
++- improved error reporting and checking
++- fixed rpc parameter processing, now php works correctly
++
++ct-lib
++- added cs_loc_alloc, cs_loc_drop, cs_locale implementations
++
++odbc
++- cursors (mssql)
++- fixed database setting 
++- return error always if odbc returns SQL_ERROR
++- fixed SQLGetData result
++
++utilities
++- added support for NUL characters inside terminators in freebcp
++- added row termination and column termination option to tsql
++- new fisql application
++- new ODBC utilities
++
++documentation
++- significant updates to TDS protocol documentation
++- freetds.conf man page
++- added tenderfoot sample code
++
++general
++- fixed timeout handling
++- added freetds.conf option for encryption
++- added protocol version discovery
+ - NTLM2 session response
+-- lot of update to TDS protocol documentation
++- read table and real column name from wire
++- experimental Kerberos support using gssapi
+ - some optimizations for GCC4
+ - optimized conversions avoiding some memory copy
+ - minor improves to server stuff
+-- add row termination and column termination option to tsql
+-- improve locale stuff on ctlib
+-  added cs_loc_alloc, cs_loc_drop, cs_locale implementations
+-- improve MingW compile (even cross one)
+-- implement dbsetnull on dblib
+-- improve dblib error reporting and check
++- improved MingW compile (even cross one)
+ - more verbose log for dblib and odbc
+-- fix rpc parameter on dblib, now php works correctly
+ - many test added
+   1 test for libTDS
+   1 test for ctlib
+   3 tests for dblib
+   13 tests for odbc
+-- fix database setting on odbc
+-- fix timeout stuff
+-- return always an error if odbc return SQL_ERROR
+-- fix SQLGetData result
+-- add freetds.conf option for encryption
+-- add protocol version discovery
+-- read table and real column name from wire
+-- experimental Kerberos support using gssapi
+ 
+ libTDS API changes
+ - tds_add_row_column_size removed
+@@ -38,7 +68,7 @@ libTDS API changes
+ - added TDSCURSOR->type and TDSCURSOR->concurrency for mssql support
+ - added fetch_type and i_row parameters to tds_cursor_fetch
+ - added tds_cursor_update and tds_cursor_setname functions
+-- make tds_alloc_get_string static
++- made tds_alloc_get_string static
+ - removed tds_free_cursor
+ - added TDSCURSOR->ref_count
+ - added tds_cursor_deallocated and tds_release_cursor to handle
+@@ -48,8 +78,8 @@ libTDS API changes
+   to trace pointer owner between libTDS and upper libraries
+ - added TDS_COMPILETIME_SETTINGS->sysconfdir
+ - changed DSTR_STRUCT structure to include dstr_size
+-- change DSTR type
+-- error handler cannot return TDS_INT_EXIT (no more defined)
++- changed DSTR type
++- error handler cannot return TDS_INT_EXIT
+ - removed TDSSOCKET->query_timeout_func TDSSOCKET->query_timeout_param,
+   TDSSOCKET->query_start_time
+ - changed TDSLOGIN->host_name to client_host_name
+@@ -83,7 +113,6 @@ libTDS API changes
+ - added TDSSOCKET->tds9_transaction (used internally for TDS9)
+ - added TDSCONNECTION->server_host_name needed for Kerberos support
+ 
+-
+ * 0.64
+ - core library
+  - reduced network bandwidth use on Linux and *BSD
+diff --git a/TODO b/TODO
+index 49074e8..55b0fbf 100644
+--- a/TODO
++++ b/TODO
+@@ -4,11 +4,11 @@ followed by things that should work before the next release,
+ followed by features that should be added/fixed/reworked (grouped by library).  
+ 
+ Everyone is encouraged to add to the list.  Developers can do it directly; 
+-anyone else can post a patch to Source Forge.  
++anyone else can post a patch to SourceForge.  
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.166 2008/01/10 08:47:37 freddy77 Exp $
++To Do List	$Id: TODO,v 1.167 2008/01/10 22:57:39 jklowden Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -30,20 +30,13 @@ Broken:
+ 
+ Work in progress:
+ 
+-Postponed to 0.65 version
+ . log and call error handler on problems with tds_iconv_init().
+ . iconv
+   - support string conversions for Sybase
+-  - add test for locale_charset() to configure.in.  Use it if available
+-    instead of nl_langinfo, because it implies we're using GNU iconv
+ . add doc/htdoc/Makefile with "publish" target to commit cvs and update
+   freetds.org
+ . drop txt2man from cvs, skip building man pages without it. 
+ . be able to disable iconv for BCP (see Sybase documentation)
+-. userguide
+-  - update table of working configurations
+-    server (vendor, version, platform) - client (freetds version, platform) 
+-    - protocol - charsets - date
+ 
+ For future versions (in priority order within library):
+   All:
+@@ -59,7 +52,6 @@ For future versions (in priority order within library):
+ . Add missing constants needed for python and verify working
+ . Add missing constants needed for Gnome-DB and verify working 
+ . conversion from ucs2 to utf8, provide for 2+ bytes/character
+-. tdsping program for testing purposes
+ . Finish off the TDS dissector for ethereal
+ . more solid. handle out of memory conditions (started, we must test all 
+   allocation and all function that return allocated data and be able to 
+@@ -81,8 +73,8 @@ For future versions (in priority order within library):
+   (too complicate, see ctlib bulk, cf "bulk copy and row buffer")
+ . improve cursor support on dblib and ctlib
+ . support for VARIANT type (requested one time, 2003-8-1)
+-. support for NT named pipe (requested many time ago for mssql6.5 server, only
+-  for completeness). If anybody knows a library to handle named pipes
++. support for NT named pipe (requested long ago for mssql6.5 server, only
++  for completeness). If the reader knows a library to handle named pipes
+   compatible with LGPL please tell us.
+ . read on partial packet, do not wait entire one
+ . detect if realloc/free accepts NULL pointers (in configure.in)
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index d26bb2e..e8d4c79 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/01/08 13:29:40 $</date>
+-		<releaseinfo>$Revision: 1.110 $</releaseinfo>
++		<date>$Date: 2008/01/10 22:57:39 $</date>
++		<releaseinfo>$Revision: 1.111 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -26,6 +26,7 @@
+ 		  <year>2005</year>
+ 		  <year>2006</year>
+ 		  <year>2007</year>
++		  <year>2008</year>
+ 		  <holder>Brian Bruns and James K. Lowden</holder>
+ 		</copyright>
+ 		<legalnotice><para>
+@@ -55,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.110 $</>
+-<member>$Date: 2008/01/08 13:29:40 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.110 2008/01/08 13:29:40 freddy77 Exp $.</>
++<member>$Revision: 1.111 $</>
++<member>$Date: 2008/01/10 22:57:39 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.111 2008/01/10 22:57:39 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -201,7 +202,7 @@ project on SourceForge.  It is a fork of the
+ 		<sect2 id="Status">
+ 			<title>Status</title>
+ 			<para>
+-The <systemitem class="library">db-lib</systemitem> and <systemitem class="library">ct-lib</systemitem> <acronym>API</>s have been usable for several years.  They have been successfully  substituted for Sybase's own libraries in a variety of venues, including <productname>Perl</productname> and <productname>PHP</productname>.  That is not to say that these drivers are complete; they're not.  But they faithfully implement an important subset of their <acronym>API</>s, enough to be useful.  This 0.64 version boasts support for server-side cursors in <systemitem class="library">ct-lib</systemitem>.  
++The <systemitem class="library">db-lib</systemitem> and <systemitem class="library">ct-lib</systemitem> <acronym>API</>s have been usable for several years.  They have been successfully  substituted for Sybase's own libraries in a variety of venues, including <productname>Perl</productname> and <productname>PHP</productname>.  That is not to say that these drivers are complete; they're not.  But they faithfully implement a useful &mdash; and widely used &mdash; subset of their <acronym>API</>s.  
+ 			</para>
+ 			<para>
+ In addition to the core <systemitem class="library">db-lib</systemitem> <acronym>API</>, <productname>FreeTDS</productname>  includes a full implementation of <systemitem class="library">db-lib</systemitem>'s <acronym>bcp</> functions, as well as <command>freebcp</>, a replacement for Sybase's <application>bcp</application> utility.  
+@@ -567,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/01/08 13:29:40 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/01/10 22:57:39 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -941,8 +942,7 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ 	<entry>instance</entry>
+ 	<entry>instance name</entry>
+ 	<entry>none</entry>
+-	<entry><para>Name of Microsoft SQL Server <emphasis>instance</> to connect to. The port will be detected automatically.
+-		<note><para>This requires an extra round-trip with server and may thus slightly delay making the connection.</para></note></para></entry>
++	<entry><para>Name of Microsoft SQL Server <emphasis>instance</> to connect to. The port will be detected automatically.</para></entry>
+ 	</row>
+ 	<row>
+ 	<entry>debug flags</entry>
+@@ -1512,7 +1512,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<entry><literal>Server</></entry>
+ 	<entry>A server name or (ip) address</entry>
+ 	<entry>none</entry>
+-	<entry>Hostname of a server. Used in an ODBC-only configuration. As of version 0.64 you can specify a Microsoft SQL Server instance in the form of <literal>server\instance</literal>.  </entry>
++	<entry>Hostname of a server. Used in an ODBC-only configuration. To specify a Microsoft SQL Server instance, use the form <literal>server\instance</literal>.  </entry>
+ 	</row>
+ 	<row>
+ 	<entry><literal>Port</></entry>
+
+commit 296c62697062c312476ce658ef7e22913008a877
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 08:30:09 2008 +0000
+
+    merged notes
+
+diff --git a/ChangeLog b/ChangeLog
+index f508d56..d8678f2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 11  9:29:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* README: merged
++
+ Thu Jan 10 17:55:41 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds_sysdep_private.h src/tds/net.c
+ 	- moved some preprocessor logic to the header file
+@@ -35,4 +38,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2463 2008/01/10 22:57:33 jklowden Exp $
++$Id: ChangeLog,v 1.2464 2008/01/11 08:30:09 freddy77 Exp $
+diff --git a/README b/README
+index 33da879..d7509e6 100644
+--- a/README
++++ b/README
+@@ -1,12 +1,11 @@
+-$Id: README,v 1.11 2007/04/05 14:17:05 freddy77 Exp $
+-README for FreeTDS 0.64
+-Saturday 1 July 2006
++README for FreeTDS 0.82
++Thusday 10 January 2008
+ 
+-* to build FreeTDS read the file INSTALL,
+-* see also the FreeTDS Users Guide,
++* to build FreeTDS read the file INSTALL or
++  the FreeTDS Users Guide (doc/userguide.tgz) and 
+   http://www.freetds.org/userguide/
+ 
+-FreeTDS is a free (open source) implementation of Sybase's db-lib,
++FreeTDS is a free implementation of Sybase's db-lib,
+ ct-lib, and ODBC libraries. FreeTDS builds and runs on every flavor of
+ unix-like systems we've heard of, as well as Win32 (with or without
+ Cygwin), VMS, and Mac OS X.  Failure to build on your system is probably
+@@ -27,60 +26,8 @@ TODO		The roadmap, such as it is
+ 
+ Also, doc/api_status.txt shows which functions are implemented.  
+ 
+-************************************
+-** Warning regarding Sybase 12.5! **
+-************************************
+-
+-Do Not Use TDS version 4.2 to connect to Sybase 12.5. Please!  
+-
+-While we don't like to put the bad news first, neither do we want you to
+-hurt your server.  We know that our implementation of TDS 4.2 gives
+-Sybase 12.5 a bad case of heartburn.  In short: it crashes the server.  
+-
+-We don't know what it is about our version of TDS 4.2 that Sybase 12.5
+-doesn't like, and we'd like to figure it out eventually.  But in the
+-meanwhile, until we can find the problem and fix it, please don't use
+-that combination.  Unless you want to help us test it, that is.  
+-
+-FreeTDS 0.63 works fine with Sybase 12.5 if you use TDS version 5.0.  
+-
+-If you are using Sybase 12.5 and anything above is not clear to you,
+-please see the User Guide.  If it is still not clear after that, please
+-write to the FreeTDS mailing list.  We'd rather answer your questions
+-while your server is still running.  
+-
+-Thank you.  We return now to your regularly scheduled README, already in
+-progress. 
+-
+-New in this version
+-===================
+-
+-ct-lib
+-------
+-
+-Ct-lib now sports bcp and cursors.  The largest missing feature is now
+-placeholder support compatible with Perl's DBD::Sybase.  
+-
+-ODBC
+-----
+-
+-ODBC continues to be improved.  It is now compatible with OpenOffice.org, for
+-example, and even works with Oracle's OTL libary.  It has better 64-bit
+-support.  
+-
+-Applications
+-------------
+-
+-This version includes two new applications, bsqldb and defncopy.  See their man
+-pages for details.  
+-
+-etc.
+-----
+-
+-Naturally, there have been other improvements as well.  This version compiles
+-and runs better than its predecessors.  
+-
+-
++For details on what's new in this version, see NEWS.  For unbearable 
++detail, see ChangeLog-0.82.
+ 
+ Documentation
+ =============
+@@ -139,3 +86,6 @@ Side note: Brian, as many free software authors, appreciates postcards
+ from all over. So if you live someplace neat (read: not Michigan) and
+ want to send one, email him (brian@bruns.org) for his current snail mail
+ address.
++
++$Id: README,v 1.12 2008/01/11 08:30:10 freddy77 Exp $
++
+
+commit 239ad2280de52827b19c5d05e923165bcc8e6ddb
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 09:44:26 2008 +0000
+
+    make test work with Sybase, add test for poll
+
+diff --git a/ChangeLog b/ChangeLog
+index d8678f2..3f540fa 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jan 11 10:42:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: make it work with Sybase
++	* configure.ac: test for poll function
++
+ Fri Jan 11  9:29:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* README: merged
+ 
+@@ -38,4 +42,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2464 2008/01/11 08:30:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2465 2008/01/11 09:44:26 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 96ec6c5..6d0bff4 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.30 2008/01/09 06:51:45 freddy77 Exp $
++dnl $Id: configure.ac,v 1.31 2008/01/11 09:44:26 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.30 $)
++AC_REVISION($Revision: 1.31 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -200,7 +200,8 @@ AC_CHECK_MEMBERS([struct tm.__tm_zone],,,[#include <sys/types.h>
+ #include <$ac_cv_struct_tm>
+ ])
+ AC_CHECK_HEADERS([unistd.h errno.h wchar.h sys/time.h sys/types.h \
+-sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h signal.h libgen.h])
++sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h \
++signal.h libgen.h poll.h])
+ if test $tds_mingw = no; then
+ 	AC_CHECK_HEADERS([sys/socket.h arpa/inet.h netdb.h netinet/in.h \
+ netinet/tcp.h paths.h sys/ioctl.h langinfo.h])
+@@ -367,7 +368,7 @@ gethrtime localtime_r])
+ OLD_LIBS="$LIBS"
+ LIBS="$LIBS $NETWORK_LIBS"
+ AC_CHECK_FUNCS([inet_ntoa_r getipnodebyaddr getipnodebyname \
+-getaddrinfo getnameinfo inet_ntop gethostname])
++getaddrinfo getnameinfo inet_ntop gethostname poll])
+ LIBS="$OLD_LIBS"
+ AC_REPLACE_FUNCS([asprintf vasprintf atoll strtok_r readpassphrase \
+ strlcpy strlcat basename])
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 9e4be47..6b7b99c 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.2 2008/01/10 15:29:03 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.3 2008/01/11 09:44:26 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -167,7 +167,7 @@ main(int argc, char **argv)
+ 
+ 	}
+ 
+-	/* No fetch rows ... */
++	/* Now fetch rows ... */
+ 
+ 	for (i = 0; i < cnt; i++) {
+ 
+@@ -175,10 +175,12 @@ main(int argc, char **argv)
+ 		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ 		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+ 
+-		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-		rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++		if (db_is_microsoft()) {
++			rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
++			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
++			rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
++			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++		}
+ 
+ 		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+
+commit 1c7684ceba4779e1eb04c13197bcd9ece2a3cb47
+Author: freddy77 <freddy77>
+Date:   Fri Jan 11 12:43:39 2008 +0000
+
+    fix compile for MacOSX
+
+diff --git a/ChangeLog b/ChangeLog
+index 3f540fa..120eda3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jan 11 13:42:06 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/apps/tsql.c:
++	- fix compile problem for MacOSX
++
+ Fri Jan 11 10:42:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: make it work with Sybase
+ 	* configure.ac: test for poll function
+@@ -42,4 +46,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2465 2008/01/11 09:44:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2466 2008/01/11 12:43:39 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 6d0bff4..4a0f729 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.31 2008/01/11 09:44:26 freddy77 Exp $
++dnl $Id: configure.ac,v 1.32 2008/01/11 12:43:39 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.31 $)
++AC_REVISION($Revision: 1.32 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -178,7 +178,24 @@ if test $tds_mingw = no; then
+ 	AC_CHECK_LIB([readline], [readline], [LIBS="$LIBS -lreadline"
+ 	  AC_DEFINE(HAVE_READLINE, 1, [Define to 1 if you have the GNU Readline library.])], [LIBS=""] )
+ 	AC_CHECK_FUNCS([rl_on_new_line rl_reset_line_state])
++	AC_LINK_IFELSE([AC_LANG_SOURCE([[
+ 
++#include <stdio.h>
++#ifdef HAVE_STDLIB_H
++#include <stdlib.h>
++#endif
++
++#ifdef HAVE_READLINE
++#include <readline/readline.h>
++#include <readline/history.h>
++#endif /* HAVE_READLINE */
++
++int main()
++{
++	rl_inhibit_completion = 1;
++	return 0;
++}
++]])],AC_DEFINE(HAVE_RL_INHIBIT_COMPLETION, 1, [Define to 1 if you have rl_inhibit_completion.]))
+ 	READLINE_LIBS="$LIBS"
+ 	LIBS="$OLDLIBS"
+ 	AC_SUBST(READLINE_LIBS)
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 6a04027..17268ef 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.112 2007/12/23 21:12:02 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.113 2008/01/11 12:43:39 freddy77 Exp $");
+ 
+ enum
+ {
+@@ -683,7 +683,7 @@ main(int argc, char **argv)
+ 	mybuf[0] = '\0';
+ 	buflen = 0;
+ 
+-#ifdef HAVE_READLINE
++#if defined(HAVE_READLINE) && HAVE_RL_INHIBIT_COMPLETION
+ 	rl_inhibit_completion = 1;
+ #endif
+ 
+
+commit 3ee05c86c5e0af66287ccd0d67dfc3aa5de0755d
+Author: freddy77 <freddy77>
+Date:   Sat Jan 12 00:14:11 2008 +0000
+
+    fix for heavy load on server
+
+diff --git a/ChangeLog b/ChangeLog
+index 120eda3..bd33ef6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jan 12  1:13:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: small fix for 64bit
++	* src/tds/net.c: fix for heavy loads
++
+ Fri Jan 11 13:42:06 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/apps/tsql.c:
+ 	- fix compile problem for MacOSX
+@@ -46,4 +50,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2466 2008/01/11 12:43:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2467 2008/01/12 00:14:11 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 6b7b99c..379930d 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.3 2008/01/11 09:44:26 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.4 2008/01/12 00:14:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -101,11 +101,11 @@ main(int argc, char **argv)
+ 	int i;
+ 
+ 	int key;
+-	SQLINTEGER vind0;
++	SQLLEN vind0;
+ 	char buf1[NBYTES];
+-	SQLINTEGER vind1;
++	SQLLEN vind1;
+ 	char buf2[NBYTES];
+-	SQLINTEGER vind2;
++	SQLLEN vind2;
+ 	int cnt = 2;
+ 
+ 	use_odbc_version3 = 1;
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 741f9b4..196af9b 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -82,6 +82,10 @@
+ #include <sys/select.h>
+ #endif /* HAVE_SELECT_H */
+ 
++#if HAVE_POLL_H
++#include <poll.h>
++#endif /* HAVE_POLL_H */
++
+ #include "tds.h"
+ #include "tdsstring.h"
+ #include "replacements.h"
+@@ -99,9 +103,23 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.72 2008/01/10 22:57:33 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.73 2008/01/12 00:14:11 freddy77 Exp $");
++
++#undef USE_POLL
++#if defined(HAVE_POLL_H) && defined(HAVE_POLL)
++# define USE_POLL 1
++# define TDSSELREAD  POLLIN
++# define TDSSELWRITE POLLOUT
++/* error is always returned */
++# define TDSSELERR   0
++#else
++# define USE_POLL 0
++# define TDSSELREAD  1
++# define TDSSELWRITE 2
++# define TDSSELERR   4
++#endif
+ 
+-static int tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout_seconds);
++static int tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
+ 
+ 
+ /**
+@@ -237,8 +255,6 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	if (retval == 0) {
+ 		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
+ 	} else {
+-		fd_set fds;
+-
+ 		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", strerror(sock_errno));
+ #if DEBUGGING_CONNECTING_PROBLEM
+ 		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != EINPROGRESS) {
+@@ -258,8 +274,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 		if (sock_errno != TDSSOCK_EINPROGRESS)
+ 			goto not_available;
+ 		
+-		FD_ZERO(&fds);
+-		if (tds_select(tds, NULL, &fds, &fds, timeout) <= 0) {
++		if (tds_select(tds, TDSSELWRITE|TDSSELERR, timeout) <= 0) {
+ 			tds_error = TDSESOCK;
+ 			goto not_available;
+ 		}
+@@ -313,13 +328,39 @@ tds_close_socket(TDSSOCKET * tds)
+  * This function does not call tdserror or close the socket because it can't know the context in which it's being called.   
+  */
+ static int
+-tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, int timeout_seconds)
++tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ {
+ 	int rc, seconds;
+ 	unsigned int poll_seconds;
++#if !USE_POLL
++	fd_set fds[3];
++	fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
++#endif
+ 
+ 	assert(tds != NULL);
+ 	assert(timeout_seconds >= 0);
++
++#if !USE_POLL
++#if !defined(WIN32) && defined(FD_SETSIZE)
++	if (tds->s >= FD_SETSIZE) {
++		sock_errno = EINVAL;
++		return -1;
++	}
++#endif
++	if ((tds_sel & TDSSELREAD) != 0) {
++		FD_ZERO(&fds[0]);
++		readfds = &fds[0];
++	}
++	if ((tds_sel & TDSSELWRITE) != 0) {
++		FD_ZERO(&fds[1]);
++		writefds = &fds[1];
++	}
++	if ((tds_sel & TDSSELERR) != 0) {
++		FD_ZERO(&fds[2]);
++		exceptfds = &fds[2];
++	}
++#endif
++
+ 	/* 
+ 	 * The select loop.  
+ 	 * If an interrupt handler is installed, we iterate once per second, 
+@@ -337,8 +378,17 @@ tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds
+ 	 */
+ 	poll_seconds = (tds->tds_ctx && tds->tds_ctx->int_handler)? 1 : timeout_seconds;
+ 	for (seconds = timeout_seconds; timeout_seconds == 0 || seconds > 0; seconds -= poll_seconds) {
++#if USE_POLL
++		struct pollfd fd;
++		int timeout = poll_seconds ? poll_seconds * 1000 : -1;
++
++		fd.fd = tds->s;
++		fd.events = tds_sel;
++		fd.revents = 0;
++		rc = poll(&fd, 1, timeout);
++#else
+ 		struct timeval tv, *ptv = poll_seconds? &tv : NULL;
+-		
++
+ 		tv.tv_sec = poll_seconds;
+ 		tv.tv_usec = 0; 
+ 
+@@ -350,6 +400,7 @@ tds_select(TDSSOCKET * tds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds
+ 			FD_SET(tds->s, exceptfds);
+ 
+ 		rc = select(tds->s + 1, readfds, writefds, exceptfds, ptv); 
++#endif
+ 
+ 		if (rc > 0 ) {
+ 			return rc;
+@@ -414,7 +465,6 @@ static int
+ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfinished)
+ {
+ 	int rc, got = 0;
+-	fd_set rfds;
+ 
+ 	if (buf == NULL || buflen < 1 || tds == NULL)
+ 		return 0;
+@@ -425,21 +475,17 @@ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfi
+ 		if (IS_TDSDEAD(tds))
+ 			return -1;
+ 
+-		FD_ZERO(&rfds);
+-		if ((len = tds_select(tds, &rfds, NULL, NULL, tds->query_timeout)) > 0) {
+-			len = 0;
+-			if (FD_ISSET(tds->s, &rfds)) {
+-
+-				len = READSOCKET(tds->s, buf + got, buflen);
+-
+-				if (len < 0 && sock_errno == EAGAIN)
+-					continue;
+-				/* detect connection close */
+-				if (len <= 0) {
+-					tdserror(tds->tds_ctx, tds, len == 0 ? TDSESEOF : TDSEREAD, sock_errno);
+-					tds_close_socket(tds);
+-					return -1;
+- 				}
++		if ((len = tds_select(tds, TDSSELREAD, tds->query_timeout)) > 0) {
++
++			len = READSOCKET(tds->s, buf + got, buflen);
++
++			if (len < 0 && sock_errno == EAGAIN)
++				continue;
++			/* detect connection close */
++			if (len <= 0) {
++				tdserror(tds->tds_ctx, tds, len == 0 ? TDSESEOF : TDSEREAD, sock_errno);
++				tds_close_socket(tds);
++				return -1;
+ 			}
+ 		} else if (len < 0) {
+ 			if (sock_errno == EAGAIN) /* shouldn't happen, but OK */
+@@ -631,34 +677,29 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *p, int len, unsigned char la
+ {
+ 	int remaining = len;
+ 	int nput, rc, err=0;
+-	fd_set fds;
+ 
+ 	/* Fix of SIGSEGV when FD_SET() called with negative fd (Sergey A. Cherukhin, 23/09/2005) */
+ 	if (TDS_IS_SOCKET_INVALID(tds->s))
+ 		return -1;
+ 
+ 	while (remaining > 0) {
+-		FD_ZERO(&fds);
+-		if ((rc = tds_select(tds, NULL, &fds, NULL, tds->query_timeout)) > 0) {
+-			nput = 0;
+-			if (FD_ISSET(tds->s, &fds)) {
++		if ((rc = tds_select(tds, TDSSELWRITE, tds->query_timeout)) > 0) {
+ #ifdef USE_MSGMORE
+-				nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
+-				/* In case the kernel does not support MSG_MORE, try again without it */
+-				if (nput < 0 && errno == EINVAL && !last)
+-					nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
++			nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
++			/* In case the kernel does not support MSG_MORE, try again without it */
++			if (nput < 0 && errno == EINVAL && !last)
++				nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
+ #else
+-				nput = WRITESOCKET(tds->s, p, remaining);
++			nput = WRITESOCKET(tds->s, p, remaining);
+ #endif
+-				if (nput < 0 && sock_errno == EAGAIN)
+-					continue;
+-				/* detect connection close */
+-				if (nput <= 0) {
+-					tdserror(tds->tds_ctx, tds, nput == 0 ? TDSESEOF : TDSEWRIT, sock_errno);
+-					tds_close_socket(tds);
+-					return -1;
+- 				}
+-			}
++			if (nput < 0 && sock_errno == EAGAIN)
++				continue;
++			/* detect connection close */
++			if (nput <= 0) {
++				tdserror(tds->tds_ctx, tds, nput == 0 ? TDSESEOF : TDSEWRIT, sock_errno);
++				tds_close_socket(tds);
++				return -1;
++ 			}
+ 		} else if (rc < 0) {
+ 			if (sock_errno == EAGAIN) /* shouldn't happen, but OK, retry */
+ 				continue;
+@@ -770,8 +811,12 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 	int num_try;
+ 	struct sockaddr_in sin;
+ 	ioctl_nonblocking_t ioctl_nonblocking;
++#if USE_POLL
++	struct pollfd fd;
++#else
+ 	struct timeval selecttimeout;
+ 	fd_set fds;
++#endif
+ 	int retval;
+ 	TDS_SYS_SOCKET s;
+ 	char msg[1024];
+@@ -795,6 +840,15 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		return 0;
+ 	}
+ 
++#if !USE_POLL
++#if !defined(WIN32) && defined(FD_SETSIZE)
++	if (s >= FD_SETSIZE) {
++		sock_errno = EINVAL;
++		return 0;
++	}
++#endif
++#endif
++
+ 	/*
+ 	 * on cluster environment is possible that reply packet came from
+ 	 * different IP so do not filter by ip with connect
+@@ -817,12 +871,20 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		tds_strlcpy(msg + 1, instance, sizeof(msg) - 1);
+ 		sendto(s, msg, strlen(msg) + 1, 0, (struct sockaddr *) &sin, sizeof(sin));
+ 
++#if USE_POLL
++		fd.fd = s;
++		fd.events = POLLIN;
++		fd.revents = 0;
++
++		retval = poll(&fd, 1, 1000);
++#else
+ 		FD_ZERO(&fds);
+ 		FD_SET(s, &fds);
+ 		selecttimeout.tv_sec = 1;
+ 		selecttimeout.tv_usec = 0;
+ 		
+ 		retval = select(s + 1, &fds, NULL, NULL, &selecttimeout);
++#endif
+ 		
+ 		/* on interrupt ignore */
+ 		if (retval < 0 && sock_errno == TDSSOCK_EINTR)
+
+commit ff4edf2fa2b3b326b0930093675d0269b90081bb
+Author: freddy77 <freddy77>
+Date:   Sun Jan 13 20:01:43 2008 +0000
+
+    detect cancellation error on ODBC
+
+diff --git a/ChangeLog b/ChangeLog
+index bd33ef6..021efb9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sun Jan 13 20:59:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/cancel.c src/tds/token.c:
++	- detect cancellation and add proper error
++	- remove errors from cancel test
++
+ Sat Jan 12  1:13:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: small fix for 64bit
+ 	* src/tds/net.c: fix for heavy loads
+@@ -50,4 +55,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2467 2008/01/12 00:14:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2468 2008/01/13 20:01:43 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a638dc7..df2cc9a 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.466 2008/01/10 13:11:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.467 2008/01/13 20:01:44 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3260,6 +3260,7 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ 		case TDS_NO_MORE_RESULTS:
+ 			return TDS_CMD_DONE;
+ 		case TDS_CANCELLED:
++			odbc_errs_add(&stmt->errs, "HY008", NULL);
+ 		case TDS_FAIL:
+ 			return TDS_CMD_FAIL;
+ 		}
+@@ -4187,6 +4188,8 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 				continue;
+ 			case TDS_NO_MORE_RESULTS:
+ 				break;
++			case TDS_CANCELLED:
++				odbc_errs_add(&stmt->errs, "HY008", NULL);
+ 			default:
+ 				stmt->errs.lastrc = SQL_ERROR;
+ 				break;
+@@ -5683,6 +5686,9 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 			if (n >= varchar_pos && varchar_pos > 0)
+ 				goto redo;
+ 			break;
++		case TDS_CANCELLED:
++			odbc_errs_add(&stmt->errs, "HY008", NULL);
++			break;
+ 		}
+ 		if (!tds->current_results)
+ 			break;
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 6aa5e3f..a43db5b 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -1,8 +1,15 @@
+ /* Testing SQLCancel() */
+ 
+ #include "common.h"
++
++/* TODO port to windows, use thread */
++
+ #include <signal.h>
+ 
++#if HAVE_UNISTD_H
++#include <unistd.h>
++#endif /* HAVE_UNISTD_H */
++
+ #ifdef HAVE_ALARM
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -15,7 +22,7 @@
+       exit(1); \
+    }
+ 
+-static SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
++static char sqlstate[SQL_SQLSTATE_SIZE + 1];
+ 
+ static void
+ getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+@@ -32,8 +39,9 @@ getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+ 			      (SQLCHAR *) sqlstate,
+ 			      (SQLINTEGER *) & naterror,
+ 			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
++	sqlstate[sizeof(sqlstate)-1] = 0;
+ 	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
++	fprintf(stderr, "  SQL State: %s\n", sqlstate);
+ 	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+ 	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+ }
+@@ -66,10 +74,11 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	printf(">> Select tab1...\n");
++	printf(">> Wait 5 minutes...\n");
+ 	alarm(4);
+ 	signal(SIGALRM, sigalrm_handler);
+ 	rcode = SQLExecDirect(Statement, (SQLCHAR *) "WAITFOR DELAY '000:05:00'", SQL_NTS);
++	alarm(0);
+ 	if (rcode != SQL_ERROR) {
+ 		fprintf(stderr, "SQLExecDirect should return error\n");
+ 		return 1;
+@@ -81,7 +90,10 @@ main(int argc, char **argv)
+ 		return 1;
+ 	}
+ 	printf(">> ...  done rcode = %d\n", rcode);
+-	signal(SIGINT, NULL);
++
++	ResetStatement();
++
++	Command(Statement, "SELECT name FROM sysobjects WHERE 0=1");
+ 
+ 	Disconnect();
+ 	return 0;
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 0c80a00..e6d5a6d 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.343 2007/12/28 23:00:18 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.344 2008/01/13 20:01:45 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2238,7 +2238,7 @@ tds_process_end(TDSSOCKET * tds, int marker, int *flags_parm)
+ 	if (IS_TDSDEAD(tds))
+ 		return TDS_FAIL;
+ 
+-	return TDS_SUCCEED;
++	return was_cancelled ? TDS_CANCELLED : TDS_SUCCEED;
+ }
+ 
+ /**
+
+commit f9912e0d61c0c0f225d8d910c4b506135cc408db
+Author: freddy77 <freddy77>
+Date:   Mon Jan 14 19:21:06 2008 +0000
+
+    finish patch for HY008
+
+diff --git a/ChangeLog b/ChangeLog
+index 021efb9..f318306 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jan 14 20:20:31 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- handle SQLCancel in signal handlers
++
+ Sun Jan 13 20:59:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/cancel.c src/tds/token.c:
+ 	- detect cancellation and add proper error
+@@ -55,4 +59,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2468 2008/01/13 20:01:43 freddy77 Exp $
++$Id: ChangeLog,v 1.2469 2008/01/14 19:21:06 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 59fdfc1..a58d547 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.103 2007/11/26 18:12:30 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.104 2008/01/14 19:21:06 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -370,6 +370,7 @@ struct _hstmt
+ 	int special_row;
+ 	/* do NOT free cursor, free from socket or attach to connection */
+ 	TDSCURSOR *cursor;
++	unsigned char cancel_sent;
+ };
+ 
+ typedef struct _henv TDS_ENV;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index df2cc9a..74f8057 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.467 2008/01/13 20:01:44 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.468 2008/01/14 19:21:06 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -562,6 +562,7 @@ odbc_lock_statement(TDS_STMT* stmt)
+ 		tds->query_timeout = (stmt->attr.query_timeout != DEFAULT_QUERY_TIMEOUT) ?
+ 			stmt->attr.query_timeout : stmt->dbc->default_query_timeout;
+ 	stmt->dbc->current_statement = stmt;
++	stmt->cancel_sent = 0;
+ 	return 1;
+ }
+ 
+@@ -1582,6 +1583,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 
+ 	/* FIXME test current statement */
+ 
++	stmt->cancel_sent = 1;
+ 	if (tds_send_cancel(tds) == TDS_FAIL) {
+ 		ODBC_SAFE_ERROR(stmt);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+@@ -1592,7 +1594,9 @@ SQLCancel(SQLHSTMT hstmt)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	stmt->dbc->current_statement = NULL;
++	/* only if we processed cancel reset statement */
++	if (stmt->dbc->current_statement && stmt->dbc->current_statement == stmt && tds->state == TDS_IDLE)
++		stmt->dbc->current_statement = NULL;
+ 
+ 	ODBC_RETURN_(stmt);
+ }
+@@ -2025,6 +2029,12 @@ odbc_errmsg_handler(const TDSCONTEXT * ctx, TDSSOCKET * tds, TDSMESSAGE * msg)
+ 		tdsdump_log(TDS_DBG_INFO1, "in timeout\n");
+ 		if (tds && (dbc = (TDS_DBC *) tds->parent) && dbc->current_statement) {
+ 			TDS_STMT *stmt = dbc->current_statement;
++			/* cancel sent, handling interrupt */
++			if (tds->in_cancel && stmt ->cancel_sent) {
++				stmt ->cancel_sent = 0;
++				tdsdump_log(TDS_DBG_INFO1, "returning from timeout\n");
++				return TDS_INT_TIMEOUT;
++			}
+ 			if (!tds->in_cancel)
+ 				odbc_errs_add(&stmt->errs, "HYT00", "Timeout expired");
+ 			stmt->errs.lastrc = SQL_ERROR;
+
+commit f5d35b8af351e12aca845f27441c970a27cc45a7
+Author: freddy77 <freddy77>
+Date:   Thu Jan 17 06:56:50 2008 +0000
+
+    do not dump received header
+
+diff --git a/ChangeLog b/ChangeLog
+index f318306..06276f3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 17  7:56:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: do not dump received header
++
+ Mon Jan 14 20:20:31 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/odbc.c:
+ 	- handle SQLCancel in signal handlers
+@@ -59,4 +62,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2469 2008/01/14 19:21:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2470 2008/01/17 06:56:50 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 196af9b..867c8f5 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.73 2008/01/12 00:14:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.74 2008/01/17 06:56:50 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -581,7 +581,6 @@ tds_read_packet(TDSSOCKET * tds)
+ 		}
+ 		return -1;
+ 	}
+-	tdsdump_dump_buf(TDS_DBG_NETWORK, "Received header", header, sizeof(header));
+ 
+ #if 0
+ 	/*
+@@ -606,7 +605,7 @@ tds_read_packet(TDSSOCKET * tds)
+ #endif
+ 
+ 	/* Convert our packet length from network to host byte order */
+-	len = ((((unsigned int) header[2]) << 8) | header[3]) - 8;
++	len = (((unsigned int) header[2]) << 8) | header[3];
+ 
+ 	/*
+ 	 * If this packet size is the largest we have gotten allocate space for it
+@@ -630,9 +629,10 @@ tds_read_packet(TDSSOCKET * tds)
+ 
+ 	/* Clean out the in_buf so we don't use old stuff by mistake */
+ 	memset(tds->in_buf, 0, tds->in_buf_max);
++	memcpy(tds->in_buf, header, 8);
+ 
+ 	/* Now get exactly how many bytes the server told us to get */
+-	have = 0;
++	have = 8;
+ 	while (have < len) {
+ 		int nbytes = goodread(tds, tds->in_buf + have, len - have);
+ 		if (nbytes < 1) {
+@@ -659,7 +659,7 @@ tds_read_packet(TDSSOCKET * tds)
+ 
+ 	/* Set the length and pos (not sure what pos is used for now */
+ 	tds->in_len = have;
+-	tds->in_pos = 0;
++	tds->in_pos = 8;
+ 	tdsdump_dump_buf(TDS_DBG_NETWORK, "Received packet", tds->in_buf, tds->in_len);
+ 
+ 	return (tds->in_len);
+
+commit 510c7865cd8f8a44029d975beaf30a92f4d8a2c0
+Author: freddy77 <freddy77>
+Date:   Thu Jan 17 06:59:28 2008 +0000
+
+    add param for version
+
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index a78d6f4..4ba053d 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -9,7 +9,7 @@ export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:$HOME
+ 
+ GROUPDIR=/home/groups/f/fr/freetds/htdocs
+ # directory to compile
+-FTDSDIR=freetds82
++FTDSDIR=freetds83
+ # output directory on server
+ OUTDIR=out
+ # additional flags for Autogen (current version)
+@@ -66,15 +66,26 @@ read_pwd_fields()
+ 
+ rm ~/freetds.log /tmp/sql.log
+ 
++ignore=
+ for param
+ do
+-	case $param in
++	shift
++	case "$param" in
++	$ignore)
++		ignore=
++		;;
+ 	--previous)
+ 		OUTDIR=out0
+ 		FTDSDIR=freetds64
+ 		FLAGS_ADD="$FLAGS_ADD_OLD"
+ 		WORKDIR=ftds_comp_old
+ 		;;
++	--version)
++		ignore=$1
++		OUTDIR=out$1
++		FTDSDIR=freetds$1
++		WORKDIR=ftds_comp$1
++		;;
+ 	*)
+ 		echo 'Option not supported!' 1>&2
+ 		exit 1
+
+commit 953a096fb706599772e0828dc9c22cf5a9c7a8e0
+Author: jklowden <jklowden>
+Date:   Thu Jan 17 22:45:50 2008 +0000
+
+    announce 0.82RC1
+
+diff --git a/ChangeLog b/ChangeLog
+index 06276f3..9c3fb34 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 17 17:44:43 EST 2008	JK Lowden <jklowden@freetds.org>
++	* doc/htdoc/news.html announce 0.82RC1
++
+ Thu Jan 17  7:56:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: do not dump received header
+ 
+@@ -62,4 +65,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2470 2008/01/17 06:56:50 freddy77 Exp $
++$Id: ChangeLog,v 1.2471 2008/01/17 22:45:50 jklowden Exp $
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index ed0a8a9..c4f8434 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.10 2007/08/09 07:52:08 freddy77 Exp $ -->
++<!-- $Id: news.html,v 1.11 2008/01/17 22:45:50 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -24,11 +24,31 @@ News&nbsp;&nbsp;|&nbsp;
+ <hr size="1" noshade="noshade" />
+ 
+ 
+-<!-- page specific content -->
++<!-- 
++  -- page specific content 
++  -->
+ <p align="center">
+ <font size="+3"><b>N</b></font>ews and <font size="+3"><b>P</b></font>ress
+ </p>
+ <table summary="layout" width="80%" align="center">
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>FreeTDS enters release process for Version 0.82</td></tr>
++<tr>
++<td>
++<br />
++Version 0.82RC1 is now available from 
++<href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/current/freetds-rc.tgz">
++ftp.ibiblio.org</a>.  This important release will incorporate many new features, involving some
++23,710 lines of code.  Detailed information can be found in the NEWS file included in the 
++the distribution.  
++<p>Version 0.82 will be the successor to 0.64, released in July 2006.  The jump in version 
++number represents the progress toward version 1.0.  
++<br />
++<br />
++</td>
++</tr>
++
+ <!--  item  -->
+ <tr bgcolor="#c9c9ff"><td>FreeTDS announces Version 0.63</td></tr>
+ <tr>
+
+commit a8b3aa76401d5ba7c1f858cedb015a7619666d8f
+Author: jklowden <jklowden>
+Date:   Thu Jan 17 22:55:33 2008 +0000
+
+    no comment
+
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index c4f8434..0e26056 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.11 2008/01/17 22:45:50 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.12 2008/01/17 22:55:33 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -25,7 +25,7 @@ News&nbsp;&nbsp;|&nbsp;
+ 
+ 
+ <!-- 
+-  -- page specific content 
++  page specific content 
+   -->
+ <p align="center">
+ <font size="+3"><b>N</b></font>ews and <font size="+3"><b>P</b></font>ress
+
+commit 33c555f4d9ccb9203c80176e2548ba2cb33a4059
+Author: jklowden <jklowden>
+Date:   Thu Jan 17 22:57:27 2008 +0000
+
+    fixed link
+
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index 0e26056..5dbbcee 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.12 2008/01/17 22:55:33 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.13 2008/01/17 22:57:27 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -38,7 +38,7 @@ News&nbsp;&nbsp;|&nbsp;
+ <td>
+ <br />
+ Version 0.82RC1 is now available from 
+-<href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/current/freetds-rc.tgz">
++<a href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/current/freetds-rc.tgz">
+ ftp.ibiblio.org</a>.  This important release will incorporate many new features, involving some
+ 23,710 lines of code.  Detailed information can be found in the NEWS file included in the 
+ the distribution.  
+
+commit 3a6980a9d331be4a918460a4075b616754943ba5
+Author: freddy77 <freddy77>
+Date:   Fri Jan 18 13:37:11 2008 +0000
+
+    merge Sebastien Flaesch patch improving ODBC parameters
+
+diff --git a/ChangeLog b/ChangeLog
+index 9c3fb34..05d433d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Jan 18 14:33:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/connectparams.c src/tds/config.c:
++	- merge Sebastien Flaesch patch for ODBC parameters
++	 - add ClientCharset, DumpFile, DumpFileAppend, DebugFlags, Encryption
++	 - rewrote ODBCINSTGetProperties
++
+ Thu Jan 17 17:44:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/htdoc/news.html announce 0.82RC1
+ 
+@@ -65,4 +71,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2471 2008/01/17 22:45:50 jklowden Exp $
++$Id: ChangeLog,v 1.2472 2008/01/18 13:37:11 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 4a63ca1..1a5eafa 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.284 2007/12/27 13:45:22 freddy77 Exp $ */
++/* $Id: tds.h,v 1.285 2008/01/18 13:37:12 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1387,6 +1387,7 @@ const TDS_COMPILETIME_SETTINGS *tds_get_compiletime_settings(void);
+ typedef void (*TDSCONFPARSE) (const char *option, const char *value, void *param);
+ int tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *parse_param);
+ int tds_read_conf_file(TDSCONNECTION * connection, const char *server);
++void tds_parse_conf_section(const char *option, const char *value, void *param);
+ TDSCONNECTION *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale);
+ void tds_fix_connection(TDSCONNECTION * connection);
+ void tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 7221a67..657062c 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,22 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.72 2007/07/01 10:10:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.73 2008/01/18 13:37:12 freddy77 Exp $");
++
++static const char odbc_param_Servername[] = "Servername";
++static const char odbc_param_Address[] = "Address";
++static const char odbc_param_Server[] = "Server";
++static const char odbc_param_Port[] = "Port";
++static const char odbc_param_TDS_Version[] = "TDS_Version";
++static const char odbc_param_Language[] = "Language";
++static const char odbc_param_Database[] = "Database";
++static const char odbc_param_TextSize[] = "TextSize";
++static const char odbc_param_PacketSize[] = "PacketSize";
++static const char odbc_param_ClientCharset[] = "ClientCharset";
++static const char odbc_param_DumpFile[] = "DumpFile";
++static const char odbc_param_DumpFileAppend[] = "DumpFileAppend";
++static const char odbc_param_DebugFlags[] = "DebugFlags";
++static const char odbc_param_Encryption[] = "Encryption";
+ 
+ #if !HAVE_SQLGETPRIVATEPROFILESTRING
+ 
+@@ -114,6 +129,13 @@ parse_server(char *server, TDSCONNECTION * connection)
+ 	return 1;
+ }
+ 
++static int
++myGetPrivateProfileString(const char *DSN, const char *key, char *buf)
++{
++	buf[0] = '\0';
++	return SQLGetPrivateProfileString(DSN, key, "", buf, FILENAME_MAX, "odbc.ini");
++}
++
+ /** 
+  * Read connection information from given DSN
+  * @param DSN           DSN name
+@@ -128,8 +150,7 @@ odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection)
+ 	int address_specified = 0;
+ 
+ 	/* use old servername */
+-	tmp[0] = '\0';
+-	if (SQLGetPrivateProfileString(DSN, "Servername", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
++	if (myGetPrivateProfileString(DSN, odbc_param_Servername, tmp) > 0) {
+ 		freetds_conf_less = 0;
+ 		tds_dstr_copy(&connection->server_name, tmp);
+ 		tds_read_conf_file(connection, tmp);
+@@ -137,16 +158,13 @@ odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection)
+ 
+ 	/* search for server (compatible with ms one) */
+ 	if (freetds_conf_less) {
+-		tmp[0] = '\0';
+-		if (SQLGetPrivateProfileString(DSN, "Address", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
++		if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
+ 			address_specified = 1;
+ 			/* TODO parse like MS */
+ 			tds_lookup_host(tmp, tmp);
+ 			tds_dstr_copy(&connection->ip_addr, tmp);
+ 		}
+-
+-		tmp[0] = '\0';
+-		if (SQLGetPrivateProfileString(DSN, "Server", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
++		if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
+ 			tds_dstr_copy(&connection->server_name, tmp);
+ 			if (!address_specified) {
+ 				if (!parse_server(tmp, connection))
+@@ -155,35 +173,39 @@ odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection)
+ 		}
+ 	}
+ 
+-	tmp[0] = '\0';
+-	if (SQLGetPrivateProfileString(DSN, "Port", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
+-		connection->port = atoi(tmp);
+-	}
++	if (myGetPrivateProfileString(DSN, odbc_param_Port, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_PORT, tmp, connection);
+ 
+-	tmp[0] = '\0';
+-	if (SQLGetPrivateProfileString(DSN, "TDS_Version", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
+-		tds_config_verstr(tmp, connection);
+-	}
++	if (myGetPrivateProfileString(DSN, odbc_param_TDS_Version, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_VERSION, tmp, connection);
+ 
+-	tmp[0] = '\0';
+-	if (SQLGetPrivateProfileString(DSN, "Language", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
+-		tds_dstr_copy(&connection->language, tmp);
+-	}
++	if (myGetPrivateProfileString(DSN, odbc_param_Language, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_LANGUAGE, tmp, connection);
+ 
+-	tmp[0] = '\0';
+ 	if (tds_dstr_isempty(&connection->database)
+-	    && SQLGetPrivateProfileString(DSN, "Database", "", tmp, FILENAME_MAX, "odbc.ini") > 0)
++	    && myGetPrivateProfileString(DSN, odbc_param_Database, tmp) > 0)
+ 		tds_dstr_copy(&connection->database, tmp);
+ 
+-	tmp[0] = '\0';
+-	if (SQLGetPrivateProfileString(DSN, "TextSize", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
+-		connection->text_size = atoi(tmp);
+-	}
++	if (myGetPrivateProfileString(DSN, odbc_param_TextSize, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_TEXTSZ, tmp, connection);
+ 
+-	tmp[0] = '\0';
+-	if (SQLGetPrivateProfileString(DSN, "PacketSize", "", tmp, FILENAME_MAX, "odbc.ini") > 0) {
+-		connection->block_size = atoi(tmp);
+-	}
++	if (myGetPrivateProfileString(DSN, odbc_param_PacketSize, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_BLKSZ, tmp, connection);
++
++	if (myGetPrivateProfileString(DSN, odbc_param_ClientCharset, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_CLCHARSET, tmp, connection);
++
++	if (myGetPrivateProfileString(DSN, odbc_param_DumpFile, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_DUMPFILE, tmp, connection);
++
++	if (myGetPrivateProfileString(DSN, odbc_param_DumpFileAppend, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_APPENDMODE, tmp, connection);
++
++	if (myGetPrivateProfileString(DSN, odbc_param_DebugFlags, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_DEBUGFLAGS, tmp, connection);
++
++	if (myGetPrivateProfileString(DSN, odbc_param_Encryption, tmp) > 0)
++		tds_parse_conf_section(TDS_STR_ENCRYPTION, tmp, connection);
+ 
+ 	return 1;
+ }
+@@ -279,16 +301,26 @@ odbc_parse_connect_string(const char *connect_string, const char *connect_string
+ 		} else if (strcasecmp(option, "WSID") == 0) {
+ 			dest_s = &connection->client_host_name;
+ 		} else if (strcasecmp(option, "LANGUAGE") == 0) {
+-			dest_s = &connection->language;
+-		} else if (strcasecmp(option, "Port") == 0) {
+-			connection->port = atoi(tds_dstr_cstr(&value));
+-		} else if (strcasecmp(option, "TDS_Version") == 0) {
+-			tds_config_verstr(tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, "TextSize") == 0) {
+-			connection->text_size = atoi(tds_dstr_cstr(&value));
+-		} else if (strcasecmp(option, "PacketSize") == 0) {
+-			connection->block_size = atoi(tds_dstr_cstr(&value));
+-			/* TODO "Address" field */
++			tds_parse_conf_section(TDS_STR_LANGUAGE, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_Port) == 0) {
++			tds_parse_conf_section(TDS_STR_PORT, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_TDS_Version) == 0) {
++			tds_parse_conf_section(TDS_STR_VERSION, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_TextSize) == 0) {
++			tds_parse_conf_section(TDS_STR_TEXTSZ, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_PacketSize) == 0) {
++			tds_parse_conf_section(TDS_STR_BLKSZ, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_ClientCharset) == 0) {
++			tds_parse_conf_section(TDS_STR_CLCHARSET, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_DumpFile) == 0) {
++			tds_parse_conf_section(TDS_STR_DUMPFILE, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_DumpFileAppend) == 0) {
++			tds_parse_conf_section(TDS_STR_APPENDMODE, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_DebugFlags) == 0) {
++			tds_parse_conf_section(TDS_STR_DEBUGFLAGS, tds_dstr_cstr(&value), connection);
++		} else if (strcasecmp(option, odbc_param_Encryption) == 0) {
++			tds_parse_conf_section(TDS_STR_ENCRYPTION, tds_dstr_cstr(&value), connection);
++			/* TODO odbc_param_Address field */
+ 		}
+ 
+ 		/* copy to destination */
+@@ -487,6 +519,19 @@ static const char *const aLanguage[] = {
+ 	NULL
+ };
+ 
++static const char *const aEncryption[] = {
++	TDS_STR_ENCRYPTION_OFF,
++	TDS_STR_ENCRYPTION_REQUEST,
++	TDS_STR_ENCRYPTION_REQUIRE,
++	NULL
++};
++
++static const char *const aBoolean[] = {
++	"Yes",
++	"No",
++	NULL
++};
++
+ /*
+ static const char *aAuth[] = {
+ 	"Server",
+@@ -496,129 +541,132 @@ static const char *aAuth[] = {
+ };
+ */
+ 
+-int
+-ODBCINSTGetProperties(HODBCINSTPROPERTY hLastProperty)
++static HODBCINSTPROPERTY
++addProperty(HODBCINSTPROPERTY hLastProperty)
+ {
+ 	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+ 	hLastProperty = hLastProperty->pNext;
+ 	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "Servername", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("Name of FreeTDS connection to connect to.\n"
+-						 "This server name refer to entry in freetds.conf file, not real server name.\n"
+-						 "This property cannot be used with Server property.");
+-
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "Server", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("Name of server to connect to.\n"
+-						 "This should be the name of real server.\n"
+-						 "This property cannot be used with Servername property.");
++	return hLastProperty;
++}
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
++static HODBCINSTPROPERTY
++definePropertyString(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const char *comment)
++{
++	hLastProperty = addProperty(hLastProperty);
+ 	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "Address", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("The hostname or ip address of the server.");
++	tds_strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
++	tds_strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
++	hLastProperty->pszHelp = (char *) strdup(comment);
++	return hLastProperty;
++}
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "Port", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "1433", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("TCP/IP Port to connect to.");
++static HODBCINSTPROPERTY
++definePropertyBoolean(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const char *comment)
++{
++	hLastProperty = addProperty(hLastProperty);
++	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
++	hLastProperty->aPromptData = malloc(sizeof(aBoolean));
++	memcpy(hLastProperty->aPromptData, aBoolean, sizeof(aBoolean));
++	tds_strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
++	tds_strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
++	hLastProperty->pszHelp = (char *) strdup(comment);
++	return hLastProperty;
++}
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "Database", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("Default database.");
++static HODBCINSTPROPERTY
++definePropertyHidden(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const char *comment)
++{
++	hLastProperty = addProperty(hLastProperty);
++	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_HIDDEN;
++	tds_strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
++	tds_strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
++	hLastProperty->pszHelp = (char *) strdup(comment);
++	return hLastProperty;
++}
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
++static HODBCINSTPROPERTY
++definePropertyList(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, void *list, int size, const char *comment)
++{
++	hLastProperty = addProperty(hLastProperty);
+ 	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
+-	hLastProperty->aPromptData = malloc(sizeof(aTDSver));
+-	memcpy(hLastProperty->aPromptData, aTDSver, sizeof(aTDSver));
+-	tds_strlcpy(hLastProperty->szName, "TDS_Version", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "4.2", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("The TDS protocol version.\n"
+-						 " 4.2 MSSQL 6.5 or Sybase < 10.x\n"
+-						 " 5.0 Sybase >= 10.x\n" " 7.0 MSSQL 7 or MSSQL 2000\n" " 8.0 MSSQL 2000");
++	hLastProperty->aPromptData = malloc(size);
++	memcpy(hLastProperty->aPromptData, list, size);
++	tds_strlcpy(hLastProperty->szName, name, INI_MAX_PROPERTY_NAME);
++	tds_strlcpy(hLastProperty->szValue, value, INI_MAX_PROPERTY_VALUE);
++	hLastProperty->pszHelp = (char *) strdup(comment);
++	return hLastProperty;
++}
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_COMBOBOX;
+-	hLastProperty->aPromptData = malloc(sizeof(aLanguage));
+-	memcpy(hLastProperty->aPromptData, aLanguage, sizeof(aLanguage));
+-	tds_strlcpy(hLastProperty->szName, "Language", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "us_english", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("The default language setting.");
++int
++ODBCINSTGetProperties(HODBCINSTPROPERTY hLastProperty)
++{
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_Servername, "", 
++		"Name of FreeTDS connection to connect to.\n"
++		"This server name refer to entry in freetds.conf file, not real server name.\n"
++		"This property cannot be used with Server property.");
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_HIDDEN;
+-	tds_strlcpy(hLastProperty->szName, "TextSize", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("Text datatype limit.");
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_Server, "", 
++		"Name of server to connect to.\n"
++		"This should be the name of real server.\n"
++		"This property cannot be used with Servername property.");
++
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_Address, "", 
++		"The hostname or ip address of the server.");
++
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_Port, "1433", 
++		"TCP/IP Port to connect to.");
++
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_Database, "", 
++		"Default database.");
++
++	hLastProperty = definePropertyList(hLastProperty, odbc_param_TDS_Version, "4.2", (void*) aTDSver, sizeof(aTDSver),
++		"The TDS protocol version.\n"
++		" 4.2 MSSQL 6.5 or Sybase < 10.x\n"
++		" 5.0 Sybase >= 10.x\n"
++		" 7.0 MSSQL 7 or MSSQL 2000\n"
++		" 8.0 MSSQL 2000");
++
++	hLastProperty = definePropertyList(hLastProperty, odbc_param_Language, "us_english", (void*) aLanguage, sizeof(aLanguage),
++		"The default language setting.");
++
++	hLastProperty = definePropertyHidden(hLastProperty, odbc_param_TextSize, "", 
++		"Text datatype limit.");
+ 
+ 	/* ??? in odbc.ini ??? */
+ /*
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "UID", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("User ID (Beware of security issues).");
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_UID, "", 
++		"User ID (Beware of security issues).");
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "PWD", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("Password (Beware of security issues).");
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_PWD, "", 
++		"Password (Beware of security issues).");
+ */
+ 
+ /*
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
+-	hLastProperty->aPromptData = malloc(sizeof(aAuth));
+-	memcpy(hLastProperty->aPromptData, aAuth, sizeof(aAuth));
+-	tds_strlcpy(hLastProperty->szName, "Authentication", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "Server", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("The server authentication mechanism.");
++	hLastProperty = definePropertyList(hLastProperty, odbc_param_Authentication, "Server", aAuth, sizeof(aAuth),
++		"The server authentication mechanism.");
++
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_Domain, "", 
++		"The default domain to use when using Domain Authentication.");
+ */
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "Domain", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("The default domain to use when using Domain Authentication.");
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_PacketSize, "", 
++		"Size of network packets.");
+ 
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
+-	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+-	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_TEXTEDIT;
+-	tds_strlcpy(hLastProperty->szName, "PacketSize", INI_MAX_PROPERTY_NAME);
+-	tds_strlcpy(hLastProperty->szValue, "", INI_MAX_PROPERTY_VALUE);
+-	hLastProperty->pszHelp = (char *) strdup("Size of network packets.");
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_ClientCharset, "", 
++		"The client character set name to convert application characters to UCS-2 in TDS 7.0 and higher.");
++
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_DumpFile, "",
++		"Specifies the location of a tds dump file and turns on logging.");
++
++	hLastProperty = definePropertyBoolean(hLastProperty, odbc_param_DumpFileAppend, "",
++		"Appends dump file instead of overwriting it. Useful for debugging when many processes are active.");
++
++	hLastProperty = definePropertyString(hLastProperty, odbc_param_DebugFlags, "", 
++		"Sets granularity of logging. A set of bit that specify levels and informations. See table below for bit specification.");
++
++	hLastProperty = definePropertyList(hLastProperty, odbc_param_Encryption, TDS_STR_ENCRYPTION_OFF, aEncryption, sizeof(aEncryption),
++		"The encryption method.");
+ 
+ 	return 1;
+ }
+diff --git a/src/tds/config.c b/src/tds/config.c
+index f88b268..9be062a 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.132 2007/12/23 21:12:02 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.133 2008/01/18 13:37:12 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -84,7 +84,6 @@ static void tds_config_env_tdsver(TDSCONNECTION * connection);
+ static void tds_config_env_tdsport(TDSCONNECTION * connection);
+ static void tds_config_env_tdshost(TDSCONNECTION * connection);
+ static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
+-static void tds_parse_conf_section(const char *option, const char *value, void *param);
+ static void tds_read_interfaces(const char *server, TDSCONNECTION * connection);
+ static int tds_config_boolean(const char *value);
+ static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
+@@ -349,13 +348,27 @@ tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection
+ 	return tds_read_conf_section(in, server, tds_parse_conf_section, connection);
+ }
+ 
++static const struct {
++	char value[7];
++	unsigned char to_return;
++} boolean_values[] = {
++	{ "yes",	1 },
++	{ "no",		0 },
++	{ "on",		1 },
++	{ "off",	0 },
++	{ "true",	1 },
++	{ "false",	0 }
++};
++
+ static int
+ tds_config_boolean(const char *value)
+ {
+-	if (!strcmp(value, "yes") || !strcmp(value, "on") || !strcmp(value, "true") || !strcmp(value, "1"))
+-		return 1;
+-	if (!strcmp(value, "no") || !strcmp(value, "off") || !strcmp(value, "false") || !strcmp(value, "0"))
+-		return 0;
++	int p;
++
++	for (p = 0; p < TDS_VECTOR_SIZE(boolean_values); ++p) {
++		if (!strcasecmp(value, boolean_values[p].value))
++			return boolean_values[p].to_return;
++	}
+ 	tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED boolean value: '%s'. Treating as 'no'.\n", value);
+ 	return 0;
+ }
+@@ -471,7 +484,8 @@ tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_pars
+ #undef option
+ }
+ 
+-static void
++/* Also used to scan ODBC.INI entries */
++void
+ tds_parse_conf_section(const char *option, const char *value, void *param)
+ {
+ 	TDSCONNECTION *connection = (TDSCONNECTION *) param;
+
+commit fbd7bff7112f0353f1bab471cd166369e18ab6a3
+Author: freddy77 <freddy77>
+Date:   Sun Jan 20 14:23:58 2008 +0000
+
+    port to win64
+
+diff --git a/ChangeLog b/ChangeLog
+index 05d433d..468a3bf 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,12 @@
++Sun Jan 20 15:23:16 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds_sysdep_private.h:
++	* include/tds_sysdep_public.h.in src/apps/Makefile.am:
++	* src/ctlib/unittests/cancel.c src/dblib/unittests/timeout.c:
++	* src/odbc/unittests/describecol.c src/replacements/iconv.c:
++	* src/tds/query.c win32/tds_sysdep_public.h win32/winlogin.c:
++	* win32/winsetup.c:
++	- port to win64
++
+ Fri Jan 18 14:33:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/connectparams.c src/tds/config.c:
+ 	- merge Sebastien Flaesch patch for ODBC parameters
+@@ -71,4 +80,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2472 2008/01/18 13:37:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2473 2008/01/20 14:23:58 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 4a0f729..77740fc 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.32 2008/01/11 12:43:39 freddy77 Exp $
++dnl $Id: configure.ac,v 1.33 2008/01/20 14:23:58 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.32 $)
++AC_REVISION($Revision: 1.33 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -142,7 +142,9 @@ tds_mingw=no
+ case $host in
+ *-*-mingw*)
+ 	tds_mingw=yes
+-	if test -r /usr/lib/w32api/libwsock32.a; then
++	if test "$host_cpu" = "x86_64"; then
++		LIBS="-lws2_32"
++	elif test -r /usr/lib/w32api/libwsock32.a; then
+ 		LIBS="-L/usr/lib/w32api -lwsock32"
+ 	else
+ 		LIBS="-lwsock32"
+@@ -381,7 +383,7 @@ TDS_NULL_IS_ZERO
+ AC_CHECK_FUNCS([vsnprintf _vsnprintf gettimeofday \
+ nl_langinfo locale_charset setenv putenv \
+ getuid getpwuid getpwuid_r fstat alarm fork \
+-gethrtime localtime_r])
++gethrtime localtime_r setitimer])
+ OLD_LIBS="$LIBS"
+ LIBS="$LIBS $NETWORK_LIBS"
+ AC_CHECK_FUNCS([inet_ntoa_r getipnodebyaddr getipnodebyname \
+@@ -474,6 +476,7 @@ if test "$with_odbc_nodm"; then
+ 	# Can't use ODBCLIB/LDFLAGS variables since they are used in building
+ 	#  other directories.
+ 	ODBCNODMLIB="-L.. -ltdsodbc"
++	ODBCNODMLIBAPP="-L../odbc -ltdsodbc"
+ 	odbc=true
+ fi
+ 
+@@ -594,6 +597,7 @@ AC_SUBST(ODBC_INC)
+ AC_SUBST(ODBCLIB)
+ AC_SUBST(ODBCINSTLIB)
+ AC_SUBST(ODBCNODMLIB)
++AC_SUBST(ODBCNODMLIBAPP)
+ 
+ AC_ARG_WITH(gnutls,
+ AS_HELP_STRING([--with-gnutls], [build with TLS support]))
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 8adfb9b..bce25a0 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.24 2008/01/10 22:57:33 jklowden Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.25 2008/01/20 14:23:59 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -95,6 +95,10 @@ typedef DWORD pid_t;
+ #define WIN32 1
+ #endif
+ 
++#if defined(_WIN64) && !defined(WIN64)
++#define WIN64 1
++#endif
++
+ #define TDS_SDIR_SEPARATOR "\\"
+ 
+ /* use macros to use new style names */
+diff --git a/include/tds_sysdep_public.h.in b/include/tds_sysdep_public.h.in
+index 4ab78fb..96a782c 100644
+--- a/include/tds_sysdep_public.h.in
++++ b/include/tds_sysdep_public.h.in
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_public_h_
+ #define _tds_sysdep_public_h_
+ 
+-/* $Id: tds_sysdep_public.h.in,v 1.11 2006/04/12 13:54:10 freddy77 Exp $ */
++/* $Id: tds_sysdep_public.h.in,v 1.12 2008/01/20 14:23:59 freddy77 Exp $ */
+ 
+ #ifdef __cplusplus
+ extern "C"
+@@ -37,7 +37,11 @@ extern "C"
+ #define tds_sysdep_int64_type __int64	/* 64-bit int */
+ #define tds_sysdep_real32_type float	/* 32-bit real */
+ #define tds_sysdep_real64_type double	/* 64-bit real */
+-#define tds_sysdep_intptr_type int	/* 32-bit int */
++#if !defined(WIN64) && !defined(_WIN64)
++#define tds_sysdep_intptr_type int      /* 32-bit int */
++#else
++#define tds_sysdep_intptr_type __int64  /* 64-bit int */
++#endif
+ #endif				/* defined(WIN32) || defined(_WIN32) || defined(__WIN32__) */
+ 
+ #ifndef tds_sysdep_int16_type
+diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
+index cfa03ac..6b03ce8 100644
+--- a/src/apps/Makefile.am
++++ b/src/apps/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.25 2008/01/01 23:09:46 freddy77 Exp $
++# $Id: Makefile.am,v 1.26 2008/01/20 14:23:59 freddy77 Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -28,9 +28,8 @@ bsqldb_LDADD	= ../dblib/libsybdb.la \
+ 		  $(NETWORK_LIBS)
+ 
+ if ODBC
+-bsqlodbc_LDADD	= ../odbc/libtdsodbc.la \
+-		  ../replacements/libreplacements.la \
+-		  $(ODBCLIB) $(NETWORK_LIBS)
++bsqlodbc_LDADD	= ../replacements/libreplacements.la \
++		  $(ODBCLIB) $(ODBCNODMLIBAPP) $(NETWORK_LIBS)
+ bsqlodbc_CPPFLAGS	= $(ODBC_INC) $(AM_CPPFLAGS)
+ endif
+ 
+diff --git a/src/ctlib/unittests/cancel.c b/src/ctlib/unittests/cancel.c
+index 09f3a1a..74e4da9 100644
+--- a/src/ctlib/unittests/cancel.c
++++ b/src/ctlib/unittests/cancel.c
+@@ -10,10 +10,10 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cancel.c,v 1.11 2006/06/15 12:17:47 freddy77 Exp $";
++static char software_version[] = "$Id: cancel.c,v 1.12 2008/01/20 14:23:59 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#ifdef HAVE_ALARM
++#if defined(HAVE_ALARM) && defined(HAVE_SETITIMER)
+ 
+ /* protos */
+ int do_fetch(CS_COMMAND * cmd, int *cnt);
+diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c
+index 736f968..7de6013 100644
+--- a/src/dblib/unittests/timeout.c
++++ b/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.3 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.4 2008/01/20 14:23:59 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+@@ -29,7 +29,7 @@ timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char
+ 		return INT_CANCEL;
+ 		
+ 	if (dberr == SYBETIME) {
+-		fprintf(stderr, "%d timeouts received in %ld seconds, ", ++ntimeouts, time(NULL) - start_time);
++		fprintf(stderr, "%d timeouts received in %ld seconds, ", ++ntimeouts, (long int) (time(NULL) - start_time));
+ 		if (ntimeouts > max_timeouts) {
+ 			if (++ncancels > 1) {
+ 				fprintf(stderr, "could not timeout cleanly, breaking connection\n");
+@@ -73,14 +73,14 @@ timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char
+ int 
+ chkintr(DBPROCESS * dbproc)
+ {
+-	printf("in chkintr, %ld seconds elapsed\n", time(NULL) - start_time);
++	printf("in chkintr, %ld seconds elapsed\n", (long int) (time(NULL) - start_time));
+ 	return FALSE;
+ }
+ 
+ int 
+ hndlintr(DBPROCESS * dbproc)
+ {
+-	printf("in hndlintr, %ld seconds elapsed\n", time(NULL) - start_time);
++	printf("in hndlintr, %ld seconds elapsed\n", (long int) (time(NULL) - start_time));
+ 	return INT_CONTINUE;
+ }
+ 
+diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c
+index cd1de67..3739957 100644
+--- a/src/odbc/unittests/describecol.c
++++ b/src/odbc/unittests/describecol.c
+@@ -6,7 +6,7 @@
+  * test what say SQLDescribeCol about precision using some type
+  */
+ 
+-static char software_version[] = "$Id: describecol.c,v 1.13 2007/12/31 10:06:50 freddy77 Exp $";
++static char software_version[] = "$Id: describecol.c,v 1.14 2008/01/20 14:23:59 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -78,6 +78,9 @@ static struct lookup_int sql_types[] = {
+ 	TYPE(SQL_BINARY),
+ 	TYPE(SQL_VARBINARY),
+ 	TYPE(SQL_LONGVARBINARY),
++	TYPE(SQL_DATE),
++	TYPE(SQL_TIME),
++	TYPE(SQL_TIMESTAMP),
+ 	TYPE(SQL_TYPE_DATE),
+ 	TYPE(SQL_TYPE_TIME),
+ 	TYPE(SQL_TYPE_TIMESTAMP),
+@@ -140,7 +143,7 @@ typedef int (*get_attr_t) (ATTR_PARAMS);
+ static int
+ get_attr_ird(ATTR_PARAMS)
+ {
+-	SQLINTEGER i;
++	SQLLEN i;
+ 	SQLRETURN ret;
+ 
+ 	if (attr->type == type_CHARP)
+diff --git a/src/replacements/iconv.c b/src/replacements/iconv.c
+index c709275..80fe192 100644
+--- a/src/replacements/iconv.c
++++ b/src/replacements/iconv.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.15 2006/08/07 19:37:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.16 2008/01/20 14:23:59 freddy77 Exp $");
+ 
+ /**
+  * \addtogroup conv
+@@ -116,7 +116,7 @@ tds_sys_iconv_open (const char* tocode, const char* fromcode)
+ 	case UTF8_ASCII:
+ 	case UCS2LE_UTF8:
+ 	case UTF8_UCS2LE:
+-		return (iconv_t)fromto;
++		return (iconv_t) (TDS_INTPTR) fromto;
+ 		break;
+ 	default:
+ 		break;
+@@ -144,7 +144,7 @@ tds_sys_iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * out
+ 	int local_errno;
+ 
+ #undef CD
+-#define CD ((int)cd)
++#define CD ((int) (TDS_INTPTR) cd)
+ 
+ 	/* iconv defines valid semantics for NULL inputs, but we don't support them. */
+ 	if (!inbuf || !*inbuf || !inbytesleft || !outbuf || !*outbuf || !outbytesleft)
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 8ef57f7..61c266d 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.217 2008/01/05 11:24:40 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.218 2008/01/20 14:23:59 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -1729,7 +1729,7 @@ tds_get_dynid(TDSSOCKET * tds, char **id)
+ 
+ 	inc_num = (inc_num + 1) & 0xffff;
+ 	/* some version of Sybase require length <= 10, so we code id */
+-	n = (unsigned long) tds;
++	n = (unsigned long) (TDS_INTPTR) tds;
+ 	if (!(p = (char *) malloc(16)))
+ 		return TDS_FAIL;
+ 	*id = p;
+diff --git a/win32/tds_sysdep_public.h b/win32/tds_sysdep_public.h
+index 048c409..d86e324 100644
+--- a/win32/tds_sysdep_public.h
++++ b/win32/tds_sysdep_public.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_public_h_
+ #define _tds_sysdep_public_h_
+ 
+-static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.5 2004/02/03 19:28:12 jklowden Exp $";
++static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.6 2008/01/20 14:23:59 freddy77 Exp $";
+ static void *no_unused_tds_sysdep_public_h_warn[] = { rcsid_tds_sysdep_public_h, no_unused_tds_sysdep_public_h_warn };
+ 
+ #ifdef __cplusplus
+@@ -34,12 +34,23 @@ extern "C"
+ #define tds_sysdep_int64_type __int64	/* 64-bit int */
+ #define tds_sysdep_real32_type float	/* 32-bit real */
+ #define tds_sysdep_real64_type double	/* 64-bit real */
++#if !defined(WIN64) && !defined(_WIN64)
+ #define tds_sysdep_intptr_type int	/* 32-bit int */
++#else
++#define tds_sysdep_intptr_type __int64	/* 64-bit int */
++#endif
+ typedef SOCKET TDS_SYS_SOCKET;
+ #ifndef TDS_IS_SOCKET_INVALID
+ #define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
+ #endif
+ 
++#if !defined(MSDBLIB) && !defined(SYBDBLIB)
++#define SYBDBLIB 1
++#endif
++#if defined(MSDBLIB) && defined(SYBDBLIB)
++#error MSDBLIB and SYBDBLIB cannot both be defined
++#endif
++
+ #ifdef __cplusplus
+ }
+ #endif
+diff --git a/win32/winlogin.c b/win32/winlogin.c
+index 4a2c2aa..9e5969d 100644
+--- a/win32/winlogin.c
++++ b/win32/winlogin.c
+@@ -88,6 +88,14 @@ get_desktop_file(const char *file)
+ 	return res;
+ }
+ 
++#ifndef WIN64
++#define GetWindowUserData(wnd)       GetWindowLong((wnd), GWL_USERDATA)
++#define SetWindowUserData(wnd, data) SetWindowLong((wnd), GWL_USERDATA, (data))
++#else
++#define GetWindowUserData(wnd)       GetWindowLongPtr((wnd), GWLP_USERDATA)
++#define SetWindowUserData(wnd, data) SetWindowLongPtr((wnd), GWLP_USERDATA, (data))
++#endif
++
+ /**
+  * Callback function for the DSN Configuration dialog 
+  * \param hDlg identifies the dialog
+@@ -107,7 +115,7 @@ LoginDlgProc(HWND hDlg, UINT message, WPARAM wParam,	/* */
+ 	case WM_INITDIALOG:
+ 		/* lParam points to the TDSCONNECTION */
+ 		connection = (TDSCONNECTION *) lParam;
+-		SetWindowLong(hDlg, GWL_USERDATA, lParam);
++		SetWindowUserData(hDlg, lParam);
+ 
+ 		/* copy info from TDSCONNECTION to the dialog */
+ 		SendDlgItemMessage(hDlg, IDC_LOGINSERVER, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&connection->server_name));
+@@ -122,7 +130,7 @@ LoginDlgProc(HWND hDlg, UINT message, WPARAM wParam,	/* */
+ 
+ 	case WM_COMMAND:
+ 		/* Dialog's user data points to TDSCONNECTION */
+-		connection = (TDSCONNECTION *) GetWindowLong(hDlg, GWL_USERDATA);
++		connection = (TDSCONNECTION *) GetWindowUserData(hDlg);
+ 
+ 		/* The wParam indicates which button was pressed */
+ 		if (LOWORD(wParam) == IDCANCEL) {
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index 20585f0..e33dc76 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -192,6 +192,13 @@ validate(DSNINFO * di)
+ 	return NULL;
+ }
+ 
++#ifndef WIN64
++#define GetWindowUserData(wnd)       GetWindowLong((wnd), GWL_USERDATA)
++#define SetWindowUserData(wnd, data) SetWindowLong((wnd), GWL_USERDATA, (data))
++#else
++#define GetWindowUserData(wnd)       GetWindowLongPtr((wnd), GWLP_USERDATA)
++#define SetWindowUserData(wnd, data) SetWindowLongPtr((wnd), GWLP_USERDATA, (data))
++#endif
+ 
+ /** 
+  * Callback function for the DSN Configuration dialog
+@@ -216,7 +223,7 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 	case WM_INITDIALOG:
+ 		/* lParam points to the DSNINFO */
+ 		di = (DSNINFO *) lParam;
+-		SetWindowLong(hDlg, GWL_USERDATA, lParam);
++		SetWindowUserData(hDlg, lParam);
+ 
+ 		/* Stuff legal protocol names into IDC_PROTOCOL */
+ 		for (i = 0; protocols[i]; i++) {
+@@ -236,7 +243,7 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 
+ 	case WM_COMMAND:
+ 		/* Dialog's user data points to DSNINFO */
+-		di = (DSNINFO *) GetWindowLong(hDlg, GWL_USERDATA);
++		di = (DSNINFO *) GetWindowUserData(hDlg);
+ 
+ 		/* The wParam indicates which button was pressed */
+ 		if (LOWORD(wParam) == IDCANCEL) {
+
+commit efed20c5ed4afafa6f782e90904bf213871b9370
+Author: freddy77 <freddy77>
+Date:   Sun Jan 20 16:36:51 2008 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index 468a3bf..f8be023 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jan 20 17:36:34 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c: remove warning
++
+ Sun Jan 20 15:23:16 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac include/tds_sysdep_private.h:
+ 	* include/tds_sysdep_public.h.in src/apps/Makefile.am:
+@@ -80,4 +83,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2473 2008/01/20 14:23:58 freddy77 Exp $
++$Id: ChangeLog,v 1.2474 2008/01/20 16:36:51 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 657062c..d16e218 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.73 2008/01/18 13:37:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.74 2008/01/20 16:36:51 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -586,7 +586,7 @@ definePropertyHidden(HODBCINSTPROPERTY hLastProperty, const char *name, const ch
+ }
+ 
+ static HODBCINSTPROPERTY
+-definePropertyList(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, void *list, int size, const char *comment)
++definePropertyList(HODBCINSTPROPERTY hLastProperty, const char *name, const char *value, const void *list, int size, const char *comment)
+ {
+ 	hLastProperty = addProperty(hLastProperty);
+ 	hLastProperty->nPromptType = ODBCINST_PROMPTTYPE_LISTBOX;
+
+commit 4f125fbe4a6beb3be0d617634f1de2698cd60be6
+Author: freddy77 <freddy77>
+Date:   Sun Jan 20 20:47:45 2008 +0000
+
+    test for 64bit
+
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+new file mode 100644
+index 0000000..2f81731
+--- /dev/null
++++ b/src/odbc/unittests/test64.c
+@@ -0,0 +1,257 @@
++/* test win64 consistency */
++#include "common.h"
++
++static char software_version[] = "$Id: test64.c,v 1.1 2008/01/20 20:47:45 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++#define CHK(func,params) \
++	if (func params != SQL_SUCCESS) \
++		ODBC_REPORT_ERROR(#func)
++
++/*
++set ipd processed_ptr with
++SQLParamOptions/SQLSetDescField/SQL_ATTR_PARAMS_PROCESSED_PTR
++check always same value IPD->processed_ptr attr 
++*/
++
++static void
++check_ipd_params(void)
++{
++	void *ptr, *ptr2;
++	SQLHDESC desc;
++	SQLINTEGER ind;
++
++	CHK(SQLGetStmtAttr,(Statement, SQL_ATTR_PARAMS_PROCESSED_PTR, &ptr, sizeof(ptr), NULL));
++	
++	/* get IPD */
++	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind));
++
++	CHK(SQLGetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
++
++	if (ptr != ptr2) {
++		fprintf(stderr, "IPD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
++		exit(1);
++	}
++}
++
++static void
++set_ipd_params1(SQLULEN *ptr)
++{
++	CHK(SQLSetStmtAttr,(Statement, SQL_ATTR_PARAMS_PROCESSED_PTR, ptr, 0));
++}
++
++static void
++set_ipd_params2(SQLULEN *ptr)
++{
++	SQLHDESC desc;
++	SQLINTEGER ind;
++
++	/* get IPD */
++	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind));
++
++	CHK(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0));
++}
++
++static void
++set_ipd_params3(SQLULEN *ptr)
++{
++	CHK(SQLParamOptions, (Statement, 2, ptr));
++}
++
++typedef void (*rows_set_t)(SQLULEN*);
++
++static const rows_set_t param_set[] = {
++	set_ipd_params1,
++	set_ipd_params2,
++	set_ipd_params3,
++	NULL
++};
++
++#define MALLOC_N(t, n) (t*) malloc(n*sizeof(t))
++
++static void
++test_params(void)
++{
++#define ARRAY_SIZE 2
++	const rows_set_t *p;
++	SQLULEN len;
++	SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE);
++	SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE);
++	unsigned long int h, l;
++	unsigned int n;
++
++	for (n = 0; n < ARRAY_SIZE; ++n) {
++		ids[n] = n;
++		id_lens[n] = 0;
++	}
++
++	/* test setting just some test pointers */
++	set_ipd_params1(int2ptr(0x01020304));
++	check_ipd_params();
++	set_ipd_params2(int2ptr(0xabcdef12));
++	check_ipd_params();
++	set_ipd_params3(int2ptr(0x87654321));
++	check_ipd_params();
++
++	/* now see results */
++	for (p = param_set; *p != NULL; ++p) {
++		ResetStatement();
++		len = 0xdeadbeef;
++		len <<= 16;
++		len <<= 16;
++		len |= 12345678;
++
++		(*p)(&len);
++		check_ipd_params();
++
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens));
++
++		Command(Statement, "INSERT INTO #tmp1(i) VALUES(?)");
++		SQLMoreResults(Statement);
++		for (n = 0; n < ARRAY_SIZE; ++n)
++			SQLMoreResults(Statement);
++		l = len;
++		len >>= 16;
++		h = len >> 16;
++		if (h != 0 || l != 2) {
++			fprintf(stderr, "Wrong number returned in param rows high %lu low %lu\n", h, l);
++			exit(1);
++		}
++	}
++
++	free(ids);
++	free(id_lens);
++}
++
++/*
++set ird processed_ptr with
++SQLExtendedFetch/SQLSetDescField/SQL_ATTR_ROWS_FETCHED_PTR
++check always same value IRD->processed_ptr attr 
++*/
++
++static void
++check_ird_params(void)
++{
++	void *ptr, *ptr2;
++	SQLHDESC desc;
++	SQLINTEGER ind;
++
++	CHK(SQLGetStmtAttr,(Statement, SQL_ATTR_ROWS_FETCHED_PTR, &ptr, sizeof(ptr), NULL));
++	
++	/* get IRD */
++	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind));
++
++	CHK(SQLGetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
++
++	if (ptr != ptr2) {
++		fprintf(stderr, "IRD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
++		exit(1);
++	}
++}
++
++static void
++set_ird_params1(SQLULEN *ptr)
++{
++	CHK(SQLSetStmtAttr,(Statement, SQL_ATTR_ROWS_FETCHED_PTR, ptr, 0));
++}
++
++static void
++set_ird_params2(SQLULEN *ptr)
++{
++	SQLHDESC desc;
++	SQLINTEGER ind;
++
++	/* get IRD */
++	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind));
++
++	CHK(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0));
++}
++
++static const rows_set_t row_set[] = {
++	set_ird_params1,
++	set_ird_params2,
++	NULL
++};
++
++#define MALLOC_N(t, n) (t*) malloc(n*sizeof(t))
++
++static void
++test_rows(void)
++{
++	const rows_set_t *p;
++	SQLULEN len;
++	SQLUINTEGER *ids = MALLOC_N(SQLUINTEGER,ARRAY_SIZE);
++	SQLLEN *id_lens = MALLOC_N(SQLLEN,ARRAY_SIZE);
++	unsigned long int h, l;
++	unsigned int n;
++
++	for (n = 0; n < ARRAY_SIZE; ++n) {
++		ids[n] = n;
++		id_lens[n] = 0;
++	}
++
++	/* test setting just some test pointers */
++	set_ird_params1(int2ptr(0x01020304));
++	check_ird_params();
++	set_ird_params2(int2ptr(0xabcdef12));
++	check_ird_params();
++
++	/* now see results */
++	for (p = row_set; ; ++p) {
++		ResetStatement();
++		len = 0xdeadbeef;
++		len <<= 16;
++		len <<= 16;
++		len |= 12345678;
++		if (*p)
++			(*p)(&len);
++		check_ird_params();
++
++//		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
++//		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens));
++
++		CHK(SQLBindCol, (Statement, 1, SQL_C_ULONG, ids, 0, id_lens));
++		if (*p) {
++			CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
++
++			Command(Statement, "SELECT DISTINCT i FROM #tmp1");
++			SQLFetch(Statement);
++		} else {
++			CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
++			Command(Statement, "SELECT DISTINCT i FROM #tmp1");
++			CHK(SQLExtendedFetch, (Statement, SQL_FETCH_NEXT, 0, &len, NULL));
++		}
++		SQLMoreResults(Statement);
++
++		l = len;
++		len >>= 16;
++		h = len >> 16;
++		if (h != 0 || l != 2) {
++			fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx)\n", h, h, l, l);
++			exit(1);
++		}
++
++		if (!*p)
++			break;
++	}
++
++	free(ids);
++	free(id_lens);
++}
++
++int
++main()
++{
++	use_odbc_version3 = 1;
++	Connect();
++
++	Command(Statement, "create table #tmp1 (i int)");
++
++	test_params();
++	test_rows();
++
++	Disconnect();
++	return 0;
++}
++
+
+commit 9d07f193e704910aefc7dbd96d6bc0614864d0e3
+Author: freddy77 <freddy77>
+Date:   Sun Jan 20 21:48:00 2008 +0000
+
+    fix ms odbc problem with SQLGetDescField
+
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index 2f81731..dc88ed8 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.1 2008/01/20 20:47:45 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.2 2008/01/20 21:48:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHK(func,params) \
+@@ -22,11 +22,11 @@ check_ipd_params(void)
+ 	SQLINTEGER ind;
+ 
+ 	CHK(SQLGetStmtAttr,(Statement, SQL_ATTR_PARAMS_PROCESSED_PTR, &ptr, sizeof(ptr), NULL));
+-	
++
+ 	/* get IPD */
+ 	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind));
+ 
+-	CHK(SQLGetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
++	CHK(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
+ 
+ 	if (ptr != ptr2) {
+ 		fprintf(stderr, "IPD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
+@@ -138,11 +138,11 @@ check_ird_params(void)
+ 	SQLINTEGER ind;
+ 
+ 	CHK(SQLGetStmtAttr,(Statement, SQL_ATTR_ROWS_FETCHED_PTR, &ptr, sizeof(ptr), NULL));
+-	
++
+ 	/* get IRD */
+ 	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind));
+ 
+-	CHK(SQLGetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
++	CHK(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
+ 
+ 	if (ptr != ptr2) {
+ 		fprintf(stderr, "IRD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
+
+commit 39e3951a5a51fa75a5b79b1f06fcdeb62bc859a2
+Author: freddy77 <freddy77>
+Date:   Mon Jan 21 15:34:32 2008 +0000
+
+    merge fix for date/time from Dann Corbit
+
+diff --git a/ChangeLog b/ChangeLog
+index f8be023..1b49d15 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jan 21 16:33:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c:
++	- merge fix for date/time from Dann Corbit
++
+ Sun Jan 20 17:36:34 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c: remove warning
+ 
+@@ -83,4 +87,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2474 2008/01/20 16:36:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2475 2008/01/21 15:34:32 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index fb38d5b..06a4d07 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.94 2007/06/19 13:31:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.95 2008/01/21 15:34:32 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -562,10 +562,12 @@ odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col)
+ 		size = col->column_prec + 2;
+ 		break;
+ 	case SQL_DATE:
++	case SQL_TYPE_DATE:
+ 		/* FIXME check always yyyy-mm-dd ?? */
+ 		size = 19;
+ 		break;
+ 	case SQL_TIME:
++	case SQL_TYPE_TIME:
+ 		/* FIXME check always hh:mm:ss[.fff] */
+ 		size = 19;
+ 		break;
+
+commit c0a4f6c10da784231e110c95d1d16454d30e09ca
+Author: freddy77 <freddy77>
+Date:   Thu Jan 24 21:02:14 2008 +0000
+
+    add test on type
+
+diff --git a/ChangeLog b/ChangeLog
+index 1b49d15..e88e56c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jan 24 22:01:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/describecol.in:
++	- some additional tests
++
+ Mon Jan 21 16:33:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c:
+ 	- merge fix for date/time from Dann Corbit
+@@ -87,4 +91,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2475 2008/01/21 15:34:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2476 2008/01/24 21:02:14 freddy77 Exp $
+diff --git a/src/odbc/unittests/describecol.in b/src/odbc/unittests/describecol.in
+index 4f1d874..aa6a63a 100644
+--- a/src/odbc/unittests/describecol.in
++++ b/src/odbc/unittests/describecol.in
+@@ -119,6 +119,7 @@ attr SQL_DESC_OCTET_LENGTH 16
+ attr SQL_DESC_PRECISION 3
+ attr SQL_DESC_SCALE 3
+ attr SQL_DESC_DISPLAY_SIZE 23
++attr SQL_DESC_CONCISE_TYPE SQL_TIMESTAMP
+ 
+ select smalldatetime '2006-04-14'
+ attr SQL_COLUMN_LENGTH 16
+@@ -129,6 +130,7 @@ attr SQL_DESC_OCTET_LENGTH 16
+ attr SQL_DESC_PRECISION 0
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 19
++attr SQL_DESC_CONCISE_TYPE SQL_TIMESTAMP
+ 
+ select char(10) 'hi!'
+ attr SQL_COLUMN_LENGTH 10
+@@ -349,6 +351,7 @@ attr SQL_DESC_OCTET_LENGTH 16
+ attr SQL_DESC_PRECISION 3
+ attr SQL_DESC_SCALE 3
+ attr SQL_DESC_DISPLAY_SIZE 23
++attr SQL_DESC_CONCISE_TYPE SQL_TYPE_TIMESTAMP
+ 
+ select smalldatetime '2006-04-14'
+ attr SQL_COLUMN_LENGTH 16
+@@ -359,6 +362,7 @@ attr SQL_DESC_OCTET_LENGTH 16
+ attr SQL_DESC_PRECISION 0
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 19
++attr SQL_DESC_CONCISE_TYPE SQL_TYPE_TIMESTAMP
+ 
+ select char(10) 'hi!'
+ attr SQL_COLUMN_LENGTH 10
+
+commit ede2f0bed2728757f3bef5f664adfaf921fe88b9
+Author: freddy77 <freddy77>
+Date:   Thu Jan 24 21:14:55 2008 +0000
+
+    va_list cleanups
+
+diff --git a/ChangeLog b/ChangeLog
+index e88e56c..fd76f3b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jan 24 22:14:31 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/tds/vstrbuild.c:
++	- va_list cleanups
++
+ Thu Jan 24 22:01:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/describecol.in:
+ 	- some additional tests
+@@ -91,4 +95,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2476 2008/01/24 21:02:14 freddy77 Exp $
++$Id: ChangeLog,v 1.2477 2008/01/24 21:14:55 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 59b3a49..b6950aa 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.320 2008/01/01 23:09:46 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.321 2008/01/24 21:14:55 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -7775,7 +7775,6 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 	DBLIB_ERROR_MESSAGE constructed_message = { 0, EXCONSISTENCY, NULL };
+ 	const DBLIB_ERROR_MESSAGE *msg = &default_message;
+ 	
+-	va_list ap;
+ 	int i, rc = INT_CANCEL;
+ 	char *os_msgtext = strerror(errnum), *rc_name;
+ 
+@@ -7811,17 +7810,16 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 			msg = &dblib_error_messages[i];
+ 			assert(*(pformats - 1) == '\0'); 
+ 			if(*pformats != '\0') {
++				va_list ap;
+ 				int result_len, len = 2 * strlen(ptext);
+ 				char * buffer = calloc(1, len);
+-				long save_errnum = errnum;
+-				errnum = (long) pformats;
++
+ 				if (buffer == NULL)
+ 					break;
+ 				va_start(ap, errnum);
+ 				rc = tds_vstrbuild(buffer, len, &result_len, ptext, TDS_NULLTERM, pformats, TDS_NULLTERM, ap);
+ 				buffer[result_len] = '\0';
+ 				va_end(ap);
+-				errnum = save_errnum;
+ 				if (TDS_FAIL == rc) {
+ 					free(buffer);
+ 					break;
+diff --git a/src/tds/vstrbuild.c b/src/tds/vstrbuild.c
+index ff521d3..af7a519 100644
+--- a/src/tds/vstrbuild.c
++++ b/src/tds/vstrbuild.c
+@@ -35,7 +35,7 @@
+ #include "tds.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: vstrbuild.c,v 1.14 2007/10/16 15:12:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: vstrbuild.c,v 1.15 2008/01/24 21:14:55 freddy77 Exp $");
+ 
+ struct string_linked_list
+ {
+@@ -206,6 +206,5 @@ tds_vstrbuild(char *buffer, int buflen, int *resultlen, char *text, int textlen,
+ 	}
+ 	free(params);
+ 
+-	va_end(ap);
+ 	return rc;
+ }
+
+commit e95d57532bc55c15fe948cda91224ed2a854bbd1
+Author: freddy77 <freddy77>
+Date:   Fri Jan 25 17:35:52 2008 +0000
+
+    fix problems with some linker
+
+diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
+index 6b03ce8..9e5c4d1 100644
+--- a/src/apps/Makefile.am
++++ b/src/apps/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.26 2008/01/20 14:23:59 freddy77 Exp $
++# $Id: Makefile.am,v 1.27 2008/01/25 17:35:52 freddy77 Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -28,8 +28,8 @@ bsqldb_LDADD	= ../dblib/libsybdb.la \
+ 		  $(NETWORK_LIBS)
+ 
+ if ODBC
+-bsqlodbc_LDADD	= ../replacements/libreplacements.la \
+-		  $(ODBCLIB) $(ODBCNODMLIBAPP) $(NETWORK_LIBS)
++bsqlodbc_LDADD	= $(ODBCLIB) $(ODBCNODMLIBAPP) \
++		  ../replacements/libreplacements.la $(NETWORK_LIBS)
+ bsqlodbc_CPPFLAGS	= $(ODBC_INC) $(AM_CPPFLAGS)
+ endif
+ 
+
+commit 78b44066acdd787d1b81bcdab135403efc5ade6f
+Author: freddy77 <freddy77>
+Date:   Sat Jan 26 21:47:26 2008 +0000
+
+    remove warning
+
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index dc88ed8..f29e745 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.2 2008/01/20 21:48:00 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.3 2008/01/26 21:47:26 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHK(func,params) \
+@@ -241,7 +241,7 @@ test_rows(void)
+ }
+ 
+ int
+-main()
++main(void)
+ {
+ 	use_odbc_version3 = 1;
+ 	Connect();
+
+commit 7671d563ca2b7a2ce589d8b5fd1b7c2837e38fd6
+Author: freddy77 <freddy77>
+Date:   Sun Jan 27 10:25:03 2008 +0000
+
+    *** empty log message ***
+
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index ae23946..2aea2d3 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -65,3 +65,4 @@ attributes
+ hidden
+ blob1
+ cancel
++test64
+
+commit 1de1a0984a75a2a6f7e532ebe3e0f584ffc06c28
+Author: freddy77 <freddy77>
+Date:   Sun Jan 27 10:25:39 2008 +0000
+
+    add generated
+
+diff --git a/.cvsignore b/.cvsignore
+index c4ca19c..d6098e5 100644
+--- a/.cvsignore
++++ b/.cvsignore
+@@ -18,3 +18,4 @@ freetds.spec
+ PWD
+ doxyfile
+ test-dist.log
++compile
+
+commit 12190adda9d9522577554554ad07080ba3e9a474
+Author: freddy77 <freddy77>
+Date:   Sun Jan 27 17:36:17 2008 +0000
+
+    implemented SQL_ATTR_CONNECTION_DEAD
+
+diff --git a/ChangeLog b/ChangeLog
+index fd76f3b..1f7e2b8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Jan 27 18:35:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: 
++	- implemented SQL_ATTR_CONNECTION_DEAD
++
+ Thu Jan 24 22:14:31 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c src/tds/vstrbuild.c:
+ 	- va_list cleanups
+@@ -95,4 +99,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2477 2008/01/24 21:14:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2478 2008/01/27 17:36:17 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 74f8057..937a8d7 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.468 2008/01/14 19:21:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.469 2008/01/27 17:36:17 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -2030,8 +2030,8 @@ odbc_errmsg_handler(const TDSCONTEXT * ctx, TDSSOCKET * tds, TDSMESSAGE * msg)
+ 		if (tds && (dbc = (TDS_DBC *) tds->parent) && dbc->current_statement) {
+ 			TDS_STMT *stmt = dbc->current_statement;
+ 			/* cancel sent, handling interrupt */
+-			if (tds->in_cancel && stmt ->cancel_sent) {
+-				stmt ->cancel_sent = 0;
++			if (tds->in_cancel && stmt->cancel_sent) {
++				stmt->cancel_sent = 0;
+ 				tdsdump_log(TDS_DBG_INFO1, "returning from timeout\n");
+ 				return TDS_INT_TIMEOUT;
+ 			}
+@@ -4443,6 +4443,11 @@ _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTE
+ 		*((SQLUINTEGER *) Value) = dbc->attr.autocommit;
+ 		ODBC_RETURN_(dbc);
+ 		break;
++#if defined(SQL_ATTR_CONNECTION_DEAD) && defined(SQL_CD_TRUE)
++		*((SQLUINTEGER *) Value) = IS_TDSDEAD(dbc->tds_socket) ? SQL_CD_TRUE : SQL_CD_FALSE;
++		ODBC_RETURN_(dbc);
++		break;
++#endif
+ 	case SQL_ATTR_CONNECTION_TIMEOUT:
+ 		*((SQLUINTEGER *) Value) = dbc->attr.connection_timeout;
+ 		ODBC_RETURN_(dbc);
+
+commit d9c30d6e29dc23b76eb3341471e6f1f3d87bdab8
+Author: freddy77 <freddy77>
+Date:   Mon Jan 28 13:36:07 2008 +0000
+
+    base test
+
+diff --git a/src/odbc/unittests/base.c b/src/odbc/unittests/base.c
+new file mode 100644
+index 0000000..f4b365f
+--- /dev/null
++++ b/src/odbc/unittests/base.c
+@@ -0,0 +1,19 @@
++#include "common.h"
++
++/* TODO place comment here */
++
++static char software_version[] = "$Id: base.c,v 1.1 2008/01/28 13:36:07 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++int
++main(int argc, char *argv[])
++{
++	/* TODO remove if not neeeded */
++	use_odbc_version3 = 1;
++	Connect();
++
++	/* TODO write your test */
++
++	Disconnect();
++	return 0;
++}
+
+commit de0657f9227f964ce8db4b66bee483dc871df0ff
+Author: freddy77 <freddy77>
+Date:   Tue Jan 29 09:35:24 2008 +0000
+
+    handle errors from convert_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index 1f7e2b8..09c3d0d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jan 29 10:34:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/odbc.c src/odbc/odbc_util.c:
++	* src/odbc/unittests/getdata.c:
++	- handle errors from convert_tds2sql
++
+ Sun Jan 27 18:35:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: 
+ 	- implemented SQL_ATTR_CONNECTION_DEAD
+@@ -99,4 +104,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2478 2008/01/27 17:36:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2479 2008/01/29 09:35:24 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 04e0b8a..f29df5b 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.49 2007/05/25 09:10:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.50 2008/01/29 09:35:24 freddy77 Exp $");
+ 
+ TDS_INT
+ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+@@ -56,7 +56,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 	TIMESTAMP_STRUCT *tssp;
+ 	SQL_NUMERIC_STRUCT *num;
+ 
+-	int ret = TDS_FAIL;
++	int ret = TDS_CONVERT_FAIL;
+ 	int i, cplen;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "convert_tds2sql: src is %d dest = %d\n", srctype, desttype);
+@@ -89,7 +89,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 			} else {
+ 				/* if destlen == 0 we return only length */
+ 				if (destlen != 0)
+-					ret = TDS_FAIL;
++					ret = TDS_CONVERT_FAIL;
+ 			}
+ 			return ret;
+ 		}
+@@ -143,7 +143,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 		} else {
+ 			/* if destlen == 0 we return only length */
+ 			if (destlen != 0)
+-				ret = TDS_FAIL;
++				ret = TDS_CONVERT_FAIL;
+ 		}
+ 		break;
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 937a8d7..b7b8235 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.469 2008/01/27 17:36:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.470 2008/01/29 09:35:25 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3340,6 +3340,28 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ 	}
+ }
+ 
++static void
++odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err)
++{
++	switch (err) {
++	case TDS_CONVERT_NOAVAIL:
++		odbc_errs_add(errs, "HY003", NULL);
++		break;
++	case TDS_CONVERT_SYNTAX:
++		odbc_errs_add(errs, "22018", NULL);
++		break;
++	case TDS_CONVERT_OVERFLOW:
++		odbc_errs_add(errs, "22003", NULL);
++		break;
++	case TDS_CONVERT_FAIL:
++		odbc_errs_add(errs, "07006", NULL);
++		break;
++	case TDS_CONVERT_NOMEM:
++		odbc_errs_add(errs, "HY001", NULL);
++		break;
++	}
++}
++
+ /*
+  * - handle correctly SQLGetData (for forward cursors accept only row_size == 1
+  *   for other types application must use SQLSetPos)
+@@ -3574,6 +3596,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				len = convert_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+ 				if (len < 0) {
++					odbc_convert_err_set(&stmt->errs, len);
+ 					row_status = SQL_ROW_ERROR;
+ 					break;
+ 				}
+@@ -4596,10 +4619,19 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+ 		if (fCType == SQL_C_DEFAULT)
+ 			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++		if (fCType == SQL_ARD_TYPE) {
++			if (icol > stmt->ard->header.sql_desc_count) {
++				odbc_errs_add(&stmt->errs, "07009", NULL);
++				ODBC_RETURN(stmt, SQL_ERROR);
++			}
++			fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++		}
+ 		assert(fCType);
+ 		*pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+-		if (*pcbValue < 0)
++		if (*pcbValue < 0) {
++			odbc_convert_err_set(&stmt->errs, *pcbValue);
+ 			ODBC_RETURN(stmt, SQL_ERROR);
++		}
+ 
+ 		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ 			/* calc how many bytes was readed */
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 06a4d07..b5e5e7c 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.95 2008/01/21 15:34:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.96 2008/01/29 09:35:25 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -140,7 +140,7 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ 
+ 		len = convert_tds2sql(context, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
+ 				      drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
+-		if (TDS_FAIL == len)
++		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+ 		if (drec->sql_desc_indicator_ptr)
+ 			LEN(drec->sql_desc_indicator_ptr) = 0;
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index eead6e0..1752423 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,15 +1,54 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.4 2007/08/07 09:20:32 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.5 2008/01/29 09:35:25 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++static char odbc_err[256];
++static char odbc_sqlstate[6];
++
++static void
++ReadError(void)
++{
++	memset(odbc_err, 0, sizeof(odbc_err));
++	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
++	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
++		printf("SQLGetDiagRec should not fail\n");
++		exit(1);
++	}
++	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
++}
++
++static void
++test_err(const char *data, int c_type, const char *state)
++{
++	char sql[128];
++	SQLRETURN rc;
++	SQLLEN ind;
++	const unsigned int buf_size = 128;
++	char *buf = (char *) malloc(buf_size);
++
++	sprintf(sql, "SELECT '%s'", data);
++	Command(Statement, sql);
++	SQLFetch(Statement);
++	rc = SQLGetData(Statement, 1, c_type, buf, buf_size, &ind);
++	free(buf);
++	if (rc != SQL_ERROR)
++		ODBC_REPORT_ERROR("SQLGetData error expected");
++	ReadError();
++	if (strcmp(odbc_sqlstate, state) != 0) {
++		fprintf(stderr, "Unexpected sql state returned\n");
++		Disconnect();
++		exit(1);
++	}
++	ResetStatement();
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+ 	char buf[16];
+ 	SQLINTEGER int_buf;
+ 	SQLLEN len;
+-	int ms_db = 0;
+ 
+ 	Connect();
+ 
+@@ -90,14 +129,24 @@ main(int argc, char *argv[])
+ 
+ 	ResetStatement();
+ 
+-	ms_db = db_is_microsoft();
+-
+ 	Disconnect();
+ 
+-	if (ms_db) {
+-		use_odbc_version3 = 1;
+-		Connect();
++	use_odbc_version3 = 1;
++	Connect();
+ 
++	/* test error from SQLGetData */
++	/* wrong constant */
++	test_err("prova 123",           SQL_VARCHAR,     "HY003");
++	/* use ARD but no ARD data column */
++	test_err("prova 123",           SQL_ARD_TYPE,    "07009");
++	/* wrong conversion, int */
++	test_err("prova 123",           SQL_C_LONG,      "22018");
++	/* wrong conversion, int */
++	test_err("prova 123",           SQL_C_TIMESTAMP, "22018");
++	/* overflow */
++	test_err("1234567890123456789", SQL_C_LONG,      "22003");
++
++	if (db_is_microsoft()) {
+ 		Command(Statement, "SELECT CONVERT(TEXT,'')");
+ 
+ 		if (SQLFetch(Statement) != SQL_SUCCESS)
+@@ -114,10 +163,10 @@ main(int argc, char *argv[])
+ 
+ 		if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 1, NULL) != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("invalid return from SQLGetData");
+-
+-		Disconnect();
+ 	}
+ 
++	Disconnect();
++
+ 	printf("Done.\n");
+ 	return 0;
+ }
+
+commit 6b2f6d934757cb502817665692b1005b84331037
+Author: freddy77 <freddy77>
+Date:   Tue Jan 29 14:30:48 2008 +0000
+
+    reuse code
+
+diff --git a/ChangeLog b/ChangeLog
+index 09c3d0d..800bfc2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,27 @@
++Tue Jan 29 15:28:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array_out.c src/odbc/unittests/common.c:
++	* src/odbc/unittests/common.h src/odbc/unittests/compute.c:
++	* src/odbc/unittests/connect2.c src/odbc/unittests/const_params.c:
++	* src/odbc/unittests/copydesc.c src/odbc/unittests/cursor1.c:
++	* src/odbc/unittests/cursor2.c src/odbc/unittests/cursor3.c:
++	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
++	* src/odbc/unittests/data.c src/odbc/unittests/date.c:
++	* src/odbc/unittests/error.c src/odbc/unittests/funccall.c:
++	* src/odbc/unittests/genparams.c src/odbc/unittests/getdata.c:
++	* src/odbc/unittests/hidden.c src/odbc/unittests/lang_error.c:
++	* src/odbc/unittests/moreandcount.c src/odbc/unittests/norowset.c:
++	* src/odbc/unittests/params.c src/odbc/unittests/prepare_results.c:
++	* src/odbc/unittests/print.c src/odbc/unittests/putdata.c:
++	* src/odbc/unittests/raiserror.c src/odbc/unittests/rebindpar.c:
++	* src/odbc/unittests/scroll.c src/odbc/unittests/t0001.c:
++	* src/odbc/unittests/t0002.c src/odbc/unittests/t0003.c:
++	* src/odbc/unittests/t0004.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/test64.c src/odbc/unittests/timeout.c:
++	* src/odbc/unittests/timeout2.c src/odbc/unittests/timeout4.c:
++	* src/odbc/unittests/transaction.c src/odbc/unittests/typeinfo.c:
++	* src/odbc/unittests/warning.c:
++	- reuse reuse reuse!
++
+ Tue Jan 29 10:34:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	* src/odbc/unittests/getdata.c:
+@@ -104,4 +128,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2479 2008/01/29 09:35:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2480 2008/01/29 14:30:48 freddy77 Exp $
+diff --git a/src/odbc/unittests/array_out.c b/src/odbc/unittests/array_out.c
+index f99918d..1bbb852 100644
+--- a/src/odbc/unittests/array_out.c
++++ b/src/odbc/unittests/array_out.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array_out.c,v 1.11 2007/11/26 20:03:17 freddy77 Exp $";
++static char software_version[] = "$Id: array_out.c,v 1.12 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -74,9 +74,7 @@ query_test(SQLRETURN expected, const char *expected_status)
+ 	SQLBindCol(Statement, 1, SQL_C_ULONG, &IDS(0), 0, &ID_LENS(0));
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, DESCS(0), desc_len, &DESC_LENS(0));
+ 
+-	ret = SQLExecDirect(Statement, (SQLCHAR *) test_query, SQL_NTS);
+-	if (ret != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Invalid result");
++	CHK(SQLExecDirect, (Statement, (SQLCHAR *) test_query, SQL_NTS));
+ 
+ 	ret = SQLFetch(Statement);
+ 	if (ret != expected)
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 0fde53d..78f58fe 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.42 2007/12/27 10:22:18 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.43 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -251,9 +251,8 @@ Command(HSTMT stmt, const char *command)
+ 	printf("%s\n", command);
+ 	result = SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS);
+ 	if (result != SQL_SUCCESS && result != SQL_NO_DATA) {
+-		printf("Unable to execute statement\n");
++		fprintf(stderr, "Unable to execute statement\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ }
+ 
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 175b164..b74e162 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.21 2007/12/21 10:39:10 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.22 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -56,6 +56,12 @@ void ResetStatement(void);
+ void CheckCursor(void);
+ 
+ #define ODBC_REPORT_ERROR(msg) ReportError(msg, __LINE__, __FILE__)
++
++#define CHK(func,params) \
++	do { if (func params != SQL_SUCCESS) \
++		ODBC_REPORT_ERROR(#func); \
++	} while(0)
++
+ int Connect(void);
+ int Disconnect(void);
+ void Command(HSTMT stmt, const char *command);
+diff --git a/src/odbc/unittests/compute.c b/src/odbc/unittests/compute.c
+index dfa0f58..11c0548 100644
+--- a/src/odbc/unittests/compute.c
++++ b/src/odbc/unittests/compute.c
+@@ -9,7 +9,7 @@
+  * and declared in odbcss.h
+  */
+ 
+-static char software_version[] = "$Id: compute.c,v 1.9 2007/07/03 15:13:55 freddy77 Exp $";
++static char software_version[] = "$Id: compute.c,v 1.10 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char col1[256], col2[256];
+@@ -23,12 +23,9 @@ TestName(SQLSMALLINT index, const char *expected_name)
+ 	char name[128];
+ 	char buf[256];
+ 	SQLSMALLINT len, type;
+-	SQLRETURN rc;
+ 
+ #define NAME_TEST \
+ 	do { \
+-		if (rc != SQL_SUCCESS) \
+-			ODBC_REPORT_ERROR("SQLDescribeCol failed"); \
+ 		if (strcmp(name, expected_name) != 0) \
+ 		{ \
+ 			sprintf(buf, "line %d: wrong name in column %d expected '%s' got '%s'", \
+@@ -38,14 +35,14 @@ TestName(SQLSMALLINT index, const char *expected_name)
+ 	} while(0)
+ 
+ 	/* retrieve with SQLDescribeCol */
+-	rc = SQLDescribeCol(Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL);
++	CHK(SQLDescribeCol, (Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL));
+ 	NAME_TEST;
+ 
+ 	/* retrieve with SQLColAttribute */
+-	rc = SQLColAttribute(Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL);
++	CHK(SQLColAttribute, (Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL));
+ 	if (db_is_microsoft())
+ 		NAME_TEST;
+-	rc = SQLColAttribute(Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL);
++	CHK(SQLColAttribute, (Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL));
+ 	NAME_TEST;
+ }
+ 
+@@ -56,8 +53,7 @@ CheckFetch(const char *c1name, const char *c1, const char *c2)
+ 
+ 	TestName(1, c1name);
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("error fetching");
++	CHK(SQLFetch, (Statement));
+ 
+ 	if (strlen(c1) != ind1 || strcmp(c1, col1) != 0) {
+ 		fprintf(stderr, "%s:%d: Column 1 error '%s' (%d) expected '%s' (%d)\n", __FILE__, main_line, col1, (int) ind1, c1,
+@@ -107,8 +103,7 @@ main(int argc, char *argv[])
+ 	CheckFetch("c", "pluto", "3");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("No more data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	/* why I need to rebind ?? ms bug of feature ?? */
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+@@ -131,8 +126,7 @@ main(int argc, char *argv[])
+ 	CheckFetch("mao", "pippo", "34");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("No more data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+@@ -140,8 +134,7 @@ main(int argc, char *argv[])
+ 	CheckFetch("sum", "46", "##");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("No more data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+@@ -150,8 +143,7 @@ main(int argc, char *argv[])
+ 	CheckFetch("mao", "pluto", "3");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Still data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+@@ -159,8 +151,7 @@ main(int argc, char *argv[])
+ 	CheckFetch("sum", "6", "%");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Still data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+@@ -182,21 +173,17 @@ main(int argc, char *argv[])
+ 	CheckFetch("c", "pippo", "34");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("No more data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	/* here just skip results, before a row */
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Still data ??");
+-
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	CheckFetch("c", "pluto", "2");
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("No more data ??");
++	CHK(SQLMoreResults, (Statement));
+ 
+ 	/* here just skip results, before done */
+ 	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+diff --git a/src/odbc/unittests/connect2.c b/src/odbc/unittests/connect2.c
+index c7f01a9..0f00546 100644
+--- a/src/odbc/unittests/connect2.c
++++ b/src/odbc/unittests/connect2.c
+@@ -5,7 +5,7 @@
+  * either SQLConnect and SQLDriverConnect
+  */
+ 
+-static char software_version[] = "$Id: connect2.c,v 1.4 2007/04/12 07:49:30 freddy77 Exp $";
++static char software_version[] = "$Id: connect2.c,v 1.5 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -35,7 +35,6 @@ normal_connect(void)
+ 	if (!SQL_SUCCEEDED(res)) {
+ 		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ }
+ 
+@@ -50,7 +49,6 @@ driver_connect(const char *conn_str)
+ 	if (!SQL_SUCCEEDED(res)) {
+ 		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ }
+ 
+@@ -66,7 +64,6 @@ check_dbname(const char *dbname)
+ 	if (!SQL_SUCCEEDED(res)) {
+ 		fprintf(stderr, "Unable to get database name to %s\n", dbname);
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	if (strcmp(out, dbname) != 0) {
+@@ -84,7 +81,6 @@ set_dbname(const char *dbname)
+ 	if (!SQL_SUCCEEDED(res)) {
+ 		fprintf(stderr, "Unable to set database name to %s\n", dbname);
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ }
+ 
+diff --git a/src/odbc/unittests/const_params.c b/src/odbc/unittests/const_params.c
+index a9fabfe..a1482e1 100644
+--- a/src/odbc/unittests/const_params.c
++++ b/src/odbc/unittests/const_params.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?,123,'foo')} syntax and run */
+ 
+-static char software_version[] = "$Id: const_params.c,v 1.13 2007/11/26 06:25:11 freddy77 Exp $";
++static char software_version[] = "$Id: const_params.c,v 1.14 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -26,22 +26,17 @@ main(int argc, char *argv[])
+ 		" return 24680\n"
+ 		"end");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind input parameter");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind));
+ 
+-	if (SQLBindParameter(Statement, 2, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind2) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
++	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind2));
+ 
+ 	/* TODO use {ts ...} for date */
+-	if (SQLPrepare(Statement, (SQLCHAR *) "{call const_param(?, 13579, '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS) !=
+-	    SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{call const_param(?, 13579, '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS));
+ 
+ 	input = 13579;
+ 	ind = sizeof(input);
+ 	out1 = output = 0xdeadbeef;
+-	if (SQLExecute(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute statement");
++	CHK(SQLExecute, (Statement));
+ 
+ 	if (out1 != 7654321) {
+ 		fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
+@@ -51,25 +46,17 @@ main(int argc, char *argv[])
+ 	/* just to reset some possible buffers */
+ 	Command(Statement, "DECLARE @i INT");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
+-
+-	if (SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind input parameter");
+-
+-	if (SQLBindParameter(Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind3) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
++	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2));
++	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1,   0, &ind3));
+ 
+ 	/* TODO use {ts ...} for date */
+-	if (SQLPrepare(Statement, (SQLCHAR *) "{?=call const_param(?, , '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS) !=
+-	    SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{?=call const_param(?, , '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS));
+ 
+ 	input = 13579;
+ 	ind2 = sizeof(input);
+ 	out1 = output = 0xdeadbeef;
+-	if (SQLExecute(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute statement");
++	CHK(SQLExecute, (Statement));
+ 
+ 	if (out1 != 7654321) {
+ 		fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
+@@ -81,8 +68,7 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 
+-	if (CommandWithResult(Statement, "drop proc const_param") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "IF OBJECT_ID('const_param') IS NOT NULL DROP PROC const_param");
+ 
+ 	Command(Statement, "create proc const_param @in1 float, @in2 varbinary(100) as\n"
+ 		"begin\n"
+@@ -91,24 +77,19 @@ main(int argc, char *argv[])
+ 		" return 54321\n"
+ 		"end");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "{?=call const_param(12.5, 0x0102030405060708)}", SQL_NTS) !=
+-	    SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{?=call const_param(12.5, 0x0102030405060708)}", SQL_NTS));
+ 
+ 	output = 0xdeadbeef;
+-	if (SQLExecute(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute statement");
++	CHK(SQLExecute, (Statement));
+ 
+ 	if (output != 54321) {
+ 		fprintf(stderr, "Invalid result %d (0x%x) expected 54321\n", (int) output, (int) output);
+ 		return 1;
+ 	}
+ 
+-	if (CommandWithResult(Statement, "drop proc const_param") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "drop proc const_param");
+ 
+ 	Command(Statement, "create proc const_param @in varchar(20) as\n"
+ 		"begin\n"
+@@ -119,7 +100,7 @@ main(int argc, char *argv[])
+ 	/* catch problem reported by Peter Deacon */
+ 	output = 0xdeadbeef;
+ 	Command(Statement, "{CALL const_param('value')}");
+-	SQLBindCol(Statement, 1, SQL_C_SLONG, &output, 0, &ind);
++	CHK(SQLBindCol, (Statement, 1, SQL_C_SLONG, &output, 0, &ind));
+ 	SQLFetch(Statement);
+ 
+ 	if (output != 8421) {
+@@ -129,8 +110,7 @@ main(int argc, char *argv[])
+ 
+ 	ResetStatement();
+ 
+-	if (CommandWithResult(Statement, "drop proc const_param") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "drop proc const_param");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/copydesc.c b/src/odbc/unittests/copydesc.c
+index a92d2d9..75380bc 100644
+--- a/src/odbc/unittests/copydesc.c
++++ b/src/odbc/unittests/copydesc.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLCopyDesc and SQLAllocHandle(SQL_HANDLE_DESC) */
+ 
+-static char software_version[] = "$Id: copydesc.c,v 1.3 2007/04/12 07:49:30 freddy77 Exp $";
++static char software_version[] = "$Id: copydesc.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -15,24 +15,20 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	if (SQLGetStmtAttr(Statement, SQL_ATTR_APP_ROW_DESC, &ard, 0, NULL) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLGetStmtAttr");
++	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_APP_ROW_DESC, &ard, 0, NULL));
+ 
+-	SQLBindCol(Statement, 1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, name, sizeof(name), &ind2);
++	CHK(SQLBindCol, (Statement, 1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1));
++	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, name, sizeof(name), &ind2));
+ 
+-	if (SQLAllocHandle(SQL_HANDLE_DESC, Connection, &ard2) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLAllocHandle");
++	CHK(SQLAllocHandle, (SQL_HANDLE_DESC, Connection, &ard2));
+ 
+ 	/*
+ 	 * this is an additional test to test additional allocation 
+ 	 * As of 0.64 for a bug in SQLAllocDesc we only allow to allocate one
+ 	 */
+-	if (SQLAllocHandle(SQL_HANDLE_DESC, Connection, &ard3) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLAllocHandle");
++	CHK(SQLAllocHandle, (SQL_HANDLE_DESC, Connection, &ard3));
+ 
+-	if (SQLCopyDesc(ard, ard2) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLCopyDesc");
++	CHK(SQLCopyDesc, (ard, ard2));
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index d10e777..28e4609 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,14 +2,9 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.12 2007/11/26 06:25:11 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.13 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHK(func,params) \
+-	do { if (func params != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func); \
+-	} while(0)
+-
+ #define CHK_INFO(func,params) \
+ 	do { if (!SQL_SUCCEEDED(func params)) \
+ 		ODBC_REPORT_ERROR(#func); \
+@@ -145,11 +140,7 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 					exit(1);
+ 				}
+ 
+-				retcode = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+-				if (retcode != SQL_SUCCESS) {
+-					fprintf(stderr, "Error not expected at line %d\n", __LINE__);
+-					exit(1);
+-				}
++				CHK(SQLGetDiagRec, (SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL));
+ 				if (strstr((char *) msg, "Invalid column name 'c'") == NULL) {
+ 					fprintf(stderr, "Expected message not found at line %d\n", __LINE__);
+ 					exit(1);
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index d5fd48d..ac1d1db 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -2,13 +2,9 @@
+ 
+ /* Test cursor do not give error for statement that do not return rows  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.3 2007/04/20 13:27:14 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHK(func,params) \
+-	if (func params != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func)
+-
+ int
+ main(int argc, char *argv[])
+ {
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index d44fe3c..6ef62c8 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,11 +1,9 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.4 2008/01/10 15:29:03 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.5 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static SQLHDBC m_hdbc;
+-
+ #define CHECK_RCODE(t,h,m) \
+    if ( rcode != SQL_NO_DATA \
+      && rcode != SQL_SUCCESS \
+@@ -43,7 +41,7 @@ exec_direct(int check, const char *stmt)
+ 	SQLRETURN rcode;
+ 	SQLHSTMT stmth = 0;
+ 
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hdbc, (SQLHANDLE *) & stmth);
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & stmth);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLAllocHandle");
+ 	rcode = SQLExecDirect(stmth, (SQLCHAR *) stmt, SQL_NTS);
+ 	if (check) {
+@@ -67,8 +65,6 @@ main(int argc, char **argv)
+ 
+ 	CheckCursor();
+ 
+-	m_hdbc = Connection;
+-
+ 	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+ 	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
+ 	exec_direct(1, "INSERT INTO #t1 VALUES (2, 'bbbbb')");
+@@ -76,12 +72,12 @@ main(int argc, char **argv)
+ 	exec_direct(1, "INSERT INTO #t1 VALUES (4, 'dd')");
+ 
+ 	m_hstmt1 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle 1");
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt1);
++	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle 1");
+ 
+ 	m_hstmt2 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle 2");
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt2);
++	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle 2");
+ 
+ /*
+ 	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c
+index ef67014..363ebfd 100755
+--- a/src/odbc/unittests/cursor4.c
++++ b/src/odbc/unittests/cursor4.c
+@@ -5,11 +5,9 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.4 2008/01/10 15:29:03 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.5 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static SQLHDBC m_hdbc;
+-
+ #define CHECK_RCODE(t,h,m) \
+    if ( rcode != SQL_NO_DATA \
+      && rcode != SQL_SUCCESS \
+@@ -47,7 +45,7 @@ exec_direct(int check, const char *stmt)
+ 	SQLRETURN rcode;
+ 	SQLHSTMT stmth = 0;
+ 
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hdbc, (SQLHANDLE *) & stmth);
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & stmth);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLAllocHandle");
+ 	rcode = SQLExecDirect(stmth, (SQLCHAR *) stmt, SQL_NTS);
+ 	if (check) {
+@@ -70,14 +68,12 @@ main(int argc, char **argv)
+ 
+ 	CheckCursor();
+ 
+-	m_hdbc = Connection;
+-
+ 	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+ 	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
+ 
+ 	m_hstmt1 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle 1");
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt1);
++	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle 1");
+ 
+ 	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Set attribute SQL_ATTR_CONCURRENCY");
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index 53f380b..d8c4540 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.3 2008/01/10 15:29:03 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -56,25 +56,23 @@ int
+ main(int argc, char **argv)
+ {
+ 	SQLRETURN rcode;
+-	SQLHDBC m_hdbc;
+ 	SQLHSTMT m_hstmt1;
+ 	SQLHSTMT m_hstmt2;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 	CheckCursor();
+-	m_hdbc = Connection;
+ 
+-	rcode = SQLSetConnectAttr(m_hdbc, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_ENV, m_hdbc, "SQLSetConnectAttr(autocommit)");
++	rcode = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER);
++	CHECK_RCODE(SQL_HANDLE_ENV, Connection, "SQLSetConnectAttr(autocommit)");
+ 
+ 	m_hstmt1 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle StmtH 1");
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt1);
++	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH 1");
+ 
+ 	m_hstmt2 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, m_hdbc, &m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_DBC, m_hdbc, "SQLAllocHandle StmtH 2");
++	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt2);
++	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH 2");
+ 
+ 	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "create table #mytab1 (k int, c char(30))", SQL_NTS);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.1");
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 7b60d86..640510e 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test various bind type */
+ 
+-static char software_version[] = "$Id: data.c,v 1.13 2007/06/21 07:21:21 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.14 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -24,10 +24,7 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 	sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
+ 	Command(Statement, sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+-	if (SQLFetch(Statement) != SQL_SUCCESS) {
+-		fprintf(stderr, "Expected row\n");
+-		exit(1);
+-	}
++	CHK(SQLFetch, (Statement));
+ 	if (SQLFetch(Statement) != SQL_NO_DATA) {
+ 		fprintf(stderr, "Row not expected\n");
+ 		exit(1);
+diff --git a/src/odbc/unittests/date.c b/src/odbc/unittests/date.c
+index 320e8b1..a37360f 100644
+--- a/src/odbc/unittests/date.c
++++ b/src/odbc/unittests/date.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: date.c,v 1.9 2004/10/28 13:16:18 freddy77 Exp $";
++static char software_version[] = "$Id: date.c,v 1.10 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -18,35 +18,25 @@ DoTest(int n)
+ 
+ 	TIMESTAMP_STRUCT ts;
+ 
+-	if (CommandWithResult(Statement, "select convert(datetime, '2002-12-27 18:43:21')") != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute statement");
++	Command(Statement, "select convert(datetime, '2002-12-27 18:43:21')");
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO)
+ 		ODBC_REPORT_ERROR("Unable to fetch row");
+ 
+-	if (SQLDescribeCol(Statement, 1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Error getting data");
++	CHK(SQLDescribeCol, (Statement, 1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable));
+ 
+ 	if (n == 0) {
+ 		memset(&ts, 0, sizeof(ts));
+-		if (SQLGetData(Statement, 1, SQL_C_TIMESTAMP, &ts, sizeof(ts), &dataSize) != SQL_SUCCESS) {
+-			printf("Unable to get data col %d\n", 1);
+-			CheckReturn();
+-			exit(1);
+-		}
++		CHK(SQLGetData, (Statement, 1, SQL_C_TIMESTAMP, &ts, sizeof(ts), &dataSize));
+ 		sprintf((char *) output, "%04d-%02d-%02d %02d:%02d:%02d.000", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
+ 	} else {
+-		if (SQLGetData(Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize) != SQL_SUCCESS) {
+-			printf("Unable to get data col %d\n", 1);
+-			CheckReturn();
+-			exit(1);
+-		}
++		CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize));
+ 	}
+ 
+ 	printf("Date returned: %s\n", output);
+ 	if (strcmp((char *) output, "2002-12-27 18:43:21.000") != 0) {
+-		printf("Invalid returned date\n");
++		fprintf(stderr, "Invalid returned date\n");
+ 		exit(1);
+ 	}
+ 
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index 125d002..d8cffb2 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.3 2004/05/22 17:25:27 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -45,17 +45,15 @@ main(int argc, char *argv[])
+ 
+ 		/* TODO when multiple row fetch available test for error on some columns */
+ 
+-		if (SQLFetch(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLFetch failed when it shouldn't");
+-		if (SQLFetch(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLFetch failed when it shouldn't");
++		CHK(SQLFetch, (Statement));
++		CHK(SQLFetch, (Statement));
+ 		if (SQLFetch(Statement) != SQL_ERROR)
+ 			ODBC_REPORT_ERROR("SQLFetch succeed when it shouldn't");
+ 	}
+ 
+ 	ReadError();
+ 	if (!strstr((char *) output, "zero")) {
+-		printf("Message invalid\n");
++		fprintf(stderr, "Message invalid\n");
+ 		return 1;
+ 	}
+ 
+@@ -64,8 +62,7 @@ main(int argc, char *argv[])
+ 	SQLFetch(Statement);
+ 	SQLMoreResults(Statement);
+ 
+-	if (SQLAllocStmt(Connection, &stmt) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to allocate statement");
++	CHK(SQLAllocStmt, (Connection, &stmt));
+ 
+ 	Command(Statement, "SELECT * FROM sysobjects");
+ 
+diff --git a/src/odbc/unittests/funccall.c b/src/odbc/unittests/funccall.c
+index 0773818..bf80de9 100644
+--- a/src/odbc/unittests/funccall.c
++++ b/src/odbc/unittests/funccall.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?)} syntax and run */
+ 
+-static char software_version[] = "$Id: funccall.c,v 1.14 2007/04/12 13:36:14 freddy77 Exp $";
++static char software_version[] = "$Id: funccall.c,v 1.15 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -15,29 +15,20 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	if (CommandWithResult(Statement, "drop proc simpleresult") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");
+ 
+ 	Command(Statement, "create proc simpleresult @i int as begin return @i end");
+ 
+-	if (SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind input parameter");
++	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2));
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "{ \n?\t\r= call simpleresult(?)}", SQL_NTS) != SQL_SUCCESS) {
+-		printf("Unable to prepare statement\n");
+-		exit(1);
+-	}
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ \n?\t\r= call simpleresult(?)}", SQL_NTS));
+ 
+ 	input = 123;
+ 	ind2 = sizeof(input);
+ 	output = 0xdeadbeef;
+-	if (SQLExecute(Statement) != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		exit(1);
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+ 	if (output != 123) {
+ 		printf("Invalid result\n");
+@@ -57,26 +48,22 @@ main(int argc, char *argv[])
+ 	input = 567;
+ 	ind2 = sizeof(input);
+ 	output = 0xdeadbeef;
+-	if (SQLExecDirect(Statement, (SQLCHAR *) "{?=call simpleresult(?)}", SQL_NTS) != SQL_SUCCESS) {
+-		printf("Unable to execure direct statement\n");
+-		exit(1);
+-	}
++	CHK(SQLExecDirect, (Statement, (SQLCHAR *) "{?=call simpleresult(?)}", SQL_NTS));
+ 
+ 	if (output != 567) {
+-		printf("Invalid result\n");
++		fprintf(stderr, "Invalid result\n");
+ 		exit(1);
+ 	}
+ 
+ 	/* should return "Invalid cursor state" */
+ 	if (SQLFetch(Statement) != SQL_ERROR) {
+-		printf("Data not expected\n");
++		fprintf(stderr, "Data not expected\n");
+ 		exit(1);
+ 	}
+ 
+ 	Command(Statement, "drop proc simpleresult");
+ 
+-	if (CommandWithResult(Statement, "drop proc simpleresult2") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");
+ 
+ 	/* force cursor close */
+ 	SQLCloseCursor(Statement);
+@@ -85,31 +72,12 @@ main(int argc, char *argv[])
+ 	Command(Statement,
+ 		"create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind) != SQL_SUCCESS) {
+-		printf("Unable to bind output parameter\n");
+-		exit(1);
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind));
++	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2));
++	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &out1,   0,            &ind3));
++	CHK(SQLBindParameter, (Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR,  SQL_VARCHAR, 20, 0, out2,    sizeof(out2), &ind4));
+ 
+-	if (SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2) != SQL_SUCCESS) {
+-		printf("Unable to bind input parameter\n");
+-		exit(1);
+-	}
+-
+-	if (SQLBindParameter(Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind3) != SQL_SUCCESS) {
+-		printf("Unable to bind output parameter\n");
+-		exit(1);
+-	}
+-
+-	if (SQLBindParameter(Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, out2, sizeof(out2), &ind4) !=
+-	    SQL_SUCCESS) {
+-		printf("Unable to bind output parameter\n");
+-		exit(1);
+-	}
+-
+-	if (SQLPrepare(Statement, (SQLCHAR *) "{ \n?\t\r= call simpleresult2(?,?,?)}", SQL_NTS) != SQL_SUCCESS) {
+-		printf("Unable to prepare statement\n");
+-		exit(1);
+-	}
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ \n?\t\r= call simpleresult2(?,?,?)}", SQL_NTS));
+ 
+ 	input = 987;
+ 	ind2 = sizeof(input);
+@@ -117,10 +85,7 @@ main(int argc, char *argv[])
+ 	output = 0xdeadbeef;
+ 	ind3 = SQL_DATA_AT_EXEC;
+ 	ind4 = SQL_DEFAULT_PARAM;
+-	if (SQLExecute(Statement) != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		exit(1);
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+ 	if (output != 987 || ind3 <= 0 || ind4 <= 0 || out1 != 6789 || strcmp(out2, "test foo") != 0) {
+ 		printf("ouput = %d ind3 = %d ind4 = %d out1 = %d out2 = %s\n", (int) output, (int) ind3, (int) ind4, (int) out1,
+@@ -131,7 +96,7 @@ main(int argc, char *argv[])
+ 
+ 	/* should return "Invalid cursor state" */
+ 	if (SQLFetch(Statement) != SQL_ERROR) {
+-		printf("Data not expected\n");
++		fprintf(stderr, "Data not expected\n");
+ 		exit(1);
+ 	}
+ 
+@@ -142,42 +107,33 @@ main(int argc, char *argv[])
+ 	 * Cfr ML 2006-11-21 "specifying a 0 for the StrLen_or_IndPtr in the
+ 	 * SQLBindParameter call is not working on AIX"
+ 	 */
+-	if (CommandWithResult(Statement, "drop proc rpc_read") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");
+ 
+-	SQLCloseCursor(Statement);
++	ResetStatement();
+ 
+ 	Command(Statement, "create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
+ 	SQLCloseCursor(Statement);
+-	SQLFreeStmt(Statement, SQL_CLOSE);
+-	SQLFreeStmt(Statement, SQL_UNBIND);
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "{ ? = CALL rpc_read ( ?, ? ) }" , SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement\n");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ ? = CALL rpc_read ( ?, ? ) }" , SQL_NTS));
+ 
+ 	ind = 0;
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter\n");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
+ 
+ 	ind2 = 0;
+-	if (SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind input parameter\n");
++	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2));
+ 
+ 	ind3 = 8;
+-	if (SQLBindParameter(Statement, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter\n");
++	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3));
+ 
+-	if (SQLExecute(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute statement\n");
++	CHK(SQLExecute, (Statement));
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Data not expected\n");
++	CHK(SQLFetch, (Statement));
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Data not expected\n");
+ 
+ 	ResetStatement();
+-	CommandWithResult(Statement, "drop proc rpc_read");
++	Command(Statement, "drop proc rpc_read");
+ 
+ 	/*
+ 	 * Test from Joao Amaral
+@@ -190,19 +146,16 @@ main(int argc, char *argv[])
+ 
+ 		ResetStatement();
+ 
+-		CommandWithResult(Statement, "drop proc sp_test");
++		Command(Statement, "IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
+ 		Command(Statement, "create proc sp_test @res int output as set @res = 456");
+ 
+ 		ResetStatement();
+ 
+-		if (SQLPrepare(Statement, (SQLCHAR *) "{ call sp_test(?)}", SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to prepare statement\n");
+-		if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to bind output parameter\n");
++		CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ call sp_test(?)}", SQL_NTS));
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
+ 
+ 		output = 0xdeadbeef;
+-		if (SQLExecute(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to execute statement\n");
++		CHK(SQLExecute, (Statement));
+ 
+ 		if (output != 456) {
+ 			fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 6b783c9..9eb1b4f 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.23 2008/01/08 09:33:32 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.24 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -37,34 +37,28 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQL
+ 
+ 	if (use_cursors) {
+ 		ResetStatement();
+-		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLSetStmtAttr error");
+-		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLSetStmtAttr error");
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0));
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
+ 	}
+ 
+ 	/* bind parameter */
+ 	if (exec_direct) {
+-		if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
+-			     sizeof(out_buf), &out_len) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to bind output parameter");
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
++			     sizeof(out_buf), &out_len));
+ 
+ 		/* call store procedure */
+-		if (SQLExecDirect(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to execute store statement");
++		CHK(SQLExecDirect, (Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS));
+ 	} else {
+-		if (prepare_before && SQLPrepare(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLPrepare() failure!");
++		if (prepare_before)
++			CHK(SQLPrepare, (Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS));
+ 
+-		if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
+-			     sizeof(out_buf), &out_len) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to bind output parameter");
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
++			     sizeof(out_buf), &out_len));
+ 
+-		if (!prepare_before && SQLPrepare(Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLPrepare() failure!");
++		if (!prepare_before)
++			CHK(SQLPrepare, (Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS));
+ 
+-		if (SQLExecute(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLExecute() failure!");
++		CHK(SQLExecute, (Statement));
+ 	}
+ 
+ 	/* test results */
+@@ -152,16 +146,14 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	} else {
+ 		SQLRETURN rc;
+ 
+-		if (prepare_before && SQLPrepare(Statement, (SQLCHAR *) sbuf, SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLPrepare() failure!");
++		if (prepare_before)
++			CHK(SQLPrepare, (Statement, (SQLCHAR *) sbuf, SQL_NTS));
+ 
+ 		out_len = 1;
+-		if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=
+-		    SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to bind input parameter");
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
+ 
+-		if (!prepare_before && SQLPrepare(Statement, (SQLCHAR *) sbuf, SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLPrepare() failure!");
++		if (!prepare_before)
++			CHK(SQLPrepare, (Statement, (SQLCHAR *) sbuf, SQL_NTS));
+ 
+ 		rc = SQLExecute(Statement);
+ 		if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
+@@ -173,8 +165,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, '%s')", param_type, expected);
+ 	Command(Statement, sbuf);
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Expected row");
++	CHK(SQLFetch, (Statement));
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Row not expected");
+ 	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 1752423..8520ca1 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.5 2008/01/29 09:35:25 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.6 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -55,11 +55,7 @@ main(int argc, char *argv[])
+ 	/* TODO test with VARCHAR too */
+ 	Command(Statement, "SELECT CONVERT(TEXT,'Prova')");
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS) {
+-		printf("Unable to fetch row\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(SQLFetch, (Statement));
+ 
+ 	/* these 2 tests test an old severe BUG in FreeTDS */
+ 	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
+@@ -75,8 +71,7 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 16, NULL) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to get data");
++	CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, buf, 16, NULL));
+ 	if (strcmp(buf, "ova") != 0) {
+ 		printf("Wrong data result 2 res = '%s'\n", buf);
+ 		exit(1);
+@@ -87,8 +82,7 @@ main(int argc, char *argv[])
+ 	/* test with varchar, not blob but variable */
+ 	Command(Statement, "SELECT CONVERT(VARCHAR(100), 'Other test')");
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to fetch row");
++	CHK(SQLFetch, (Statement));
+ 
+ 	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 7, NULL) != SQL_SUCCESS_WITH_INFO)
+ 		ODBC_REPORT_ERROR("Unable to get data");
+@@ -97,8 +91,7 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 16, NULL) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to get data");
++	CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, buf, 16, NULL));
+ 	if (strcmp(buf, "test") != 0) {
+ 		printf("Wrong data result 2 res = '%s'\n", buf);
+ 		exit(1);
+@@ -109,12 +102,10 @@ main(int argc, char *argv[])
+ 	/* test with fixed length */
+ 	Command(Statement, "SELECT CONVERT(INT, 12345)");
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to fetch row");
++	CHK(SQLFetch, (Statement));
+ 
+ 	int_buf = 0xdeadbeef;
+-	if (SQLGetData(Statement, 1, SQL_C_SLONG, &int_buf, 0, NULL) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to get data");
++	CHK(SQLGetData, (Statement, 1, SQL_C_SLONG, &int_buf, 0, NULL));
+ 	if (int_buf != 12345) {
+ 		printf("Wrong data result\n");
+ 		exit(1);
+@@ -149,12 +140,10 @@ main(int argc, char *argv[])
+ 	if (db_is_microsoft()) {
+ 		Command(Statement, "SELECT CONVERT(TEXT,'')");
+ 
+-		if (SQLFetch(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to fetch row");
++		CHK(SQLFetch, (Statement));
+ 
+ 		len = 1234;
+-		if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 1, &len) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("invalid return from SQLGetData");
++		CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, buf, 1, &len));
+ 
+ 		if (len != 0) {
+ 			fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+index 71124a6..b02881e 100755
+--- a/src/odbc/unittests/hidden.c
++++ b/src/odbc/unittests/hidden.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.3 2008/01/10 21:19:47 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -41,7 +41,6 @@ int
+ main(int argc, char **argv)
+ {
+ 	SQLRETURN rcode;
+-	SQLHSTMT m_hstmt1;
+ 	SQLSMALLINT cnt = 0;
+ 	int failed = 0;
+ 
+@@ -54,13 +53,10 @@ main(int argc, char **argv)
+ 	/* test hidden column with FOR BROWSE */
+ 	ResetStatement();
+ 
+-	m_hstmt1 = Statement;
++	Command(Statement, "SELECT c, b FROM #tmp1");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c, b FROM #tmp1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect");
+-
+-	rcode = SQLNumResultCols(m_hstmt1, &cnt);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLNumResultCols 1");
++	rcode = SQLNumResultCols(Statement, &cnt);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLNumResultCols 1");
+ 
+ 	if (cnt != 2) {
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+@@ -70,21 +66,20 @@ main(int argc, char **argv)
+ 
+ 	/* test hidden column with cursors*/
+ 	CheckCursor();
+-	m_hstmt1 = Statement;
+ 
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++	rcode = SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
++	rcode = SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLPrepare 1");
++	rcode = SQLPrepare(Statement, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLPrepare 1");
+ 
+-	rcode = SQLExecute(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecute 1");
++	rcode = SQLExecute(Statement);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLExecute 1");
+ 
+-	rcode = SQLNumResultCols(m_hstmt1, &cnt);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLNumResultCols 1");
++	rcode = SQLNumResultCols(Statement, &cnt);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLNumResultCols 1");
+ 
+ 	if (cnt != 3) {
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+diff --git a/src/odbc/unittests/lang_error.c b/src/odbc/unittests/lang_error.c
+index 7634934..90192b4 100644
+--- a/src/odbc/unittests/lang_error.c
++++ b/src/odbc/unittests/lang_error.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test if SQLExecDirect return error if a error in row is returned */
+ 
+-static char software_version[] = "$Id: lang_error.c,v 1.2 2003/11/08 18:00:33 freddy77 Exp $";
++static char software_version[] = "$Id: lang_error.c,v 1.3 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,7 +12,7 @@ main(int argc, char *argv[])
+ 
+ 	/* issue print statement and test message returned */
+ 	if (CommandWithResult(Statement, "SELECT DATEADD(dd,-100000,getdate())") != SQL_ERROR) {
+-		printf("SQLExecDirect should return SQL_ERROR\n");
++		fprintf(stderr, "SQLExecDirect should return SQL_ERROR\n");
+ 		return 1;
+ 	}
+ 
+diff --git a/src/odbc/unittests/moreandcount.c b/src/odbc/unittests/moreandcount.c
+index 4c922dc..95ae329 100644
+--- a/src/odbc/unittests/moreandcount.c
++++ b/src/odbc/unittests/moreandcount.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults and SQLRowCount on batch */
+ 
+-static char software_version[] = "$Id: moreandcount.c,v 1.14 2006/07/13 08:21:56 freddy77 Exp $";
++static char software_version[] = "$Id: moreandcount.c,v 1.15 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -45,21 +45,12 @@ DoTest(int prepare)
+ 		"UPDATE #tmp1 SET i=i+1 WHERE i >= 2";
+ 
+ 	if (prepare) {
+-		if (SQLPrepare(Statement, (SQLCHAR *) query, SQL_NTS) != SQL_SUCCESS) {
+-			printf("Unable to prepare statement\n");
+-			exit(1);
+-		}
+-		if (SQLExecute(Statement) != SQL_SUCCESS) {
+-			printf("Unable to execute statement\n");
+-			exit(1);
+-		}
++		CHK(SQLPrepare, (Statement, (SQLCHAR *) query, SQL_NTS));
++		CHK(SQLExecute, (Statement));
+ 	} else {
+ 
+ 		/* execute a batch command select insert insert select and check rows */
+-		if (SQLExecDirect(Statement, (SQLCHAR *) query, SQL_NTS) != SQL_SUCCESS) {
+-			printf("Unable to execute direct statement\n");
+-			exit(1);
+-		}
++		CHK(SQLExecDirect, (Statement, (SQLCHAR *) query, SQL_NTS));
+ 	}
+ 	if (!prepare) {
+ 		printf("Result %d\n", ++n);
+diff --git a/src/odbc/unittests/norowset.c b/src/odbc/unittests/norowset.c
+index 6a6afb3..b18245c 100644
+--- a/src/odbc/unittests/norowset.c
++++ b/src/odbc/unittests/norowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: norowset.c,v 1.5 2006/03/23 14:53:44 freddy77 Exp $";
++static char software_version[] = "$Id: norowset.c,v 1.6 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Test that a select following a store procedure execution return results */
+@@ -22,18 +22,9 @@ main(int argc, char *argv[])
+ 
+ 	/* note, mssql 2005 seems to not return row for tempdb, use always master */
+ 	Command(Statement, "select name from master..sysobjects where name = 'sysobjects'");
+-	res = SQLFetch(Statement);
+-	if (res != SQL_SUCCESS) {
+-		printf("Unable to fetch row\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(SQLFetch, (Statement));
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize) != SQL_SUCCESS) {
+-		printf("Unable to get data col %d\n", 1);
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize));
+ 
+ 	if (strcmp(output, "sysobjects") != 0) {
+ 		printf("Unexpected result\n");
+@@ -42,13 +33,12 @@ main(int argc, char *argv[])
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_NO_DATA) {
+-		printf("Row not expected\n");
++		fprintf(stderr, "Row not expected\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		printf("Not expected another recordset\n");
++		fprintf(stderr, "Not expected another recordset\n");
+ 		exit(1);
+ 	}
+ 
+diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c
+index cbf01ee..191066c 100644
+--- a/src/odbc/unittests/params.c
++++ b/src/odbc/unittests/params.c
+@@ -3,7 +3,7 @@
+ /* Test for store procedure and params */
+ /* Test from Tom Rogers */
+ 
+-static char software_version[] = "$Id: params.c,v 1.7 2005/03/29 15:19:36 freddy77 Exp $";
++static char software_version[] = "$Id: params.c,v 1.8 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* SP definition */
+@@ -39,51 +39,22 @@ Test(int bind_before)
+ 	/* create proc */
+ 	Command(Statement, sp_define);
+ 
+-	if (!bind_before) {
+-		if (SQLPrepare(Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)) != SQL_SUCCESS) {
+-			fprintf(stderr, "Unable to prepare statement\n");
+-			return 1;
+-		}
+-	}
+-
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode) !=
+-	    SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to bind input parameter\n");
+-		return 1;
+-	}
+-
+-	if (SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam, 0, &cbInParam) !=
+-	    SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to bind input parameter\n");
+-		return 1;
+-	}
++	if (!bind_before)
++		CHK(SQLPrepare, (Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)));
+ 
+-	if (SQLBindParameter(Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam, 0, &cbOutParam) !=
+-	    SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to bind input parameter\n");
+-		return 1;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode));
++	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT,  SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam,    0, &cbInParam));
++	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam,   0, &cbOutParam));
+ 
+ 	OutString[0] = '\0';
+ 	strcpy(OutString, "Test");	/* Comment this line and we get an error!  Why? */
+-	if (SQLBindParameter
+-	    (Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
+-	     &cbOutString) != SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to bind input parameter\n");
+-		return 1;
+-	}
++	CHK(SQLBindParameter, (Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, 
++	    OUTSTRING_LEN, &cbOutString));
+ 
+-	if (bind_before) {
+-		if (SQLPrepare(Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)) != SQL_SUCCESS) {
+-			fprintf(stderr, "Unable to prepare statement\n");
+-			return 1;
+-		}
+-	}
++	if (bind_before)
++		CHK(SQLPrepare, (Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)));
+ 
+-	if (SQLExecute(Statement) != SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to execute statement\n");
+-		return 1;
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+ 	Command(Statement, "drop proc spTestProc");
+ 
+diff --git a/src/odbc/unittests/prepare_results.c b/src/odbc/unittests/prepare_results.c
+index 651ce0a..8ebdb4e 100644
+--- a/src/odbc/unittests/prepare_results.c
++++ b/src/odbc/unittests/prepare_results.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for data format returned from SQLPrepare */
+ 
+-static char software_version[] = "$Id: prepare_results.c,v 1.8 2007/06/19 12:07:59 freddy77 Exp $";
++static char software_version[] = "$Id: prepare_results.c,v 1.9 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -22,11 +22,9 @@ main(int argc, char *argv[])
+ 	SQLMoreResults(Statement);
+ 
+ 	/* test query returns column information for update */
+-	if (SQLPrepare(Statement, (SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLPrepare return failure");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS));
+ 
+-	if (SQLNumResultCols(Statement, &count) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLNumResultCols return failure");
++	CHK(SQLNumResultCols, (Statement, &count));
+ 
+ 	if (count != 0) {
+ 		fprintf(stderr, "Wrong number of columns returned. Got %d expected 0\n", (int) count);
+@@ -34,35 +32,30 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* test query returns column information */
+-	if (SQLPrepare(Statement, (SQLCHAR *) "select * from #odbctestdata select * from #odbctestdata", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLPrepare return failure");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "select * from #odbctestdata select * from #odbctestdata", SQL_NTS));
+ 
+-	if (SQLNumResultCols(Statement, &count) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLNumResultCols return failure");
++	CHK(SQLNumResultCols, (Statement, &count));
+ 
+ 	if (count != 3) {
+ 		fprintf(stderr, "Wrong number of columns returned. Got %d expected 3\n", (int) count);
+ 		exit(1);
+ 	}
+ 
+-	if (SQLDescribeCol(Statement, 1, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLDescribeCol failure for column 1");
++	CHK(SQLDescribeCol, (Statement, 1, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable));
+ 
+ 	if (type != SQL_INTEGER || strcmp(name, "i") != 0) {
+ 		fprintf(stderr, "wrong column 1 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+ 		exit(1);
+ 	}
+ 
+-	if (SQLDescribeCol(Statement, 2, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLDescribeCol failure for column 2");
++	CHK(SQLDescribeCol, (Statement, 2, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable));
+ 
+ 	if (type != SQL_CHAR || strcmp(name, "c") != 0 || (size != 20 && (db_is_microsoft() || size != 40))) {
+ 		fprintf(stderr, "wrong column 2 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+ 		exit(1);
+ 	}
+ 
+-	if (SQLDescribeCol(Statement, 3, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLDescribeCol failure for column 3");
++	CHK(SQLDescribeCol, (Statement, 3, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable));
+ 
+ 	if (type != SQL_NUMERIC || strcmp(name, "n") != 0 || size != 34 || digits != 12) {
+ 		fprintf(stderr, "wrong column 3 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c
+index 4033d5b..45f33dd 100644
+--- a/src/odbc/unittests/print.c
++++ b/src/odbc/unittests/print.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: print.c,v 1.18 2005/12/04 11:16:30 freddy77 Exp $";
++static char software_version[] = "$Id: print.c,v 1.19 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -53,16 +53,13 @@ test(int odbc3)
+ 		rc = SQLFetch(Statement);
+ 		if (rc != SQL_ERROR)
+ 			ODBC_REPORT_ERROR("Still data?");
+-		rc = SQLMoreResults(Statement);
+-		if (rc != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLMoreResults failed");
++		CHK(SQLMoreResults, (Statement));
+ 	}
+     
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLFetch no succeeded");
++	CHK(SQLFetch, (Statement));
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index b199b9d..a9d3878 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.9 2004/10/28 13:16:18 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.10 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -25,9 +25,7 @@ main(int argc, char *argv[])
+ 	/* create table to hold data */
+ 	Command(Statement, "CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (SQLPOINTER) 123, 0, &ind) !=
+-	    SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (SQLPOINTER) 123, 0, &ind));
+ 	/* length required */
+ 	ind = SQL_LEN_DATA_AT_EXEC(len);
+ 
+@@ -35,8 +33,7 @@ main(int argc, char *argv[])
+ 	 * test for char 
+ 	 */
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
+ 
+ 	if (SQLExecute(Statement) != SQL_NEED_DATA)
+ 		ODBC_REPORT_ERROR("Wrong result executing statement");
+@@ -57,8 +54,7 @@ main(int argc, char *argv[])
+ 		p += n;
+ 		n *= 2;
+ 	}
+-	if (SQLParamData(Statement, &ptr) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++	CHK(SQLParamData, (Statement, &ptr));
+ 
+ 	if (SQLParamData(Statement, &ptr) != SQL_ERROR)
+ 		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
+@@ -74,13 +70,10 @@ main(int argc, char *argv[])
+ 	 * test for binary 
+ 	 */
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind) !=
+-	    SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind output parameter");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind));
+ 	ind = SQL_LEN_DATA_AT_EXEC(254);
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "UPDATE #putdata SET b = ?", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "UPDATE #putdata SET b = ?", SQL_NTS));
+ 
+ 	if (SQLExecute(Statement) != SQL_NEED_DATA)
+ 		ODBC_REPORT_ERROR("Wrong result executing statement");
+@@ -96,13 +89,11 @@ main(int argc, char *argv[])
+ 
+ 		if (l < n)
+ 			n = l;
+-		if (SQLPutData(Statement, (char *) p, n) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Wrong result from SQLPutData");
++		CHK(SQLPutData, (Statement, (char *) p, n));
+ 		pb += n;
+ 		n *= 2;
+ 	}
+-	if (SQLParamData(Statement, &ptr) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++	CHK(SQLParamData, (Statement, &ptr));
+ 
+ 	if (SQLParamData(Statement, &ptr) != SQL_ERROR)
+ 		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
+@@ -112,14 +103,11 @@ main(int argc, char *argv[])
+ 
+ 
+ 	/* test len == 0 case from ML */
+-	if (SQLFreeStmt(Statement, SQL_RESET_PARAMS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLFreeStmt error");
++	CHK(SQLFreeStmt, (Statement, SQL_RESET_PARAMS));
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLBindParameter error");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind));
+ 
+ 	ind = SQL_LEN_DATA_AT_EXEC(0);
+ 
+diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c
+index 94bb486..76fd66f 100644
+--- a/src/odbc/unittests/raiserror.c
++++ b/src/odbc/unittests/raiserror.c
+@@ -4,7 +4,7 @@
+ 
+ /* TODO add support for Sybase */
+ 
+-static char software_version[] = "$Id: raiserror.c,v 1.19 2007/11/26 06:25:11 freddy77 Exp $";
++static char software_version[] = "$Id: raiserror.c,v 1.20 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{?=call #tmp1(?,?,?)}"
+@@ -153,14 +153,10 @@ Test(int level)
+ 	SQLBindParameter(Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
+ 			 &cbOutString);
+ 
+-	result = SQLExecute(Statement);
+-
+-	if (result != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("query should success");
++	CHK(SQLExecute, (Statement));
+ 
+ 	CheckData("");
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLFetch returned failure");
++	CHK(SQLFetch, (Statement));
+ 	CheckData("Here is the first row");
+ 
+ 	result = SQLFetch(Statement);
+@@ -221,8 +217,7 @@ Test(int level)
+ 	CheckReturnCode(result, INVALID_RETURN);
+ 
+ 	CheckData("");
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLFetch returned failure");
++	CHK(SQLFetch, (Statement));
+ 	CheckData("Here is the last row");
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+diff --git a/src/odbc/unittests/rebindpar.c b/src/odbc/unittests/rebindpar.c
+index d8f0c21..d814b1c 100644
+--- a/src/odbc/unittests/rebindpar.c
++++ b/src/odbc/unittests/rebindpar.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for executing SQLExecute and rebinding parameters */
+ 
+-static char software_version[] = "$Id: rebindpar.c,v 1.6 2004/12/01 13:11:35 freddy77 Exp $";
++static char software_version[] = "$Id: rebindpar.c,v 1.7 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -13,16 +13,15 @@ TestInsert(HSTMT stmt, char *buf)
+ 	char sql[200];
+ 
+ 	/* insert some data and test success */
+-	if (SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, l, 0, buf, l, &ind) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to bind");
++	CHK(SQLBindParameter, (stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, l, 0, buf, l, &ind));
+ 
+ 	ind = l;
+-	if (SQLExecute(stmt) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute");
++	CHK(SQLExecute, (stmt));
+ 
+ 	sprintf(sql, "SELECT 1 FROM #tmp1 WHERE c = '%s'", buf);
+ 	Command(Statement, sql);
+-	if (SQLFetch(Statement) != SQL_SUCCESS || SQLFetch(Statement) != SQL_NO_DATA || SQLMoreResults(Statement) != SQL_NO_DATA) {
++	CHK(SQLFetch, (Statement));
++	if (SQLFetch(Statement) != SQL_NO_DATA || SQLMoreResults(Statement) != SQL_NO_DATA) {
+ 		fprintf(stderr, "One row expected!\n");
+ 		exit(1);
+ 	}
+@@ -43,15 +42,12 @@ Test(int prebind)
+ 
+ 	Command(Statement, "DELETE FROM #tmp1");
+ 
+-	if (SQLAllocStmt(Connection, &stmt) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to allocate statement");
++	CHK(SQLAllocStmt, (Connection, &stmt));
+ 
+ 	if (prebind)
+-		if (SQLBindParameter(stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 1, 0, buf, 1, &ind) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to bind");
++		CHK(SQLBindParameter, (stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 1, 0, buf, 1, &ind));
+ 
+-	if (SQLPrepare(stmt, (SQLCHAR *) "INSERT INTO #tmp1(c) VALUES(?)", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (stmt, (SQLCHAR *) "INSERT INTO #tmp1(c) VALUES(?)", SQL_NTS));
+ 
+ 	/* try to insert al empty string, should not fail */
+ 	/* NOTE this is currently the only test for insert a empty string using rpc */
+@@ -61,8 +57,7 @@ Test(int prebind)
+ 	TestInsert(stmt, "bb");
+ 	TestInsert(stmt, buf);
+ 
+-	if (SQLFreeStmt(stmt, SQL_DROP) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to free statement");
++	CHK(SQLFreeStmt, (stmt, SQL_DROP));
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/scroll.c b/src/odbc/unittests/scroll.c
+index 9ba8e5f..f3ff03f 100644
+--- a/src/odbc/unittests/scroll.c
++++ b/src/odbc/unittests/scroll.c
+@@ -2,13 +2,9 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: scroll.c,v 1.6 2007/11/26 06:25:11 freddy77 Exp $";
++static char software_version[] = "$Id: scroll.c,v 1.7 2008/01/29 14:30:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHK(func,params) \
+-	if (func params != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func)
+-
+ int
+ main(int argc, char *argv[])
+ {
+diff --git a/src/odbc/unittests/t0001.c b/src/odbc/unittests/t0001.c
+index 399e30c..6ca6c8d 100644
+--- a/src/odbc/unittests/t0001.c
++++ b/src/odbc/unittests/t0001.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.14 2004/10/28 13:16:18 freddy77 Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.15 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -24,40 +24,23 @@ main(int argc, char *argv[])
+ 		"col1 varchar(30) not null,"
+ 		"col2 int not null,"
+ 		"col3 float not null," "col4 numeric(18,6) not null," "col5 datetime not null," "col6 text not null)";
+-	if (CommandWithResult(Statement, command) != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(CommandWithResult, (Statement, command));
+ 
+ 	command = "insert #odbctestdata values ("
+ 		"'ABCDEFGHIJKLMNOP',"
+ 		"123456," "1234.56," "123456.78," "'Sep 11 2001 10:00AM'," "'just to check returned length...')";
+-	if (CommandWithResult(Statement, command) != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(CommandWithResult, (Statement, command));
+ 
+-	if (CommandWithResult(Statement, "select * from #odbctestdata") != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(CommandWithResult, (Statement, "select * from #odbctestdata"));
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
+-		printf("Unable to fetch row\n");
++		fprintf(stderr, "Unable to fetch row\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	for (i = 1; i <= 6; i++) {
+-		if (SQLGetData(Statement, i, SQL_C_CHAR, output, sizeof(output), &cnamesize) != SQL_SUCCESS) {
+-			printf("Unable to get data col %d\n", i);
+-			CheckReturn();
+-			exit(1);
+-		}
++		CHK(SQLGetData, (Statement, i, SQL_C_CHAR, output, sizeof(output), &cnamesize));
+ 
+ 		printf("output data >%s< len_or_ind = %d\n", output, (int) cnamesize);
+ 		if (cnamesize != strlen((char *) output))
+@@ -66,23 +49,17 @@ main(int argc, char *argv[])
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_NO_DATA) {
+-		printf("Unable to fetch row\n");
++		fprintf(stderr, "Unable to fetch row\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	res = SQLCloseCursor(Statement);
+ 	if (!SQL_SUCCEEDED(res)) {
+-		printf("Unable to close cursr\n");
++		fprintf(stderr, "Unable to close cursor\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+-	if (CommandWithResult(Statement, "drop table #odbctestdata") != SQL_SUCCESS) {
+-		printf("Unable to drop table #odbctestdata \n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	Command(Statement, "drop table #odbctestdata");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/t0002.c b/src/odbc/unittests/t0002.c
+index 5da1784..8fa2830 100644
+--- a/src/odbc/unittests/t0002.c
++++ b/src/odbc/unittests/t0002.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.12 2005/06/29 07:21:24 freddy77 Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.13 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -24,53 +24,42 @@ main(int argc, char *argv[])
+ 	 * result should not disappear (required for DBD::ODBC)
+ 	 */
+ 
+-	if (SQLAllocStmt(Connection, &stmt) != SQL_SUCCESS) {
+-		printf("Unable to allocate statement\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(SQLAllocStmt, (Connection, &stmt));
+ 
+ 	Command(stmt, "select * from #odbctestdata where 0=1");
+ 
+ 	if (SQLFetch(stmt) != SQL_NO_DATA) {
+-		printf("Data not expected\n");
++		fprintf(stderr, "Data not expected\n");
+ 		exit(1);
+ 	}
+ 
+ 	res = SQLCloseCursor(stmt);
+ 	if (!SQL_SUCCEEDED(res)) {
+-		printf("Unable to close cursr\n");
++		fprintf(stderr, "Unable to close cursor\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	Command(Statement, "select * from #odbctestdata");
+ 
+ 	/* drop first statement .. data should not disappear */
+-	if (SQLFreeStmt(stmt, SQL_DROP) != SQL_SUCCESS) {
+-		printf("Error dropping??\n");
+-		exit(1);
+-	}
++	CHK(SQLFreeStmt, (stmt, SQL_DROP));
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
+-		printf("Unable to fetch row. Drop of previous statement discard results... bad!\n");
++		fprintf(stderr, "Unable to fetch row. Drop of previous statement discard results... bad!\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_NO_DATA) {
+-		printf("Unable to fetch row\n");
++		fprintf(stderr, "Unable to fetch row\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	res = SQLCloseCursor(Statement);
+ 	if (!SQL_SUCCEEDED(res)) {
+-		printf("Unable to close cursr\n");
++		fprintf(stderr, "Unable to close cursr\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	Command(Statement, "drop table #odbctestdata");
+diff --git a/src/odbc/unittests/t0003.c b/src/odbc/unittests/t0003.c
+index c36947e..d9e6640 100644
+--- a/src/odbc/unittests/t0003.c
++++ b/src/odbc/unittests/t0003.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.16 2005/03/29 15:19:36 freddy77 Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.17 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -14,17 +14,14 @@ DoTest(int prepared)
+ 	if (!prepared) {
+ 		Command(Statement, "select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+-		if (SQLPrepare(Statement, (SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLPrepare return failure");
+-		if (SQLExecute(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLExecure return failure");
++		CHK(SQLPrepare, (Statement, (SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS));
++		CHK(SQLExecute, (Statement));
+ 	}
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Data not expected");
+ 
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Expected another recordset");
++	CHK(SQLMoreResults, (Statement));
+ 	printf("Getting next recordset\n");
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+@@ -38,18 +35,14 @@ DoTest(int prepared)
+ 	if (!prepared) {
+ 		Command(Statement, "select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+-		if (SQLPrepare(Statement, (SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLPrepare return failure");
+-		if (SQLExecute(Statement) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLExecure return failure");
++		CHK(SQLPrepare, (Statement, (SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS));
++		CHK(SQLExecute, (Statement));
+ 	}
+ 
+-	if (SQLMoreResults(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Expected another recordset");
++	CHK(SQLMoreResults, (Statement));
+ 	printf("Getting next recordset\n");
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Expecting a row");
++	CHK(SQLFetch, (Statement));
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Data not expected");
+diff --git a/src/odbc/unittests/t0004.c b/src/odbc/unittests/t0004.c
+index 60cbddb..839fa60 100644
+--- a/src/odbc/unittests/t0004.c
++++ b/src/odbc/unittests/t0004.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.15 2006/03/23 14:53:44 freddy77 Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.16 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -15,28 +15,19 @@ Test(int use_indicator)
+ 	strcpy(buf, "I don't exist");
+ 	ind = strlen(buf);
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, buf, 128, pind) != SQL_SUCCESS) {
+-		printf("Unable to bind parameter\n");
+-		exit(1);
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, buf, 128, pind));
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "SELECT id, name FROM master..sysobjects WHERE name = ?", SQL_NTS) != SQL_SUCCESS) {
+-		printf("Unable to prepare statement\n");
+-		exit(1);
+-	}
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT id, name FROM master..sysobjects WHERE name = ?", SQL_NTS));
+ 
+-	if (SQLExecute(Statement) != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		exit(1);
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA) {
+-		printf("Data not expected\n");
++		fprintf(stderr, "Data not expected\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		printf("Not expected another recordset\n");
++		fprintf(stderr, "Not expected another recordset\n");
+ 		exit(1);
+ 	}
+ 
+@@ -44,23 +35,17 @@ Test(int use_indicator)
+ 	strcpy(buf, "sysobjects");
+ 	ind = strlen(buf);
+ 
+-	if (SQLExecute(Statement) != SQL_SUCCESS) {
+-		printf("Unable to execute statement\n");
+-		exit(1);
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+-	if (SQLFetch(Statement) != SQL_SUCCESS) {
+-		printf("Data expected\n");
+-		exit(1);
+-	}
++	CHK(SQLFetch, (Statement));
+ 
+ 	if (SQLFetch(Statement) != SQL_NO_DATA) {
+-		printf("Data not expected\n");
++		fprintf(stderr, "Data not expected\n");
+ 		exit(1);
+ 	}
+ 
+ 	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		printf("Not expected another recordset\n");
++		fprintf(stderr, "Not expected another recordset\n");
+ 		exit(1);
+ 	}
+ }
+diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c
+index 011a377..671ef79 100644
+--- a/src/odbc/unittests/tables.c
++++ b/src/odbc/unittests/tables.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: tables.c,v 1.13 2007/07/03 15:13:55 freddy77 Exp $";
++static char software_version[] = "$Id: tables.c,v 1.14 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef WIN32
+@@ -15,11 +15,7 @@ static void
+ ReadCol(int i)
+ {
+ 	strcpy(output, "NULL");
+-	if (SQLGetData(Statement, i, SQL_C_CHAR, output, sizeof(output), &cnamesize) != SQL_SUCCESS) {
+-		printf("Unable to get data col %d\n", i);
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHK(SQLGetData, (Statement, i, SQL_C_CHAR, output, sizeof(output), &cnamesize));
+ }
+ 
+ static void
+@@ -28,12 +24,9 @@ TestName(int index, const char *expected_name)
+ 	char name[128];
+ 	char buf[256];
+ 	SQLSMALLINT len, type;
+-	SQLRETURN rc;
+ 
+ #define NAME_TEST \
+ 	do { \
+-		if (rc != SQL_SUCCESS) \
+-			ODBC_REPORT_ERROR("SQLDescribeCol failed"); \
+ 		if (strcmp(name, expected_name) != 0) \
+ 		{ \
+ 			sprintf(buf, "wrong name in column %d expected '%s' got '%s'", index, expected_name, name); \
+@@ -42,14 +35,14 @@ TestName(int index, const char *expected_name)
+ 	} while(0)
+ 
+ 	/* retrieve with SQLDescribeCol */
+-	rc = SQLDescribeCol(Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL);
++	CHK(SQLDescribeCol, (Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL));
+ 	NAME_TEST;
+ 
+ 	/* retrieve with SQLColAttribute */
+-	rc = SQLColAttribute(Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL);
++	CHK(SQLColAttribute, (Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL));
+ 	if (db_is_microsoft())
+ 		NAME_TEST;
+-	rc = SQLColAttribute(Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL);
++	CHK(SQLColAttribute, (Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL));
+ 	NAME_TEST;
+ }
+ 
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index f29e745..8d0dd75 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,13 +1,9 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.3 2008/01/26 21:47:26 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.4 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHK(func,params) \
+-	if (func params != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func)
+-
+ /*
+ set ipd processed_ptr with
+ SQLParamOptions/SQLSetDescField/SQL_ATTR_PARAMS_PROCESSED_PTR
+diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c
+index a1b7385..f8a7ddf 100644
+--- a/src/odbc/unittests/timeout.c
++++ b/src/odbc/unittests/timeout.c
+@@ -3,27 +3,19 @@
+ 
+ /* Test timeout of query */
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.7 2007/11/26 18:12:31 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.8 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ AutoCommit(int onoff)
+ {
+-	SQLRETURN ret;
+-
+-	ret = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0);
+-	if (ret != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Enabling AutoCommit");
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0));
+ }
+ 
+ static void
+ EndTransaction(SQLSMALLINT type)
+ {
+-	SQLRETURN ret;
+-
+-	ret = SQLEndTran(SQL_HANDLE_DBC, Connection, type);
+-	if (ret != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Can't commit transaction");
++	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, type));
+ }
+ 
+ int
+@@ -58,17 +50,12 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+-	ret = SQLSetStmtAttr(Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0);
+-	if (ret != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Error setting timeout");
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
+ 
+ 	i = 1;
+-	ret = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &i, 0, NULL);
+-	if (ret != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLBindParameter failure");
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &i, 0, NULL));
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) "update test_timeout set t = 'bad' where n = ?", SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("SQLPrepare failure");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "update test_timeout set t = 'bad' where n = ?", SQL_NTS));
+ 	ret = SQLExecute(Statement);
+ 	if (ret != SQL_ERROR)
+ 		ODBC_REPORT_ERROR("SQLExecute success ??");
+diff --git a/src/odbc/unittests/timeout2.c b/src/odbc/unittests/timeout2.c
+index 3cded35..1c61565 100644
+--- a/src/odbc/unittests/timeout2.c
++++ b/src/odbc/unittests/timeout2.c
+@@ -14,17 +14,13 @@
+  * Test from Ou Liu, cf "Query Time Out", 2006-08-08
+  */
+ 
+-static char software_version[] = "$Id: timeout2.c,v 1.4 2007/06/27 14:52:25 freddy77 Exp $";
++static char software_version[] = "$Id: timeout2.c,v 1.5 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if defined(__MINGW32__) || defined(WIN32)
+ #define sleep(s) Sleep((s)*1000)
+ #endif
+ 
+-#define CHK(func,params) \
+-	if (func params != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func)
+-
+ int
+ main(int argc, char *argv[])
+ {
+diff --git a/src/odbc/unittests/timeout4.c b/src/odbc/unittests/timeout4.c
+index 3738dc8..be9c6f9 100644
+--- a/src/odbc/unittests/timeout4.c
++++ b/src/odbc/unittests/timeout4.c
+@@ -39,7 +39,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: timeout4.c,v 1.1 2007/04/20 09:15:06 freddy77 Exp $";
++static char software_version[] = "$Id: timeout4.c,v 1.2 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -91,9 +91,7 @@ Test(int direct)
+ 		return 1;
+ 	}
+ 
+-	ret = SQLSetStmtAttr(Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER);
+-	if (ret != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Error setting timeout");
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER));
+ 
+ 	alarm(30);
+ 	start_time = time(NULL);
+diff --git a/src/odbc/unittests/transaction.c b/src/odbc/unittests/transaction.c
+index a166f63..e7b507a 100644
+--- a/src/odbc/unittests/transaction.c
++++ b/src/odbc/unittests/transaction.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: transaction.c,v 1.12 2006/08/13 13:03:19 freddy77 Exp $";
++static char software_version[] = "$Id: transaction.c,v 1.13 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int
+@@ -27,96 +27,48 @@ Test(int discard_test)
+ 	/* create stored proc */
+ 	CommandWithResult(Statement, "DROP PROCEDURE testinsert");
+ 
+-	result = CommandWithResult(Statement, createProcedure);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't create proc testinsert");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	Command(Statement, createProcedure);
+ 
+ 	/* create stored proc that generates an error */
+ 	CommandWithResult(Statement, "DROP PROCEDURE testerror");
+ 
+-	result = CommandWithResult(Statement, createErrorProcedure);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't create proc testerror");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	Command(Statement, createErrorProcedure);
+ 
+ 	/* Start transaction */
+-	result = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't start transaction");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0));
+ 
+ 	/* Insert a value */
+ 	Command(Statement, "EXEC testinsert 1");
+ 
+ 	/* we should be able to read row count */
+-	if (SQLRowCount(Statement, &rows) != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't get row counts");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHK(SQLRowCount, (Statement, &rows));
+ 
+ 	/* Commit transaction */
+-	result = SQLEndTran(SQL_HANDLE_DBC, Connection, SQL_COMMIT);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't commit transaction");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, SQL_COMMIT));
+ 
+ 	SQLCloseCursor(Statement);
+ 
+ 	/* Start transaction */
+-	result = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't start transaction");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0));
+ 
+ 	/* Insert another value */
+ 	Command(Statement, "EXEC testinsert 2");
+ 
+ 	/* Roll back transaction */
+-	result = SQLEndTran(SQL_HANDLE_DBC, Connection, SQL_ROLLBACK);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't roll back transaction");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, SQL_ROLLBACK));
+ 
+ 	/* TODO test row inserted */
+ 
+-	result = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0);
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't stop transaction");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0));
+ 
+ 	/* generate an error */
+-	result = CommandWithResult(Statement, "EXEC testerror");
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("error: SQLExecDirect: testerror");
+-		retcode = 1;
+-		goto cleanup;
+-	}
+-	if (SQLBindCol(Statement, 1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len) != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("error: SQLBindCol: testerror");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	Command(Statement, "EXEC testerror");
++	CHK(SQLBindCol, (Statement, 1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len));
+ 
+ 	while ((result = SQLFetch(Statement)) == SQL_SUCCESS) {
+ 		printf("\t%ld\n", (long int) out_buf);
+ 		if (out_buf != 1) {
+-			printf("error: expected to select 1 got %ld\n", (long int) out_buf);
++			fprintf(stderr, "error: expected to select 1 got %ld\n", (long int) out_buf);
+ 			retcode = 1;
+ 			goto cleanup;
+ 		}
+@@ -131,7 +83,7 @@ Test(int discard_test)
+ 	printf("SQLMoreResults returned %d\n", result);
+ 
+ 	if (result != SQL_ERROR) {
+-		printf("SQLMoreResults should return error\n");
++		fprintf(stderr, "SQLMoreResults should return error\n");
+ 		retcode = 1;
+ 		goto cleanup;
+ 	}
+@@ -147,7 +99,7 @@ Test(int discard_test)
+ 	result = SQLMoreResults(Statement);
+ 	printf("SQLMoreResults returned %d\n", result);
+ 	if (result != SQL_NO_DATA) {
+-		printf("SQLMoreResults should return error");
++		fprintf(stderr, "SQLMoreResults should return error");
+ 		retcode = 1;
+ 		goto cleanup;
+ 	}
+@@ -163,26 +115,19 @@ Test(int discard_test)
+ int
+ main(int argc, char *argv[])
+ {
+-	int result;
+ 	int retcode = 0;
+ 
+ 	Connect();
+ 
+ 	/* create table */
+ 	CommandWithResult(Statement, "DROP TABLE TestTransaction");
+-	result = CommandWithResult(Statement, "CREATE TABLE TestTransaction ( value INT )");
+-	if (result != SQL_SUCCESS) {
+-		ODBC_REPORT_ERROR("Can't create table TestTransaction");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	Command(Statement, "CREATE TABLE TestTransaction ( value INT )");
+ 
+ 	if (!retcode)
+ 		retcode = Test(1);
+ 	if (!retcode)
+ 		retcode = Test(0);
+ 
+-      cleanup:
+ 	/* drop table */
+ 	CommandWithResult(Statement, "DROP TABLE TestTransaction");
+ 
+diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c
+index cae15e5..c9539c9 100644
+--- a/src/odbc/unittests/typeinfo.c
++++ b/src/odbc/unittests/typeinfo.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: typeinfo.c,v 1.8 2007/07/03 15:13:55 freddy77 Exp $";
++static char software_version[] = "$Id: typeinfo.c,v 1.9 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -9,12 +9,9 @@ TestName(int index, const char *expected_name)
+ 	char name[128];
+ 	char buf[256];
+ 	SQLSMALLINT len, type;
+-	SQLRETURN rc;
+ 
+ #define NAME_TEST \
+ 	do { \
+-		if (rc != SQL_SUCCESS) \
+-			ODBC_REPORT_ERROR("SQLDescribeCol failed"); \
+ 		if (strcmp(name, expected_name) != 0) \
+ 		{ \
+ 			sprintf(buf, "wrong name in column %d expected '%s' got '%s'", index, expected_name, name); \
+@@ -23,14 +20,14 @@ TestName(int index, const char *expected_name)
+ 	} while(0)
+ 
+ 	/* retrieve with SQLDescribeCol */
+-	rc = SQLDescribeCol(Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL);
++	CHK(SQLDescribeCol, (Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL));
+ 	NAME_TEST;
+ 
+ 	/* retrieve with SQLColAttribute */
+-	rc = SQLColAttribute(Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL);
++	CHK(SQLColAttribute, (Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL));
+ 	if (db_is_microsoft())
+ 		NAME_TEST;
+-	rc = SQLColAttribute(Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL);
++	CHK(SQLColAttribute, (Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL));
+ 	NAME_TEST;
+ }
+ 
+diff --git a/src/odbc/unittests/warning.c b/src/odbc/unittests/warning.c
+index 05f3353..741a250 100644
+--- a/src/odbc/unittests/warning.c
++++ b/src/odbc/unittests/warning.c
+@@ -14,7 +14,7 @@
+  * inside recordset
+  * Sybase do not return warning but test works the same
+  */
+-static char software_version[] = "$Id: warning.c,v 1.5 2007/05/17 13:11:56 freddy77 Exp $";
++static char software_version[] = "$Id: warning.c,v 1.6 2008/01/29 14:30:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char one_null_with_warning[] = "select max(a) as foo from (select convert(int, null) as a) as test";
+@@ -30,15 +30,9 @@ Test(const char *query)
+ {
+ 	int res;
+ 
+-	if (SQLPrepare(Statement, (SQLCHAR *) query, SQL_NTS) != SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to prepare statement\n");
+-		exit(1);
+-	}
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) query, SQL_NTS));
+ 
+-	if (SQLExecute(Statement) != SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to execute statement\n");
+-		exit(1);
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+ 	res = SQLFetch(Statement);
+ 	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
+
+commit d49abfe40b4b73fc27676fcd5ef742493cdda99a
+Author: freddy77 <freddy77>
+Date:   Thu Jan 31 09:13:05 2008 +0000
+
+    reuse code
+
+diff --git a/ChangeLog b/ChangeLog
+index 800bfc2..0e5bc0f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jan 21 10:12:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/convert_error.c src/odbc/unittests/genparams.c:
++	- more reuse
++
+ Tue Jan 29 15:28:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/array_out.c src/odbc/unittests/common.c:
+ 	* src/odbc/unittests/common.h src/odbc/unittests/compute.c:
+@@ -128,4 +132,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2480 2008/01/29 14:30:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2481 2008/01/31 09:13:05 freddy77 Exp $
+diff --git a/src/odbc/unittests/convert_error.c b/src/odbc/unittests/convert_error.c
+index 29c8c93..68a70ef 100644
+--- a/src/odbc/unittests/convert_error.c
++++ b/src/odbc/unittests/convert_error.c
+@@ -4,33 +4,11 @@
+  */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: convert_error.c,v 1.7 2005/08/03 06:24:50 freddy77 Exp $";
++static char software_version[] = "$Id: convert_error.c,v 1.8 2008/01/31 09:13:08 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int test_num = 0;
+ 
+-static int
+-success(int ident, SQLRETURN r)
+-{
+-	if (r == SQL_SUCCESS || r == SQL_SUCCESS_WITH_INFO)
+-		return 1;
+-	printf("failed: num:%d ident:%d sqlreturn:%d\n", test_num, ident, (int) r);
+-
+-	if (Statement) {
+-		SQLCHAR buf[4096];
+-		SQLCHAR state[6];
+-		SQLINTEGER nativeerrorcode;
+-		SQLSMALLINT tmp;
+-
+-		memset(state, 0, sizeof(state));
+-		memset(buf, 0, sizeof(buf));
+-		SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, state, &nativeerrorcode, buf, 4096, &tmp);
+-		printf("%s\n", buf);
+-	}
+-	Disconnect();
+-	exit(1);
+-}
+-
+ static void
+ Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2)
+ {
+@@ -44,14 +22,13 @@ Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2)
+ 	++test_num;
+ 	sprintf(sql, "insert into #test_output values (%s, %s)", bind1, bind2);
+ 
+-	success(2, SQLPrepare(Statement, (SQLCHAR *) sql, strlen(sql)));
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) sql, strlen(sql)));
+ 	if (bind1[0] == '?')
+-		success(3, SQLBindParameter(Statement, id++, SQL_PARAM_INPUT, SQL_C_LONG, type1, 3, 0, &test_num, 0, &ind));
++		CHK(SQLBindParameter, (Statement, id++, SQL_PARAM_INPUT, SQL_C_LONG, type1, 3, 0, &test_num, 0, &ind));
+ 	if (bind2[0] == '?')
+-		success(4,
+-			SQLBindParameter(Statement, id++, SQL_PARAM_INPUT, SQL_C_CHAR, type2, strlen(val) + 1, 0, (SQLCHAR *) val,
++		CHK(SQLBindParameter, (Statement, id++, SQL_PARAM_INPUT, SQL_C_CHAR, type2, strlen(val) + 1, 0, (SQLCHAR *) val,
+ 					 0, &ind));
+-	success(5, SQLExecute(Statement));
++	CHK(SQLExecute, (Statement));
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 9eb1b4f..96f153b 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.24 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.25 2008/01/31 09:13:08 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -124,10 +124,8 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 
+ 	if (use_cursors) {
+ 		ResetStatement();
+-		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLSetStmtAttr error");
+-		if (SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLSetStmtAttr error");
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0));
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
+ 	}
+ 
+ 	/* insert data using prepared statements */
+@@ -136,9 +134,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		SQLRETURN rc;
+ 
+ 		out_len = 1;
+-		if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len) !=
+-		    SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Unable to bind input parameter");
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
+ 
+ 		rc = SQLExecDirect(Statement, (SQLCHAR *) sbuf, SQL_NTS);
+ 		if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
+
+commit d55aa0695496bec96daf4d7fb01a91431e0462b5
+Author: freddy77 <freddy77>
+Date:   Mon Feb 4 07:51:10 2008 +0000
+
+    fix silly memory leak
+
+diff --git a/ChangeLog b/ChangeLog
+index 0e5bc0f..8256c3a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Feb 04 08:49:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: fix silly memory leak
++
+ Thu Jan 21 10:12:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/convert_error.c src/odbc/unittests/genparams.c:
+ 	- more reuse
+@@ -132,4 +135,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2481 2008/01/31 09:13:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2482 2008/02/04 07:51:10 freddy77 Exp $
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index fa8dbd1..67ea545 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.179 2007/12/31 10:06:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.180 2008/02/04 07:51:11 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -1958,6 +1958,7 @@ string_to_datetime(const char *instr, int desttype, CONV_RESULT * cr)
+ 
+ 			tdsdump_log(TDS_DBG_INFO1,
+ 				    "error_handler:  Attempt to convert data stopped by syntax error in source field \n");
++			free(in);
+ 			return TDS_CONVERT_SYNTAX;
+ 		}
+ 
+
+commit 18dedd394149a835f6f90602af7c56cdc9482a10
+Author: freddy77 <freddy77>
+Date:   Tue Feb 5 09:46:33 2008 +0000
+
+    deal with SQLWCHAR type
+
+diff --git a/src/odbc/sqlwchar.c b/src/odbc/sqlwchar.c
+new file mode 100644
+index 0000000..61eb5a7
+--- /dev/null
++++ b/src/odbc/sqlwchar.c
+@@ -0,0 +1,40 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2008  Ziglio Frediano
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif /* HAVE_CONFIG_H */
++
++#include <stdarg.h>
++#include <stdio.h>
++
++#include "tdsodbc.h"
++
++TDS_RCSID(var, "$Id: sqlwchar.c,v 1.1 2008/02/05 09:46:33 freddy77 Exp $");
++
++#if SIZEOF_SQLWCHAR != SIZEOF_WCHAR_T
++size_t sqlwcslen(const SQLWCHAR * s)
++{
++	size_t res = 0;
++	while (*s)
++		++s, ++res;
++	return res;
++}
++#endif
++
+
+commit 1f108b0482cd647bb38ad17a0bed1b301682b06a
+Author: freddy77 <freddy77>
+Date:   Tue Feb 5 10:03:57 2008 +0000
+
+    test NCHAR and SQL_C_DEFAULT
+
+diff --git a/src/odbc/unittests/wchar.c b/src/odbc/unittests/wchar.c
+new file mode 100644
+index 0000000..92bb084
+--- /dev/null
++++ b/src/odbc/unittests/wchar.c
+@@ -0,0 +1,38 @@
++#include "common.h"
++
++/* test SQL_C_DEFAULT with NCHAR type */
++
++static char software_version[] = "$Id: wchar.c,v 1.1 2008/02/05 10:03:57 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++int
++main(int argc, char *argv[])
++{
++	char buf[102];
++	SQLLEN ind;
++	int failed = 0;
++
++	/* TODO remove if not neeeded */
++	use_odbc_version3 = 1;
++	Connect();
++
++	SQLBindCol(Statement, 1, SQL_C_DEFAULT, buf, 100, &ind);
++	Command(Statement, "SELECT CONVERT(NCHAR(10), 'Pippo 123')");
++
++	/* get data */
++	memset(buf, 0, sizeof(buf));
++	SQLFetch(Statement);
++
++	SQLMoreResults(Statement);
++	SQLMoreResults(Statement);
++
++	Disconnect();
++
++	if (strcmp(buf, "Pippo 123 ") != 0) {
++		fprintf(stderr, "Wrong results '%s'\n", buf);
++		failed = 1;
++	}
++
++	return failed ? 1 : 0;
++}
++
+
+commit 332bf81cc62288f01164db84b316a01f7e8bce8f
+Author: freddy77 <freddy77>
+Date:   Tue Feb 5 15:01:28 2008 +0000
+
+    conversion test improve
+
+diff --git a/ChangeLog b/ChangeLog
+index 8256c3a..f167c34 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Feb 05 15:59:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/t0007.c:
++	- improve SYBINT8 conversions testing
++
+ Mon Feb 04 08:49:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/convert.c: fix silly memory leak
+ 
+@@ -135,4 +139,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2482 2008/02/04 07:51:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2483 2008/02/05 15:01:28 freddy77 Exp $
+diff --git a/src/tds/unittests/t0007.c b/src/tds/unittests/t0007.c
+index d867fbe..1c20101 100644
+--- a/src/tds/unittests/t0007.c
++++ b/src/tds/unittests/t0007.c
+@@ -20,7 +20,7 @@
+ #include "common.h"
+ #include <tdsconvert.h>
+ 
+-static char software_version[] = "$Id: t0007.c,v 1.14 2006/06/08 08:19:05 freddy77 Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.15 2008/02/05 15:01:29 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static TDSCONTEXT ctx;
+@@ -39,6 +39,7 @@ test0(const char *src, int len, int dsttype, const char *result)
+ 	if (res < 0)
+ 		strcpy(buf, "error");
+ 	else {
++		buf[0] = 0;
+ 		switch (dsttype) {
+ 		case SYBINT1:
+ 			sprintf(buf, "%d", cr.ti);
+@@ -49,6 +50,9 @@ test0(const char *src, int len, int dsttype, const char *result)
+ 		case SYBINT4:
+ 			sprintf(buf, "%d", cr.i);
+ 			break;
++		case SYBINT8:
++			sprintf(buf, "0x%08x%08x", (unsigned int) ((cr.bi >> 32) & 0xfffffffflu), (unsigned int) (cr.bi & 0xfffffffflu));
++			break;
+ 		case SYBUNIQUE:
+ 			sprintf(buf, "%08X-%04X-%04X-%02X%02X%02X%02X"
+ 				"%02X%02X%02X%02X",
+@@ -92,9 +96,42 @@ main(int argc, char **argv)
+ 	test("123", SYBINT1, "123");
+ 	test("  -    1234   ", SYBINT2, "-1234");
+ 	test("  -    1234   a", SYBINT2, "error");
++	test("", SYBINT4, "0");
++	test("    ", SYBINT4, "0");
++	test("    123", SYBINT4, "123");
++	test("    123    ", SYBINT4, "123");
++	test("  +  123  ", SYBINT4, "123");
++	test("+", SYBINT4, "error");
++	test("   +", SYBINT4, "error");
++	test("+   ", SYBINT4, "error");
++	test("   +   ", SYBINT4, "error");
++	test("-", SYBINT4, "error");
++	test("   -", SYBINT4, "error");
++	test("-   ", SYBINT4, "error");
++	test("   -   ", SYBINT4, "error");
++
++	test("  -    1234   ", SYBINT8, "0xfffffffffffffb2e");
++	test("  -    1234   a", SYBINT8, "error");
++	test("", SYBINT8, "0x0000000000000000");
++	test("    ", SYBINT8, "0x0000000000000000");
++	test("    123", SYBINT8, "0x000000000000007b");
++	test("    123    ", SYBINT8, "0x000000000000007b");
++	test("  +  123  ", SYBINT8, "0x000000000000007b");
++	test("+", SYBINT8, "error");
++	test("   +", SYBINT8, "error");
++	test("+   ", SYBINT8, "error");
++	test("   +   ", SYBINT8, "error");
++	test("-", SYBINT8, "error");
++	test("   -", SYBINT8, "error");
++	test("-   ", SYBINT8, "error");
++	test("   -   ", SYBINT8, "error");
+ 
+ 	/* test for overflow */
+ 	printf("overflow checks...\n");
++	test("9223372036854775807", SYBINT8, "0x7fffffffffffffff");
++	test("9223372036854775808", SYBINT8, "error");
++	test("-9223372036854775808", SYBINT8, "0x8000000000000000");
++	test("-9223372036854775809", SYBINT8, "error");
+ 	test("2147483647", SYBINT4, "2147483647");
+ 	test("2147483648", SYBINT4, "error");
+ 	test("-2147483648", SYBINT4, "-2147483648");
+@@ -121,6 +158,7 @@ main(int argc, char **argv)
+ 
+ 	/* test not terminated string */
+ 	test0("1234", 2, SYBINT4, "12");
++	test0("123456", 4, SYBINT8, "0x00000000000004d2");
+ 
+ 	/* some test for unique */
+ 	printf("unique type...\n");
+
+commit 21dd3e0ae79e8b08d30c0553d19c359127307cc1
+Author: freddy77 <freddy77>
+Date:   Wed Feb 6 08:28:10 2008 +0000
+
+    use printf instead of fprintf(stdout...)
+
+diff --git a/ChangeLog b/ChangeLog
+index f167c34..d6e621a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Feb 06 09:27:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/rpc.c src/odbc/unittests/cursor5.c:
++	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor3.c:
++	- use printf instead of fprintf(stdout...)
++
+ Tue Feb 05 15:59:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/unittests/t0007.c:
+ 	- improve SYBINT8 conversions testing
+@@ -139,4 +144,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2483 2008/02/05 15:01:28 freddy77 Exp $
++$Id: ChangeLog,v 1.2484 2008/02/06 08:28:10 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index 6ef62c8..5a6849f 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,7 +1,7 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.5 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.6 2008/02/06 08:28:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -126,14 +126,14 @@ main(int argc, char **argv)
+ 
+ 	rcode = SQLGetData(m_hstmt1, 2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLGetData 1");
+-	fprintf(stdout, ">> Fetch from 1: [%s]\n", buff);
++	printf(">> Fetch from 1: [%s]\n", buff);
+ 
+ 	rcode = SQLFetch(m_hstmt2);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLFetch 2");
+ 
+ 	rcode = SQLGetData(m_hstmt2, 2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLGetData 2");
+-	fprintf(stdout, ">> Fetch from 2: [%s]\n", buff);
++	printf(">> Fetch from 2: [%s]\n", buff);
+ 
+ 	rcode = SQLCloseCursor(m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLCloseCursor 1");
+diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c
+index 363ebfd..c1ac6cd 100755
+--- a/src/odbc/unittests/cursor4.c
++++ b/src/odbc/unittests/cursor4.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.5 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.6 2008/02/06 08:28:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -108,7 +108,7 @@ main(int argc, char **argv)
+ 	rcode = SQLGetData(m_hstmt1, 1, SQL_C_CHAR, buff, sizeof(buff), &ind);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLGetData");
+ 
+-	fprintf(stdout, ">> New value after update = [%s] (should be [xxx]) \n", buff);
++	printf(">> New value after update = [%s] (should be [xxx]) \n", buff);
+ 
+ 	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle 1");
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index d8c4540..9b300f5 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.5 2008/02/06 08:28:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -47,9 +47,9 @@ doFetch(SQLHSTMT m_hstmt, int dir, int pos)
+ 
+ 	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFetchScroll");
+ 	if (rcode != SQL_NO_DATA)
+-		fprintf(stdout, ">> fetch %2d %10d : %d [%s]\n", dir, pos, v_ind_3_1 ? (int) v_int_3 : -1, v_ind_3_2 ? v_char_3 : "null");
++		printf(">> fetch %2d %10d : %d [%s]\n", dir, pos, v_ind_3_1 ? (int) v_int_3 : -1, v_ind_3_2 ? v_char_3 : "null");
+ 	else
+-		fprintf(stdout, ">> fetch %2d %10d : no data found\n", dir, pos);
++		printf(">> fetch %2d %10d : no data found\n", dir, pos);
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c
+index 5543dd4..23d8436 100644
+--- a/src/odbc/unittests/rpc.c
++++ b/src/odbc/unittests/rpc.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.8 2007/11/26 06:25:11 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.9 2008/02/06 08:28:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char procedure_sql[] = 
+@@ -38,7 +38,7 @@ init_proc(const char *name)
+ 	static char cmd[4096];
+ 
+ 	if (name[0] != '#') {
+-		fprintf(stdout, "Dropping procedure %s\n", name);
++		printf("Dropping procedure %s\n", name);
+ 		sprintf(cmd, "if exists (select 1 from sysobjects where name = '%s' and type = 'P') "
+ 				"DROP PROCEDURE %s", name, name);
+ 		if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) cmd, SQL_NTS))) {
+@@ -47,14 +47,14 @@ init_proc(const char *name)
+ 		}
+ 	}
+ 
+-	fprintf(stdout, "Creating procedure %s\n", name);
++	printf("Creating procedure %s\n", name);
+ 	sprintf(cmd, procedure_sql, name);
+ 
+ 	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) cmd, SQL_NTS))) {
+ 		if (name[0] == '#')
+-			fprintf(stdout, "Failed to create procedure %s. Wrong permission or not MSSQL.\n", name);
++			printf("Failed to create procedure %s. Wrong permission or not MSSQL.\n", name);
+ 		else
+-			fprintf(stdout, "Failed to create procedure %s. Wrong permission.\n", name);
++			printf("Failed to create procedure %s. Wrong permission.\n", name);
+ 		CheckReturn();
+ 		exit(1);
+ 	}
+
+commit 33ba1e2143a8cdf5a80e28dc0b3e1641d1190c2c
+Author: freddy77 <freddy77>
+Date:   Wed Feb 6 08:29:53 2008 +0000
+
+    simplify test
+
+diff --git a/ChangeLog b/ChangeLog
+index d6e621a..49811a7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Feb 06 09:28:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/testodbc.c: simplify
++
+ Wed Feb 06 09:27:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/rpc.c src/odbc/unittests/cursor5.c:
+ 	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor3.c:
+@@ -144,4 +147,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2484 2008/02/06 08:28:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2485 2008/02/06 08:29:53 freddy77 Exp $
+diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c
+index c800bcb..5ab9325 100644
+--- a/src/odbc/unittests/testodbc.c
++++ b/src/odbc/unittests/testodbc.c
+@@ -10,7 +10,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: testodbc.c,v 1.9 2005/06/29 07:21:24 freddy77 Exp $";
++static char software_version[] = "$Id: testodbc.c,v 1.10 2008/02/06 08:29:53 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef DEBUG
+@@ -40,25 +40,25 @@ typedef struct
+  * Output ODBC errors.
+  */
+ static void
+-DispODBCErrs(SQLHENV envHandle, SQLHDBC connHandle, SQLHSTMT statementHandle)
++DispODBCErrs(void)
+ {
+ 	SQLCHAR buffer[256];
+ 	SQLCHAR sqlState[16];
+ 
+ 	/* Statement errors */
+-	if (statementHandle) {
+-		while (SQLError(envHandle, connHandle, statementHandle, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
++	if (Statement) {
++		while (SQLError(Environment, Connection, Statement, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
+ 			AB_ERROR(("%s, SQLSTATE=%s", buffer, sqlState));
+ 		}
+ 	}
+ 
+ 	/* Connection errors */
+-	while (SQLError(envHandle, connHandle, SQL_NULL_HSTMT, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
++	while (SQLError(Environment, Connection, SQL_NULL_HSTMT, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
+ 		AB_ERROR(("%s, SQLSTATE=%s", buffer, sqlState));
+ 	}
+ 
+ 	/* Environmental errors */
+-	while (SQLError(envHandle, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
++	while (SQLError(Environment, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
+ 		AB_ERROR(("%s, SQLSTATE=%s", buffer, sqlState));
+ 	}
+ }
+@@ -67,7 +67,7 @@ DispODBCErrs(SQLHENV envHandle, SQLHDBC connHandle, SQLHSTMT statementHandle)
+  * Output ODBC diagnostics. Only used for 'raw' ODBC tests.
+  */
+ static void
+-DispODBCDiags(SQLHSTMT statementHandle)
++DispODBCDiags(void)
+ {
+ 	SQLSMALLINT recNumber;
+ 	SQLCHAR sqlState[10];
+@@ -82,7 +82,7 @@ DispODBCDiags(SQLHSTMT statementHandle)
+ 	AB_FUNCT(("DispODBCDiags (in)"));
+ 
+ 	do {
+-		status = SQLGetDiagRec(SQL_HANDLE_STMT, statementHandle, recNumber,
++		status = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, recNumber,
+ 				       sqlState, &nativeError, messageText, bufferLength, &textLength);
+ 		if (status != SQL_SUCCESS) {
+ 			/* No data mean normal end of iteration. Anything else is error. */
+@@ -137,13 +137,13 @@ TestRawODBCPreparedQuery(void)
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(12,'Queso Manchego La Pastora',5,4,'10 - 500 g pkgs.',38.00,86,0,0,0)");
+ 	while (SQLMoreResults(Statement) == SQL_SUCCESS);
+ 
+-	strcpy((char *) (queryString), "SELECT * FROM #Products WHERE SupplierID = ?");
++	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+ 
+ 	status = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("SQLBindParameter failed"));
+-		DispODBCErrs(Environment, Connection, Statement);
+-		DispODBCDiags(Statement);
++		DispODBCErrs();
++		DispODBCDiags();
+ 		AB_FUNCT(("TestRawODBCPreparedQuery (out): error"));
+ 		return FALSE;
+ 	}
+@@ -158,8 +158,8 @@ TestRawODBCPreparedQuery(void)
+ 	status = SQLExecute(Statement);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("Execute failed"));
+-		DispODBCErrs(Environment, Connection, Statement);
+-		DispODBCDiags(Statement);
++		DispODBCErrs();
++		DispODBCDiags();
+ 		AB_FUNCT(("TestRawODBCPreparedQuery (out): error"));
+ 		return FALSE;
+ 	}
+@@ -228,13 +228,13 @@ TestRawODBCDirectQuery(void)
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(5,'Chef Anton''s Gumbo Mix',2,2,'36 boxes',21.35,0,0,0,1) ");
+ 	while (SQLMoreResults(Statement) == SQL_SUCCESS);
+ 
+-	strcpy((char *) (queryString), "SELECT * FROM #Products WHERE SupplierID = ?");
++	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+ 
+ 	status = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("SQLBindParameter failed"));
+-		DispODBCErrs(Environment, Connection, Statement);
+-		DispODBCDiags(Statement);
++		DispODBCErrs();
++		DispODBCDiags();
+ 		AB_FUNCT(("TestRawODBCDirectQuery (out): error"));
+ 		return FALSE;
+ 	}
+@@ -242,8 +242,8 @@ TestRawODBCDirectQuery(void)
+ 	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("Execute failed"));
+-		DispODBCErrs(Environment, Connection, Statement);
+-		DispODBCDiags(Statement);
++		DispODBCErrs();
++		DispODBCDiags();
+ 		AB_FUNCT(("TestRawODBCDirectQuery (out): error"));
+ 		return FALSE;
+ 	}
+@@ -581,8 +581,8 @@ TestRawODBCGuid(void)
+ 	return TRUE;
+ 
+       odbcfail:
+-	DispODBCErrs(Environment, Connection, Statement);
+-	DispODBCDiags(Statement);
++	DispODBCErrs();
++	DispODBCDiags();
+ 	AB_FUNCT(("TestRawODBCGuid (out): error"));
+ 	return FALSE;
+ }
+
+commit d7c53b3a37cdfc0160316ccfb2f86d0668b2fbbd
+Author: freddy77 <freddy77>
+Date:   Thu Feb 7 22:05:36 2008 +0000
+
+    improve bigint test
+
+diff --git a/src/tds/unittests/t0007.c b/src/tds/unittests/t0007.c
+index 1c20101..161280b 100644
+--- a/src/tds/unittests/t0007.c
++++ b/src/tds/unittests/t0007.c
+@@ -20,7 +20,7 @@
+ #include "common.h"
+ #include <tdsconvert.h>
+ 
+-static char software_version[] = "$Id: t0007.c,v 1.15 2008/02/05 15:01:29 freddy77 Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.16 2008/02/07 22:05:36 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static TDSCONTEXT ctx;
+@@ -111,6 +111,7 @@ main(int argc, char **argv)
+ 	test("   -   ", SYBINT4, "error");
+ 
+ 	test("  -    1234   ", SYBINT8, "0xfffffffffffffb2e");
++	test("1234x", SYBINT8, "error");
+ 	test("  -    1234   a", SYBINT8, "error");
+ 	test("", SYBINT8, "0x0000000000000000");
+ 	test("    ", SYBINT8, "0x0000000000000000");
+@@ -155,6 +156,10 @@ main(int argc, char **argv)
+ 	test("63147483647", SYBINT4, "error");
+ 	test("64147483647", SYBINT4, "error");
+ 	test("65147483647", SYBINT4, "error");
++	test("53248632876323876761", SYBINT8, "error");
++	test("56248632876323876761", SYBINT8, "error");
++	test("59248632876323876761", SYBINT8, "error");
++	test("12248632876323876761", SYBINT8, "error");
+ 
+ 	/* test not terminated string */
+ 	test0("1234", 2, SYBINT4, "12");
+
+commit 47a97f5e23af4b3281f5f710d0ee14e3541b949f
+Author: freddy77 <freddy77>
+Date:   Fri Feb 8 08:31:19 2008 +0000
+
+    reuse code and macros
+
+diff --git a/ChangeLog b/ChangeLog
+index 49811a7..cc65a1b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb 08 09:30:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/rpc.c: reuse code and macros
++
+ Wed Feb 06 09:28:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/testodbc.c: simplify
+ 
+@@ -147,4 +150,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2485 2008/02/06 08:29:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2486 2008/02/08 08:31:19 freddy77 Exp $
+diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c
+index 23d8436..3b58e29 100644
+--- a/src/odbc/unittests/rpc.c
++++ b/src/odbc/unittests/rpc.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.9 2008/02/06 08:28:10 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.10 2008/02/08 08:31:19 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char procedure_sql[] = 
+@@ -97,8 +97,7 @@ Test(const char *name)
+ 
+ 
+ 	printf("executing SQLAllocStmt\n");
+-	if (SQLAllocStmt(Connection, &stmt) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to allocate statement");
++	CHK(SQLAllocStmt, (Connection, &stmt));
+ 
+ 	for( ipar=0; ipar < sizeof(args)/sizeof(args[0]); ipar++ ) {
+ 		printf("executing SQLBindParameter for parameter %d\n", 1+ipar);
+@@ -108,7 +107,7 @@ Test(const char *name)
+ 			memset(args[ipar].ParameterValuePtr, 0, args[ipar].BufferLength);
+ 			memset(args[ipar].ParameterValuePtr, 'a', args[ipar].BufferLength - 1);
+ 		}
+-		erc = SQLBindParameter	( stmt, 1+ipar
++		CHK(SQLBindParameter,	( stmt, 1+ipar
+ 					, args[ipar].InputOutputType
+ 					, args[ipar].ValueType
+ 					, args[ipar].ParameterType
+@@ -117,58 +116,41 @@ Test(const char *name)
+ 					, args[ipar].ParameterValuePtr
+ 					, args[ipar].BufferLength
+ 					, &args[ipar].ind
+-					);
+-		if (erc != SQL_SUCCESS) {
+-			fprintf(stderr, "Failed: SQLBindParameter\n");
+-			exit(1);
+-		}
++					));
+ 	}
+-		
+-
+ 
+ 	sprintf(call_cmd, "{?=call %s(?,?,?,?,?)}", name );
+ 	printf("executing SQLPrepare: %s\n", call_cmd);
+-	if (SQLPrepare(stmt, (SQLCHAR *) call_cmd, SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to prepare statement");
++	CHK(SQLPrepare, (stmt, (SQLCHAR *) call_cmd, SQL_NTS));
+ 
+ 	printf("executing SQLExecute\n");
+ 	if (! SQL_SUCCEEDED(SQLExecute(stmt))) {
+ 		erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+ 		fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
+ 		ODBC_REPORT_ERROR("Unable to execute SQLExecute\n");
+-		
+ 	}
+ 
+ 	do {
+-		static const char dashes[] = "------------------------------", 
+-				  *dashes5   = &dashes[25], 
+-				  *dashes15  = &dashes[15];
++		static const char dashes[] = "------------------------------";
+ 		int nrows;
+ 		SQLSMALLINT  icol, ncols;
+-                SQLCHAR      name[256] = "";
+-                SQLSMALLINT  namelen;
+-                SQLSMALLINT  type;
+-                SQLSMALLINT  scale;
+-                SQLSMALLINT  nullable;
+-				  
++		SQLCHAR      name[256] = "";
++		SQLSMALLINT  namelen;
++		SQLSMALLINT  type;
++		SQLSMALLINT  scale;
++		SQLSMALLINT  nullable;
++
+ 		printf("executing SQLNumResultCols for result set %d\n", ++iresults);
+-		if((erc = SQLNumResultCols(stmt,  &ncols)) != SQL_SUCCESS) {
+-			ODBC_REPORT_ERROR("Unable to execute SQLNumResultCols\n");
+-		}
++		CHK(SQLNumResultCols, (stmt,  &ncols));
+ 
+ 		printf("executing SQLDescribeCol for %d column%c\n", ncols, (ncols == 1? ' ' : 's'));
+-		printf("%-5s %-15s %5s %5s %5s %8s\n", "col", "name", "type", "size", "scale", "nullable"); 
+-		printf("%-5s %-15s %5s %5s %5s %8s\n", dashes5, dashes15, dashes5, dashes5, dashes5, &dashes[30-8]); 
++		printf("%-5.5s %-15.15s %5.5s %5.5s %5.5s %8.8s\n", "col", "name", "type", "size", "scale", "nullable"); 
++		printf("%-5.5s %-15.15s %5.5s %5.5s %5.5s %8.8s\n", dashes, dashes, dashes, dashes, dashes, dashes); 
+ 		
+ 		for (icol=ncols; icol > 0; icol--) {
+-                	SQLULEN size;
+-			erc = SQLDescribeCol( stmt, icol, name, sizeof(name),
+-						    &namelen, &type, &size, &scale, &nullable);
+-			if (erc != SQL_SUCCESS) {
+-				erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+-				fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
+-				ODBC_REPORT_ERROR("Unable to execute SQLDescribeCol\n");
+-			} 			
++			SQLULEN size;
++			CHK(SQLDescribeCol, (stmt, icol, name, sizeof(name),
++						    &namelen, &type, &size, &scale, &nullable));
+ 			printf("%-5d %-15s %5d %5ld %5d %8c\n", icol, name, type, (long int)size, scale, (nullable? 'Y' : 'N')); 
+ 		}
+ 
+@@ -238,8 +220,7 @@ Test(const char *name)
+ 	}
+ 
+ 	printf("executing SQLFreeStmt\n");
+-	if (SQLFreeStmt(stmt, SQL_DROP) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to free statement");
++	CHK(SQLFreeStmt, (stmt, SQL_DROP));
+ 
+ 	for (ipar = 0; ipar < sizeof(args)/sizeof(args[0]); ++ipar)
+ 		if (args[ipar].BufferLength > 0)
+@@ -268,12 +249,7 @@ main(int argc, char *argv[])
+ 	Test(proc_name);
+ 	
+ 	printf("dropping procedure\n");
+-	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) drop_proc, SQL_NTS))) {
+-		printf("Unable to drop procedure\n");
+-		CheckReturn();
+-		exit(1);
+-	}
+-
++	Command(Statement, drop_proc);
+ 
+ 	Disconnect();
+ 
+
+commit 4c9b9c1626339d75cbf2cc077fbdebd3674408c8
+Author: freddy77 <freddy77>
+Date:   Fri Feb 8 08:33:09 2008 +0000
+
+    *** empty log message ***
+
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index 2aea2d3..fb6855d 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -66,3 +66,4 @@ hidden
+ blob1
+ cancel
+ test64
++wchar
+
+commit 656c4bad229439cc87140c70429165dcfa1881ea
+Author: freddy77 <freddy77>
+Date:   Fri Feb 8 09:28:01 2008 +0000
+
+    more reuse in tests
+
+diff --git a/ChangeLog b/ChangeLog
+index cc65a1b..393b4a0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Fri Feb 08 10:26:36 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/describecol.in:
++	* src/odbc/unittests/params.c src/odbc/unittests/putdata.c:
++	* src/odbc/unittests/raiserror.c src/odbc/unittests/rownumber.c:
++	* src/odbc/unittests/t0001.c src/odbc/unittests/t0002.c:
++	* src/odbc/unittests/testodbc.c src/odbc/unittests/timeout3.c:
++	- more reuse and unification
++
+ Fri Feb 08 09:30:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/rpc.c: reuse code and macros
+ 
+@@ -150,4 +158,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2486 2008/02/08 08:31:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2487 2008/02/08 09:28:01 freddy77 Exp $
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 7fca97b..f9e14f9 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.71 2008/01/10 16:05:59 freddy77 Exp $
++# $Id: Makefile.am,v 1.72 2008/02/08 09:28:03 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -21,7 +21,7 @@ TESTS		=	\
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+-			cancel$(EXEEXT)
++			cancel$(EXEEXT) wchar$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -81,6 +81,7 @@ attributes_SOURCES	= attributes.c common.c common.h
+ hidden_SOURCES	= hidden.c common.c common.h
+ blob1_SOURCES	= blob1.c common.c common.h
+ cancel_SOURCES = cancel.c common.c common.h
++wchar_SOURCES = wchar.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/describecol.in b/src/odbc/unittests/describecol.in
+index aa6a63a..b1aaa7f 100644
+--- a/src/odbc/unittests/describecol.in
++++ b/src/odbc/unittests/describecol.in
+@@ -153,25 +153,21 @@ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 11
+ 
+ select nchar(12) 'hi!'
+-## TODO
+-#attr SQL_COLUMN_LENGTH 24
++attr SQL_COLUMN_LENGTH 24
+ attr SQL_COLUMN_PRECISION 12
+ attr SQL_COLUMN_SCALE 0
+ attr SQL_DESC_LENGTH 12
+-## TODO
+-#attr SQL_DESC_OCTET_LENGTH 24
++attr SQL_DESC_OCTET_LENGTH 24
+ attr SQL_DESC_PRECISION 12
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 12
+ 
+ select nvarchar(13) 'hi!'
+-## TODO
+-#attr SQL_COLUMN_LENGTH 26
++attr SQL_COLUMN_LENGTH 26
+ attr SQL_COLUMN_PRECISION 13
+ attr SQL_COLUMN_SCALE 0
+ attr SQL_DESC_LENGTH 13
+-## TODO
+-#attr SQL_DESC_OCTET_LENGTH 26
++attr SQL_DESC_OCTET_LENGTH 26
+ attr SQL_DESC_PRECISION 13
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 13
+@@ -187,13 +183,11 @@ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 4096
+ 
+ select ntext 'hi!'
+-## TODO
+-#attr SQL_COLUMN_LENGTH 4096
++attr SQL_COLUMN_LENGTH 4096
+ attr SQL_COLUMN_PRECISION 2048
+ attr SQL_COLUMN_SCALE 0
+ attr SQL_DESC_LENGTH 2048
+-## TODO
+-#attr SQL_DESC_OCTET_LENGTH 4096
++attr SQL_DESC_OCTET_LENGTH 4096
+ attr SQL_DESC_PRECISION 2048
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 2048
+@@ -385,25 +379,21 @@ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 11
+ 
+ select nchar(12) 'hi!'
+-## TODO
+-#attr SQL_COLUMN_LENGTH 24
++attr SQL_COLUMN_LENGTH 24
+ attr SQL_COLUMN_PRECISION 12
+ attr SQL_COLUMN_SCALE 0
+ attr SQL_DESC_LENGTH 12
+-## TODO
+-#attr SQL_DESC_OCTET_LENGTH 24
++attr SQL_DESC_OCTET_LENGTH 24
+ attr SQL_DESC_PRECISION 12
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 12
+ 
+ select nvarchar(13) 'hi!'
+-## TODO
+-#attr SQL_COLUMN_LENGTH 26
++attr SQL_COLUMN_LENGTH 26
+ attr SQL_COLUMN_PRECISION 13
+ attr SQL_COLUMN_SCALE 0
+ attr SQL_DESC_LENGTH 13
+-## TODO
+-#attr SQL_DESC_OCTET_LENGTH 26
++attr SQL_DESC_OCTET_LENGTH 26
+ attr SQL_DESC_PRECISION 13
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 13
+@@ -419,13 +409,11 @@ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 4096
+ 
+ select ntext 'hi!'
+-## TODO
+-#attr SQL_COLUMN_LENGTH 4096
++attr SQL_COLUMN_LENGTH 4096
+ attr SQL_COLUMN_PRECISION 2048
+ attr SQL_COLUMN_SCALE 0
+ attr SQL_DESC_LENGTH 2048
+-## TODO
+-#attr SQL_DESC_OCTET_LENGTH 4096
++attr SQL_DESC_OCTET_LENGTH 4096
+ attr SQL_DESC_PRECISION 2048
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 2048
+diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c
+index 191066c..dc382cb 100644
+--- a/src/odbc/unittests/params.c
++++ b/src/odbc/unittests/params.c
+@@ -3,7 +3,7 @@
+ /* Test for store procedure and params */
+ /* Test from Tom Rogers */
+ 
+-static char software_version[] = "$Id: params.c,v 1.8 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: params.c,v 1.9 2008/02/08 09:28:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* SP definition */
+@@ -33,8 +33,7 @@ Test(int bind_before)
+ 	Connect();
+ 
+ 	/* drop proc */
+-	if (CommandWithResult(Statement, "drop proc spTestProc") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
+ 
+ 	/* create proc */
+ 	Command(Statement, sp_define);
+@@ -56,7 +55,7 @@ Test(int bind_before)
+ 
+ 	CHK(SQLExecute, (Statement));
+ 
+-	Command(Statement, "drop proc spTestProc");
++	Command(Statement, "DROP PROC spTestProc");
+ 
+ 	printf("Output:\n");
+ 	printf("   Return Code = %d\n", (int) ReturnCode);
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index a9d3878..3eff23f 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.10 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.11 2008/02/08 09:28:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -49,8 +49,7 @@ main(int argc, char *argv[])
+ 
+ 		if (l < n)
+ 			n = l;
+-		if (SQLPutData(Statement, (char *) p, n) != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Wrong result from SQLPutData");
++		CHK(SQLPutData, (Statement, (char *) p, n));
+ 		p += n;
+ 		n *= 2;
+ 	}
+diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c
+index 76fd66f..3395ad4 100644
+--- a/src/odbc/unittests/raiserror.c
++++ b/src/odbc/unittests/raiserror.c
+@@ -4,7 +4,7 @@
+ 
+ /* TODO add support for Sybase */
+ 
+-static char software_version[] = "$Id: raiserror.c,v 1.20 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: raiserror.c,v 1.21 2008/02/08 09:28:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{?=call #tmp1(?,?,?)}"
+@@ -209,9 +209,8 @@ Test(int level)
+ 	}
+ 
+ 	if (!use_odbc_version3 || !g_nocount) {
+-		result = SQLMoreResults(Statement);
+-		if (result != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLMoreResults returned failure");
++		CHK(SQLMoreResults, (Statement));
++		result = SQL_SUCCESS;
+ 	}
+ 
+ 	CheckReturnCode(result, INVALID_RETURN);
+diff --git a/src/odbc/unittests/rownumber.c b/src/odbc/unittests/rownumber.c
+index d2c213f..55eddaf 100644
+--- a/src/odbc/unittests/rownumber.c
++++ b/src/odbc/unittests/rownumber.c
+@@ -7,7 +7,7 @@
+  * TODO make it work and add to Makefile.am
+  */
+ 
+-static char software_version[] = "$Id: rownumber.c,v 1.2 2005/01/14 15:03:12 freddy77 Exp $";
++static char software_version[] = "$Id: rownumber.c,v 1.3 2008/02/08 09:28:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -62,8 +62,8 @@ DoTest()
+ 	static const char query[] = "SELECT * FROM #tmp1 ORDER BY i SELECT * FROM #tmp1 WHERE i < 3 ORDER BY i";
+ 
+ 	/* execute a batch command and check row number */
+-	if (SQLExecDirect(Statement, (SQLCHAR *) query, SQL_NTS) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to execute direct statement");
++	CHK(SQLExecDirect, (Statement, (SQLCHAR *) query, SQL_NTS));
++
+ 	CHECK_ROWS(-1);
+ 	printf("Result %d\n", ++n);
+ 	Fetch(SQL_SUCCESS);
+diff --git a/src/odbc/unittests/t0001.c b/src/odbc/unittests/t0001.c
+index 6ca6c8d..a51adea 100644
+--- a/src/odbc/unittests/t0001.c
++++ b/src/odbc/unittests/t0001.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.15 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.16 2008/02/08 09:28:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -17,8 +17,7 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	if (CommandWithResult(Statement, "drop table #odbctestdata") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
+ 
+ 	command = "create table #odbctestdata ("
+ 		"col1 varchar(30) not null,"
+diff --git a/src/odbc/unittests/t0002.c b/src/odbc/unittests/t0002.c
+index 8fa2830..af7cfc3 100644
+--- a/src/odbc/unittests/t0002.c
++++ b/src/odbc/unittests/t0002.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.13 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.14 2008/02/08 09:28:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,8 +12,7 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	if (CommandWithResult(Statement, "drop table #odbctestdata") != SQL_SUCCESS)
+-		printf("Unable to execute statement\n");
++	Command(Statement, "if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
+ 
+ 	Command(Statement, "create table #odbctestdata (i int)");
+ 	Command(Statement, "insert #odbctestdata values (123)");
+diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c
+index 5ab9325..61e80bb 100644
+--- a/src/odbc/unittests/testodbc.c
++++ b/src/odbc/unittests/testodbc.c
+@@ -10,7 +10,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: testodbc.c,v 1.10 2008/02/06 08:29:53 freddy77 Exp $";
++static char software_version[] = "$Id: testodbc.c,v 1.11 2008/02/08 09:28:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef DEBUG
+@@ -139,30 +139,11 @@ TestRawODBCPreparedQuery(void)
+ 
+ 	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+ 
+-	status = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		DispODBCErrs();
+-		DispODBCDiags();
+-		AB_FUNCT(("TestRawODBCPreparedQuery (out): error"));
+-		return FALSE;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd));
+ 
+-	status = SQLPrepare(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Prepare failed"));
+-		AB_FUNCT(("TestRawODBCPreparedQuery (out): error"));
+-		return FALSE;
+-	}
++	CHK(SQLPrepare, (Statement, queryString, SQL_NTS));
+ 
+-	status = SQLExecute(Statement);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Execute failed"));
+-		DispODBCErrs();
+-		DispODBCDiags();
+-		AB_FUNCT(("TestRawODBCPreparedQuery (out): error"));
+-		return FALSE;
+-	}
++	CHK(SQLExecute, (Statement));
+ 
+ 	count = 0;
+ 
+@@ -230,23 +211,9 @@ TestRawODBCDirectQuery(void)
+ 
+ 	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+ 
+-	status = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		DispODBCErrs();
+-		DispODBCDiags();
+-		AB_FUNCT(("TestRawODBCDirectQuery (out): error"));
+-		return FALSE;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd));
+ 
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Execute failed"));
+-		DispODBCErrs();
+-		DispODBCDiags();
+-		AB_FUNCT(("TestRawODBCDirectQuery (out): error"));
+-		return FALSE;
+-	}
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 
+ 	count = 0;
+ 
+@@ -326,11 +293,7 @@ TestRawODBCGuid(void)
+ 
+ 	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age ) \
+                          VALUES ( 'Fang', 'Mike', 'dog', 'm', 12 );");
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Insert row 1 failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 
+ 	AB_PRINT(("Insert row 2"));
+ 
+@@ -343,21 +306,10 @@ TestRawODBCGuid(void)
+ 
+ 	lenOrInd = 0;
+ 	age = 3;
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &age, 0, &lenOrInd)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &age, 0, &lenOrInd));
+ 
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Insert row 2 failed"));
+-		goto odbcfail;
+-	}
+-	if (SQLFreeStmt(Statement, SQL_CLOSE) != SQL_SUCCESS) {
+-		AB_ERROR(("Free statement failed (5)"));
+-		goto odbcfail;
+-	}
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
+ 
+ 	AB_PRINT(("Insert row 3"));
+ 	/*
+@@ -369,16 +321,8 @@ TestRawODBCGuid(void)
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "87654321-4321-4321-4321-123456789abc");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		goto odbcfail;
+-	}
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Insert row 3 failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd));
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 
+ 	AB_PRINT(("Insert row 4"));
+ 	/*
+@@ -390,16 +334,8 @@ TestRawODBCGuid(void)
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 36, 0, guid, 0, &lenOrInd)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		goto odbcfail;
+-	}
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("Insert row 4 failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 36, 0, guid, 0, &lenOrInd));
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 
+ 	AB_PRINT(("Insert row 5"));
+ 	/*
+@@ -423,11 +359,7 @@ TestRawODBCGuid(void)
+ 	lenOrInd = 16;
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd));
+ 	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("Insert row 5 failed"));
+@@ -439,23 +371,11 @@ TestRawODBCGuid(void)
+ 	 */
+ 	AB_PRINT(("retrieving name and guid"));
+ 	strcpy((char *) (queryString), "SELECT name, guid FROM #pet");
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("SELECT failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 	while (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		count++;
+-		if (SQLGetData(Statement, 1, SQL_CHAR, name, 20, 0)
+-		    != SQL_SUCCESS) {
+-			AB_ERROR(("Get row %d, name column failed", count));
+-			goto odbcfail;
+-		}
+-		if (SQLGetData(Statement, 2, SQL_CHAR, guid, 37, 0)
+-		    != SQL_SUCCESS) {
+-			AB_ERROR(("Get row %d, guid column failed", count));
+-			goto odbcfail;
+-		}
++		CHK(SQLGetData, (Statement, 1, SQL_CHAR, name, 20, 0));
++		CHK(SQLGetData, (Statement, 2, SQL_CHAR, guid, 37, 0));
+ 
+ 		AB_PRINT(("name: %-10s guid: %s", name, guid));
+ 	}
+@@ -464,15 +384,8 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state if we try SELECT again).
+ 	 */
+-	if (SQLFreeStmt(Statement, SQL_CLOSE) != SQL_SUCCESS) {
+-		AB_ERROR(("Free statement failed (5)"));
+-		goto odbcfail;
+-	}
+-	if (SQLAllocHandle(SQL_HANDLE_STMT, Connection, &Statement)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLAllocStmt failed(1)"));
+-		goto odbcfail;
+-	}
++	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
++	CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
+ 
+ 
+ 	/*
+@@ -481,23 +394,11 @@ TestRawODBCGuid(void)
+ 
+ 	AB_PRINT(("retrieving name and guid again"));
+ 	strcpy((char *) (queryString), "SELECT name, guid FROM #pet");
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("SELECT failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 	while (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		count++;
+-		if (SQLGetData(Statement, 1, SQL_CHAR, name, 20, 0)
+-		    != SQL_SUCCESS) {
+-			AB_ERROR(("Get row %d, name column failed", count));
+-			goto odbcfail;
+-		}
+-		if (SQLGetData(Statement, 2, SQL_GUID, &sqlguid, 16, 0)
+-		    != SQL_SUCCESS) {
+-			AB_ERROR(("Get row %d, guid column failed", count));
+-			goto odbcfail;
+-		}
++		CHK(SQLGetData, (Statement, 1, SQL_CHAR, name, 20, 0));
++		CHK(SQLGetData, (Statement, 2, SQL_GUID, &sqlguid, 16, 0));
+ 
+ 		AB_PRINT(("%-10s %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ 			  name,
+@@ -511,15 +412,8 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state if we try SELECT again).
+ 	 */
+-	if (SQLFreeStmt(Statement, SQL_CLOSE) != SQL_SUCCESS) {
+-		AB_ERROR(("Free statement failed (5)"));
+-		goto odbcfail;
+-	}
+-	if (SQLAllocHandle(SQL_HANDLE_STMT, Connection, &Statement)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLAllocStmt failed(1)"));
+-		goto odbcfail;
+-	}
++	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
++	CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
+ 
+ 	/*
+ 	 * Now retrieve rows via stored procedure passing GUID as param.
+@@ -530,28 +424,12 @@ TestRawODBCGuid(void)
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "87654321-4321-4321-4321-123456789abc");
+ 
+-	if (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLBindParameter failed"));
+-		goto odbcfail;
+-	}
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS) {
+-		AB_ERROR(("SELECT failed"));
+-		goto odbcfail;
+-	}
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd));
++	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+ 	while (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		count++;
+-		if (SQLGetData(Statement, 1, SQL_CHAR, name, 20, 0)
+-		    != SQL_SUCCESS) {
+-			AB_ERROR(("Get row %d, name column failed", count));
+-			goto odbcfail;
+-		}
+-		if (SQLGetData(Statement, 2, SQL_CHAR, guid, 37, 0)
+-		    != SQL_SUCCESS) {
+-			AB_ERROR(("Get row %d, guid column failed", count));
+-			goto odbcfail;
+-		}
++		CHK(SQLGetData, (Statement, 1, SQL_CHAR, name, 20, 0));
++		CHK(SQLGetData, (Statement, 2, SQL_CHAR, guid, 37, 0));
+ 
+ 		AB_PRINT(("%-10s %s", name, guid));
+ 	}
+@@ -560,15 +438,8 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state after a previous SELECT has occurred).
+ 	 */
+-	if (SQLFreeStmt(Statement, SQL_CLOSE) != SQL_SUCCESS) {
+-		AB_ERROR(("Free statement failed (5)"));
+-		goto odbcfail;
+-	}
+-	if (SQLAllocHandle(SQL_HANDLE_STMT, Connection, &Statement)
+-	    != SQL_SUCCESS) {
+-		AB_ERROR(("SQLAllocStmt failed(1)"));
+-		goto odbcfail;
+-	}
++	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
++	CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
+ 
+ 	/* cleanup */
+ 	CommandWithResult(Statement, "DROP PROC GetGUIDRows");
+diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c
+index edb7d37..8fdeff3 100644
+--- a/src/odbc/unittests/timeout3.c
++++ b/src/odbc/unittests/timeout3.c
+@@ -40,7 +40,7 @@
+ 	test connection timeout
+ */
+ 
+-static char software_version[] = "$Id: timeout3.c,v 1.6 2007/11/26 18:12:31 freddy77 Exp $";
++static char software_version[] = "$Id: timeout3.c,v 1.7 2008/02/08 09:28:05 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -49,14 +49,14 @@ static void
+ init_connect(void)
+ {
+ 	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		printf("Unable to allocate env\n");
++		fprintf(stderr, "Unable to allocate env\n");
+ 		exit(1);
+ 	}
+ 
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+ 
+ 	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		printf("Unable to allocate connection\n");
++		fprintf(stderr, "Unable to allocate connection\n");
+ 		SQLFreeEnv(Environment);
+ 		exit(1);
+ 	}
+
+commit 1f0c7cafa73fb9e09ea9ebdceef4099fae62cca1
+Author: freddy77 <freddy77>
+Date:   Fri Feb 8 09:32:06 2008 +0000
+
+    add a comment
+
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index b7b8235..a897f93 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.470 2008/01/29 09:35:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.471 2008/02/08 09:32:06 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3343,6 +3343,10 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ static void
+ odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err)
+ {
++	/*
++	 * TODO we really need a column offset in the _sql_error structure so that caller can 
++	 * invoke SQLGetDiagField to learn which column is failing
++	 */
+ 	switch (err) {
+ 	case TDS_CONVERT_NOAVAIL:
+ 		odbc_errs_add(errs, "HY003", NULL);
+
+commit 7b994c7e6ac231e2f269b028fe3ca0cfe74d095b
+Author: freddy77 <freddy77>
+Date:   Fri Feb 8 10:20:23 2008 +0000
+
+    let it compile
+
+diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c
+index 61e80bb..96c28f5 100644
+--- a/src/odbc/unittests/testodbc.c
++++ b/src/odbc/unittests/testodbc.c
+@@ -10,7 +10,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: testodbc.c,v 1.11 2008/02/08 09:28:04 freddy77 Exp $";
++static char software_version[] = "$Id: testodbc.c,v 1.12 2008/02/08 10:20:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef DEBUG
+@@ -104,7 +104,6 @@ DispODBCDiags(void)
+ static int
+ TestRawODBCPreparedQuery(void)
+ {
+-	SQLRETURN status;
+ 	SQLCHAR queryString[200];
+ 	SQLLEN lenOrInd = 0;
+ 	SQLSMALLINT supplierId = 4;
+@@ -176,7 +175,6 @@ TestRawODBCPreparedQuery(void)
+ static int
+ TestRawODBCDirectQuery(void)
+ {
+-	SQLRETURN status;
+ 	SQLCHAR queryString[200];
+ 	SQLLEN lenOrInd = 0;
+ 	SQLSMALLINT supplierId = 1;
+@@ -359,7 +357,7 @@ TestRawODBCGuid(void)
+ 	lenOrInd = 16;
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+ 
+-	CHK(SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd));
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd));
+ 	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("Insert row 5 failed"));
+
+commit 862f3b5f92558517a616e14fab0a83ad6fcc24ef
+Author: freddy77 <freddy77>
+Date:   Wed Feb 13 08:52:08 2008 +0000
+
+    merged small memory issues, fix test64 test output
+
+diff --git a/ChangeLog b/ChangeLog
+index 393b4a0..bd126d0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Feb 13 09:50:35 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqlodbc.c: fix memory error
++	* src/tds/query.c: remove possible buffer underflow
++	* src/odbc/unittests/test64.c: truncate upper part for low
++
+ Fri Feb 08 10:26:36 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/describecol.in:
+ 	* src/odbc/unittests/params.c src/odbc/unittests/putdata.c:
+@@ -158,4 +163,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2487 2008/02/08 09:28:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2488 2008/02/13 08:52:08 freddy77 Exp $
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index 1050550..89d9c19 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.9 2007/11/26 06:25:57 freddy77 Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.10 2008/02/13 08:52:09 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -339,6 +339,10 @@ main(int argc, char *argv[])
+ 		} 
+ 	}
+ 
++	SQLDisconnect(hDbc);
++	SQLFreeHandle(SQL_HANDLE_DBC, hDbc);
++	SQLFreeHandle(SQL_HANDLE_ENV, hEnv);
++
+ 	return 0;
+ }
+ 
+@@ -347,14 +351,15 @@ next_query()
+ {
+ 	char query_line[4096];
+ 	static char *sql = NULL;
+-	
++
+ 	if (feof(stdin))
+ 		return NULL;
+-			
++
+ 	fprintf(options.verbose, "%s:%d: Query:\n", options.appname, __LINE__);
+-	
++
+ 	free(sql);
+-	
++	sql = NULL;
++
+ 	while (fgets(query_line, sizeof(query_line), stdin)) {
+ 		/* 'go' or 'GO' separates command batches */
+ 		char *p = query_line;
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index 8d0dd75..4078cd8 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.4 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.5 2008/02/13 08:52:09 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -110,6 +110,7 @@ test_params(void)
+ 		l = len;
+ 		len >>= 16;
+ 		h = len >> 16;
++		l &= 0xfffffffflu;
+ 		if (h != 0 || l != 2) {
+ 			fprintf(stderr, "Wrong number returned in param rows high %lu low %lu\n", h, l);
+ 			exit(1);
+@@ -223,6 +224,7 @@ test_rows(void)
+ 		l = len;
+ 		len >>= 16;
+ 		h = len >> 16;
++		l &= 0xfffffffflu;
+ 		if (h != 0 || l != 2) {
+ 			fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx)\n", h, h, l, l);
+ 			exit(1);
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 61c266d..3cd8c5f 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.218 2008/01/20 14:23:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.219 2008/02/13 08:52:09 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -577,7 +577,7 @@ tds_next_placeholder_ucs2le(const char *start, const char *end, int named)
+ 		case '?':
+ 			return p;
+ 		case '@':
+-			if (named && !isalnum(prev))
++			if (named && !isalnum((unsigned char) prev))
+ 				return p;
+ 		default:
+ 			p += 2;
+@@ -849,7 +849,7 @@ tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t quer
+ 					continue;
+ 				/* find end of param name */
+ 				for (id_end = e + 2; id_end != query_end; id_end += 2)
+-					if (!id_end[1] && (id_end[0] != '_' && id_end[1] != '#' && !isalnum(id_end[0])))
++					if (!id_end[1] && (id_end[0] != '_' && id_end[1] != '#' && !isalnum((unsigned char) id_end[0])))
+ 						break;
+ 				ids[i].p = e;
+ 				ids[i].len = id_end - e;
+
+commit e0694937b57d4d27978d4866298b98410d9c68e8
+Author: freddy77 <freddy77>
+Date:   Fri Feb 15 11:00:40 2008 +0000
+
+    fix an ABI problem under HP-UX
+
+diff --git a/ChangeLog b/ChangeLog
+index bd126d0..2dec974 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb 15 11:53:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac: fix nasty problem with HP-UX
++
+ Wed Feb 13 09:50:35 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqlodbc.c: fix memory error
+ 	* src/tds/query.c: remove possible buffer underflow
+@@ -163,4 +166,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2488 2008/02/13 08:52:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2489 2008/02/15 11:00:40 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 77740fc..26bf18f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.33 2008/01/20 14:23:58 freddy77 Exp $
++dnl $Id: configure.ac,v 1.34 2008/02/15 11:00:40 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.33 $)
++AC_REVISION($Revision: 1.34 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -47,7 +47,6 @@ case $host in
+     netdb_reentrant=yes
+     ;;
+   *-*-hpux11*)
+-    CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE_EXTENDED"
+     netdb_reentrant=yes
+     ;;
+   *-*-cygwin*)
+@@ -151,6 +150,27 @@ case $host in
+ 	fi
+ 	AM_CONDITIONAL(MINGW32, true)
+ 	;;
++*-*-hpux*)
++	# these lines are needed to fix a problem for HP-UX
++	# HP-UX define two versions of sockets, one BSD and one X/Open
++	# these versions are not binary compatible (BSD use int where X/Open 
++	# use socklen_t == size_t) and different libraries (BSD in libc and
++	# X/Open in libxnet). X/Open is used if _XOPEN_SOURCE and 
++	# _XOPEN_SOURCE_EXTENDED are defined. To complicate the things gcc
++	# by default define _XOPEN_SOURCE_EXTENDED so define always both
++	# constants and link always libxnet!
++	CPPFLAGS="$CPPFLAGS -D_XOPEN_SOURCE -D_XOPEN_SOURCE_EXTENDED"
++	LIBS="$LIBS -lxnet"
++	AC_SEARCH_LIBS(gethostbyname, nsl)
++	if test "$enable_krb5" = "yes" ; then
++		AC_SEARCH_LIBS(gss_init_sec_context, [gssapi_krb5 gssapi])
++		if test "$ac_cv_search_gss_init_sec_context" != no; then
++			AC_DEFINE(ENABLE_KRB5, 1, [Defined if --enable-krb5 used and library detected])
++		fi
++	fi
++
++	AM_CONDITIONAL(MINGW32, false)
++	;;
+ *)
+ 	AC_SEARCH_LIBS(socket, socket)
+ 	AC_SEARCH_LIBS(gethostbyname, nsl)
+
+commit 03780ab494ed3fe0192268b97fdbc595f3f5fd0a
+Author: freddy77 <freddy77>
+Date:   Fri Feb 15 11:06:39 2008 +0000
+
+    fix SQL_ATTR_CONNECTION_DEAD
+
+diff --git a/ChangeLog b/ChangeLog
+index 2dec974..0373661 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb 15 12:05:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix SQL_ATTR_CONNECTION_DEAD
++
+ Fri Feb 15 11:53:41 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac: fix nasty problem with HP-UX
+ 
+@@ -166,4 +169,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2489 2008/02/15 11:00:40 freddy77 Exp $
++$Id: ChangeLog,v 1.2490 2008/02/15 11:06:39 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a897f93..9438336 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.471 2008/02/08 09:32:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.472 2008/02/15 11:06:39 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4471,6 +4471,7 @@ _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTE
+ 		ODBC_RETURN_(dbc);
+ 		break;
+ #if defined(SQL_ATTR_CONNECTION_DEAD) && defined(SQL_CD_TRUE)
++	case SQL_ATTR_CONNECTION_DEAD:
+ 		*((SQLUINTEGER *) Value) = IS_TDSDEAD(dbc->tds_socket) ? SQL_CD_TRUE : SQL_CD_FALSE;
+ 		ODBC_RETURN_(dbc);
+ 		break;
+
+commit e355230cc6c9e491c13a7cd2fbeb9828109a0f2a
+Author: jklowden <jklowden>
+Date:   Fri Feb 15 16:27:38 2008 +0000
+
+    support SYBUNIQUE printable width
+
+diff --git a/ChangeLog b/ChangeLog
+index 0373661..77bc6c3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Feb 15 11:25:46 EST 2008	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c src/tds/convert.c
++	- support SYBUNIQUE printable width
++
+ Fri Feb 15 12:05:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix SQL_ATTR_CONNECTION_DEAD
+ 
+@@ -169,4 +173,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2490 2008/02/15 11:06:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2491 2008/02/15 16:27:38 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index b6950aa..b9baa7e 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.321 2008/01/24 21:14:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.322 2008/02/15 16:27:38 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -3469,6 +3469,10 @@ dbprrow(DBPROCESS * dbproc)
+ 	return SUCCEED;
+ }
+ 
++/*
++ * src/tds/convert.c::tds_willconvert() returns same information.
++ * Available to user via dbwillconvert(). 
++ */
+ static int
+ _get_printable_size(TDSCOLUMN * colinfo)
+ {
+@@ -3496,17 +3500,16 @@ _get_printable_size(TDSCOLUMN * colinfo)
+ 	case SYBCHAR:
+ 		return colinfo->column_size;
+ 	case SYBFLT8:
+-		return 11;	/* FIX ME -- we do not track precision */
+ 	case SYBREAL:
+ 		return 11;	/* FIX ME -- we do not track precision */
+ 	case SYBMONEY:
+-		return 12;	/* FIX ME */
+ 	case SYBMONEY4:
+-		return 12;	/* FIX ME */
++		return 12;
+ 	case SYBDATETIME:
+-		return 26;	/* FIX ME */
+ 	case SYBDATETIME4:
+-		return 26;	/* FIX ME */
++		return 26;
++	case SYBUNIQUE:
++		return 36;
+ 	case SYBBIT:
+ 	case SYBBITN:
+ 		return 1;
+@@ -3514,7 +3517,6 @@ _get_printable_size(TDSCOLUMN * colinfo)
+ 	default:
+ 		return 0;
+ 	}
+-
+ }
+ 
+ /**
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 67ea545..2283097 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.180 2008/02/04 07:51:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.181 2008/02/15 16:27:39 jklowden Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -2896,6 +2896,8 @@ tds_willconvert(int srctype, int desttype)
+ 	case SYBMONEY:
+ 	case SYBMONEY4:
+ 			return 12;
++	case SYBUNIQUE:
++			return 36;
+ 	/* non-fixed types have variable data sizes, just return 0xff */
+ 	case SYBCHAR:
+ 	case SYBBINARY:
+@@ -2919,7 +2921,6 @@ tds_willconvert(int srctype, int desttype)
+ 	case SYBINTERVAL:
+ 	case SYBSENSITIVITY:
+ 	case SYBTIME:
+-	case SYBUNIQUE:
+ 	case SYBUNITEXT:
+ 	case SYBVARIANT:
+ 	case SYBVOID:
+
+commit b0a20c0ee8ab8a10f8a189c8f8963870b49e245d
+Author: freddy77 <freddy77>
+Date:   Wed Feb 20 08:04:31 2008 +0000
+
+    avoid duplicate case
+
+diff --git a/ChangeLog b/ChangeLog
+index 77bc6c3..96cd21e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Feb 20 09:04:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: avoid duplicate case
++
+ Fri Feb 15 11:25:46 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c src/tds/convert.c
+ 	- support SYBUNIQUE printable width
+@@ -173,4 +176,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2491 2008/02/15 16:27:38 jklowden Exp $
++$Id: ChangeLog,v 1.2492 2008/02/20 08:04:31 freddy77 Exp $
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 2283097..6c6b985 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.181 2008/02/15 16:27:39 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.182 2008/02/20 08:04:32 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -2896,12 +2896,12 @@ tds_willconvert(int srctype, int desttype)
+ 	case SYBMONEY:
+ 	case SYBMONEY4:
+ 			return 12;
++	/* TODO SYBBLOB has the same value */
+ 	case SYBUNIQUE:
+ 			return 36;
+ 	/* non-fixed types have variable data sizes, just return 0xff */
+ 	case SYBCHAR:
+ 	case SYBBINARY:
+-	case SYBBLOB:
+ 	case SYBLONGBINARY:
+ 	case SYBLONGCHAR:
+ 	case SYBTEXT:
+
+commit 85f0d20666452ef19da29d3d368bc04e121603b2
+Author: jklowden <jklowden>
+Date:   Thu Feb 28 23:27:10 2008 +0000
+
+    announced 0.82RC2
+
+diff --git a/ChangeLog b/ChangeLog
+index 96cd21e..da12d08 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Feb 28 18:24:31 EST 2008	JK Lowden <jklowden@freetds.org>
++	* doc/htdoc/news.html announced 0.82RC2
++	* vms/configure.com turn off iconv by default
++
+ Wed Feb 20 09:04:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/convert.c: avoid duplicate case
+ 
+@@ -176,4 +180,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2492 2008/02/20 08:04:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2493 2008/02/28 23:27:10 jklowden Exp $
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index 5dbbcee..b940620 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.13 2008/01/17 22:57:27 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.14 2008/02/28 23:27:10 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -33,6 +33,19 @@ News&nbsp;&nbsp;|&nbsp;
+ <table summary="layout" width="80%" align="center">
+ 
+ <!--  item  -->
++<tr bgcolor="#c9c9ff"><td>Second Release Candidate available for 0.82</td></tr>
++<tr>
++<td>
++<br />
++Version 0.82RC2 is now available from 
++<a href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/current/freetds-rc.tgz">
++ftp.ibiblio.org</a>.  
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
+ <tr bgcolor="#c9c9ff"><td>FreeTDS enters release process for Version 0.82</td></tr>
+ <tr>
+ <td>
+
+commit ba520b40b0b671c6a12e26d6368ea56a3e32f319
+Author: jklowden <jklowden>
+Date:   Thu Feb 28 23:27:14 2008 +0000
+
+    turn off iconv by default
+
+diff --git a/vms/configure.com b/vms/configure.com
+index 37b59b3..ca0d413 100644
+--- a/vms/configure.com
++++ b/vms/configure.com
+@@ -16,7 +16,7 @@ $! License along with this library; if not, write to the
+ $! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ $! Boston, MA 02111-1307, USA.
+ $!
+-$! $Id: configure.com,v 1.5 2005/12/29 10:24:34 freddy77 Exp $
++$! $Id: configure.com,v 1.6 2008/02/28 23:27:14 jklowden Exp $
+ $!
+ $! CONFIGURE.COM -- run from top level source directory as @[.vms]configure
+ $!
+@@ -38,7 +38,9 @@ $! The system-supplied iconv() is fine, but unless the internationalization
+ $! kit has been installed, we may not have the conversions we need.  Check
+ $! for their presence and use the homegrown iconv() if necessary.
+ $!
+-$ IF F$SEARCH("SYS$I18N_ICONV:UCS-2_ISO8859-1.ICONV") .NES. "" -
++$ IF -
++    "FALSE" - ! native iconv() buggy, don't use for now
++    .AND. F$SEARCH("SYS$I18N_ICONV:UCS-2_ISO8859-1.ICONV") .NES. "" -
+     .AND. F$SEARCH("SYS$I18N_ICONV:ISO8859-1_UCS-2.ICONV") .NES. "" -
+     .AND. F$SEARCH("SYS$I18N_ICONV:UTF-8_ISO8859-1.ICONV") .NES. "" -
+     .AND. F$SEARCH("SYS$I18N_ICONV:ISO8859-1_UTF-8.ICONV") .NES. ""
+
+commit a8b0c6b4ee8c579b2a76bceb742ad486b6d08747
+Author: freddy77 <freddy77>
+Date:   Fri Feb 29 10:54:53 2008 +0000
+
+    ported tests and SQL_ROWSET_SIZE fix
+
+diff --git a/ChangeLog b/ChangeLog
+index da12d08..e91b2b1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Feb 29 11:50:06 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/rowset.c(added):
++	- ported tests and SQL_ROWSET_SIZE fix
++
+ Thu Feb 28 18:24:31 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/htdoc/news.html announced 0.82RC2
+ 	* vms/configure.com turn off iconv by default
+@@ -180,4 +185,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2493 2008/02/28 23:27:10 jklowden Exp $
++$Id: ChangeLog,v 1.2494 2008/02/29 10:54:53 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 9438336..51a0658 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.472 2008/02/15 11:06:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.473 2008/02/29 10:54:53 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -1472,8 +1472,7 @@ _SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR * phstmt)
+ 	stmt->attr.simulate_cursor = SQL_SC_NON_UNIQUE;
+ 	stmt->attr.use_bookmarks = SQL_UB_OFF;
+ 
+-	/* is not the same of using APD sql_desc_bind_type */
+-	stmt->sql_rowset_size = SQL_BIND_BY_COLUMN;
++	stmt->sql_rowset_size = 1;
+ 
+ 	stmt->row_count = TDS_NO_COUNT;
+ 	stmt->row_status = NOT_IN_ROW;
+@@ -6189,6 +6188,10 @@ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN
+ 		stmt->attr.use_bookmarks = ui;
+ 		break;
+ 	case SQL_ROWSET_SIZE:	/* although this is ODBC2 we must support this attribute */
++		if (((TDS_INTPTR) ValuePtr) < 1) {
++			odbc_errs_add(&stmt->errs, "HY024", NULL);
++			ODBC_RETURN(stmt, SQL_ERROR);
++		}
+ 		stmt->sql_rowset_size = ui;
+ 		break;
+ 	default:
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index fb6855d..4d90945 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -64,6 +64,7 @@ cursor5
+ attributes
+ hidden
+ blob1
++rowset
+ cancel
+ test64
+ wchar
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index f9e14f9..f6bb215 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.72 2008/02/08 09:28:03 freddy77 Exp $
++# $Id: Makefile.am,v 1.73 2008/02/29 10:54:53 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -21,7 +21,7 @@ TESTS		=	\
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+-			cancel$(EXEEXT) wchar$(EXEEXT)
++			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -80,6 +80,7 @@ cursor5_SOURCES	= cursor5.c common.c common.h
+ attributes_SOURCES	= attributes.c common.c common.h
+ hidden_SOURCES	= hidden.c common.c common.h
+ blob1_SOURCES	= blob1.c common.c common.h
++rowset_SOURCES	= rowset.c common.c common.h
+ cancel_SOURCES = cancel.c common.c common.h
+ wchar_SOURCES = wchar.c common.c common.h
+ 
+diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c
+new file mode 100644
+index 0000000..93a0b2f
+--- /dev/null
++++ b/src/odbc/unittests/rowset.c
+@@ -0,0 +1,108 @@
++#include "common.h"
++
++static char software_version[] = "$Id: rowset.c,v 1.2 2008/02/29 10:54:53 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static char odbc_err[256];
++static char odbc_sqlstate[6];
++
++static void
++ReadError(void)
++{
++	memset(odbc_err, 0, sizeof(odbc_err));
++	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
++	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
++		printf("SQLGetDiagRec should not fail\n");
++		exit(1);
++	}
++	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
++}
++
++static void
++test_err(int n)
++{
++	SQLRETURN rc;
++
++	rc = SQLSetStmtAttr(Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(n), 0);
++	if (rc != SQL_ERROR) {
++		fprintf(stderr, "SQLSetStmtAttr should fail\n");
++		Disconnect();
++		exit(1);
++        }
++	ReadError();
++	if (strcmp(odbc_sqlstate, "HY024") != 0) {
++		fprintf(stderr, "Unexpected sql state returned\n");
++		Disconnect();
++		exit(1);
++        }
++}
++
++int
++main(int argc, char *argv[])
++{
++	int i;
++	SQLLEN len;
++#ifdef HAVE_SQLROWSETSIZE
++	SQLROWSETSIZE row_count;
++#else
++	SQLULEN row_count;
++#endif
++	SQLUSMALLINT statuses[10];
++	char buf[32];
++	SQLRETURN rc;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	/* initial value should be 1 */
++	CHK(SQLGetStmtAttr, (Statement, SQL_ROWSET_SIZE, &len, sizeof(len), NULL));
++	if (len != 1) {
++		fprintf(stderr, "len should be 1\n");
++		Disconnect();
++		return 1;
++	}
++
++	/* check invalid parameter values */
++	test_err(-123);
++	test_err(-1);
++	test_err(0);
++
++	/* set some correct values */
++	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0));
++
++	/* now check that SQLExtendedFetch works as expected */
++	Command(Statement, "CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
++	for (i = 0; i < 10; ++i) {
++		char s[10];
++		char sql[128];
++
++		memset(s, 'a' + i, 9);
++		s[9] = 0;
++		sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s);
++		Command(Statement, sql);
++	}
++
++	ResetStatement();
++	CHK(SQLSetStmtOption, (Statement, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC));
++	rc = CommandWithResult(Statement, "SELECT * FROM #rowset ORDER BY n");
++	if (!SQL_SUCCEEDED(rc))
++		ODBC_REPORT_ERROR("SQLExecDirect error");
++
++	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, buf, sizeof(buf), &len));
++
++	row_count = 0xdeadbeef;
++	memset(statuses, 0x55, sizeof(statuses));
++	CHK(SQLExtendedFetch, (Statement, SQL_FETCH_NEXT, 1, &row_count, statuses));
++
++	if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) {
++		fprintf(stderr, "Invalid result\n");
++		Disconnect();
++		return 1;
++	}
++
++	Disconnect();
++
++	printf("Done.\n");
++	return 0;
++}
+
+commit 281d4a6963bfe2d187caaa4d1adde6e96c382285
+Author: freddy77 <freddy77>
+Date:   Wed Mar 5 11:01:15 2008 +0000
+
+    change some vc6 build options
+
+diff --git a/ChangeLog b/ChangeLog
+index e91b2b1..c274c53 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar 05 12:0:43 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/build_dsw.pl: change some build options
++
+ Fri Feb 29 11:50:06 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/rowset.c(added):
+@@ -185,4 +188,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2494 2008/02/29 10:54:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2495 2008/03/05 11:01:15 freddy77 Exp $
+diff --git a/win32/build_dsw.pl b/win32/build_dsw.pl
+index a52e303..3a5dc9d 100644
+--- a/win32/build_dsw.pl
++++ b/win32/build_dsw.pl
+@@ -48,8 +48,8 @@ RSC=rc.exe
+ # PROP Output_Dir "..\\Release"
+ # PROP Intermediate_Dir "..\\Release"
+ # PROP Target_Dir ""
+-# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
+-# ADD CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /YX /FD /c
++# ADD BASE CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
++# ADD CPP /nologo /MD /W3 /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /YX /FD /c
+ # ADD BASE RSC /l 0x410 /d "NDEBUG"
+ # ADD RSC /l 0x410 /d "NDEBUG"
+ BSC32=bscmake.exe
+@@ -71,8 +71,8 @@ LINK32=link.exe
+ # PROP Output_Dir "..\\Debug"
+ # PROP Intermediate_Dir "..\\Debug"
+ # PROP Target_Dir ""
+-# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
+-# ADD CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /YX /FD /GZ  /c
++# ADD BASE CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ  /c
++# ADD CPP /nologo /MDd /W3 /Gm /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D FREETDS_SRCDIR=\\"..\\" /D DBNTWIN32 /YX /FD /GZ  /c
+ # ADD BASE RSC /l 0x410 /d "_DEBUG"
+ # ADD RSC /l 0x410 /d "_DEBUG"
+ BSC32=bscmake.exe
+
+commit e1a31eedce73a87474310ac8cd3fe98bdaafff60
+Author: freddy77 <freddy77>
+Date:   Fri Mar 7 08:56:34 2008 +0000
+
+    updated protocol doc
+
+diff --git a/ChangeLog b/ChangeLog
+index c274c53..0e5937f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar 07 09:55:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/tds.html: updated
++
+ Wed Mar 05 12:0:43 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/build_dsw.pl: change some build options
+ 
+@@ -188,4 +191,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2495 2008/03/05 11:01:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2496 2008/03/07 08:56:34 freddy77 Exp $
+diff --git a/doc/tds.html b/doc/tds.html
+index f1dc00e..a0bdf38 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -94,7 +94,8 @@ of what goes on.
+ <h2 class="section">The packet format</h2>
+ <p>
+ <a name="packet"></a>
+-All packets start with the following 8 byte header.  
++Every informations in TDS protocol (query, RPCs, responses and so on) is splitted in packets.</p>
++<p>All packets start with the following 8 byte header.  
+ 
+ <pre>
+  INT8       INT8          INT16      4 bytes
+@@ -134,9 +135,11 @@ above header.</p>
+ <p><i>Note:</i>
+   A TDS packet that is longer than 512 bytes is split on the 512 byte
+   boundary and the "more packets" bit is set.  The full TDS packet is reassembled
+-  from its component 512 byte packets with the 8-byte headers stripped out.  (I
+-  believe the 512 is the block_size in the login packet, so it could be set to a
+-  different value. *mjs*)</p>
++  from its component 512 byte packets with the 8-byte headers stripped out.
++  512 is the block_size in the login packet, so it could be set to a
++  different values.
++  In Sybase you can configure a range of valid block sizes.
++  TDS7+ use a default of 4096 as block size.</p>
+ <hr>
+ <p>
+ <a name="login"></a>
+
+commit c22ed544f1f569190b92587eb990ac69c875b2c0
+Author: freddy77 <freddy77>
+Date:   Fri Mar 7 10:57:54 2008 +0000
+
+    added transaction level support
+
+diff --git a/ChangeLog b/ChangeLog
+index 0e5937f..22bac52 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Mar 07 11:57:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/transaction2.c(added):
++	- transaction level support
++
+ Fri Mar 07 09:55:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/tds.html: updated
+ 
+@@ -191,4 +197,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2496 2008/03/07 08:56:34 freddy77 Exp $
++$Id: ChangeLog,v 1.2497 2008/03/07 10:57:54 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 51a0658..190efbc 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.473 2008/02/29 10:54:53 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.474 2008/03/07 10:57:54 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -270,6 +270,40 @@ change_database(TDS_DBC * dbc, char *database, int database_len)
+ 	ODBC_RETURN_(dbc);
+ }
+ 
++static SQLRETURN
++change_txn(TDS_DBC * dbc, SQLUINTEGER txn_isolation)
++{
++	char query[64];
++	const char *level;
++	TDSSOCKET *tds = dbc->tds_socket;
++
++	if (!tds)
++		ODBC_RETURN(dbc, SQL_ERROR);
++
++	level = "READ COMMITTED";
++	switch (txn_isolation) {
++	case SQL_TXN_READ_UNCOMMITTED:
++		level = "READ UNCOMMITTED";
++		break;
++	case SQL_TXN_REPEATABLE_READ:
++		level = "REPEATABLE READ";
++		break;
++	case SQL_TXN_SERIALIZABLE:
++		level = "SERIALIZABLE";
++		break;
++	}
++	sprintf(query, "SET TRANSACTION ISOLATION LEVEL %s", level);
++
++	if (tds->state == TDS_IDLE)
++		tds->query_timeout = dbc->default_query_timeout;
++	if (tds_submit_query(tds, query) != TDS_SUCCEED)
++		ODBC_RETURN(dbc, SQL_ERROR);
++	if (tds_process_simple_query(tds) != TDS_SUCCEED)
++		ODBC_RETURN(dbc, SQL_ERROR);
++
++	ODBC_RETURN_(dbc);
++}
++
+ static void
+ odbc_env_change(TDSSOCKET * tds, int type, char *oldval, char *newval)
+ {
+@@ -323,6 +357,10 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 	if (IS_TDS7_PLUS(dbc->tds_socket))
+ 		dbc->cursor_support = 1;
+ 
++	if (dbc->attr.txn_isolation != SQL_TXN_READ_COMMITTED)
++		if (change_txn(dbc, dbc->attr.txn_isolation) != SQL_SUCCESS)
++			ODBC_RETURN_(dbc);
++
+ 	/* this overwrite any error arrived (wanted behavior, Sybase return error for conversion errors) */
+ 	ODBC_RETURN(dbc, SQL_SUCCESS);
+ }
+@@ -5890,7 +5928,10 @@ _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLI
+ 		break;
+ #endif
+ 	case SQL_ATTR_TXN_ISOLATION:
+-		dbc->attr.txn_isolation = u_value;
++		if (u_value != dbc->attr.txn_isolation) {
++			if (change_txn(dbc, u_value) == SQL_SUCCESS)
++				dbc->attr.txn_isolation = u_value;
++		}
+ 		ODBC_RETURN_(dbc);
+ 		break;
+ 	case SQL_ATTR_TRANSLATE_LIB:
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index 4d90945..b8adb7f 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -68,3 +68,4 @@ rowset
+ cancel
+ test64
+ wchar
++transaction2
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index f6bb215..6254689 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.73 2008/02/29 10:54:53 freddy77 Exp $
++# $Id: Makefile.am,v 1.74 2008/03/07 10:57:54 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -21,7 +21,7 @@ TESTS		=	\
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+-			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT)
++			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -83,6 +83,7 @@ blob1_SOURCES	= blob1.c common.c common.h
+ rowset_SOURCES	= rowset.c common.c common.h
+ cancel_SOURCES = cancel.c common.c common.h
+ wchar_SOURCES = wchar.c common.c common.h
++transaction2_SOURCES = transaction2.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+new file mode 100644
+index 0000000..c7a0fae
+--- /dev/null
++++ b/src/odbc/unittests/transaction2.c
+@@ -0,0 +1,205 @@
++#include "common.h"
++#include <assert.h>
++
++/* Test transaction types */
++
++static char software_version[] = "$Id: transaction2.c,v 1.1 2008/03/07 10:57:54 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static void
++AutoCommit(int onoff)
++{
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0));
++}
++
++static void
++EndTransaction(SQLSMALLINT type)
++{
++	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, type));
++}
++
++#define SWAP(t,a,b) do { t xyz = a; a = b; b = xyz; } while(0)
++#define SWAP_CONN() do { SWAP(HENV,env,Environment); SWAP(HDBC,dbc,Connection); SWAP(HSTMT,stmt,Statement);} while(0)
++
++static HENV env = SQL_NULL_HENV;
++static HDBC dbc = SQL_NULL_HDBC;
++static HSTMT stmt = SQL_NULL_HSTMT;
++
++static int
++CheckDirtyRead(void)
++{
++	SQLRETURN ret;
++
++	/* transaction 1 try to change a row but not commit */
++	Command(Statement, "UPDATE test_transaction SET t = 'second' WHERE n = 1");
++
++	SWAP_CONN();
++
++	/* second transaction try to fetch uncommited row */
++	ret = CommandWithResult(Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
++	if (ret == SQL_ERROR) {
++		EndTransaction(SQL_ROLLBACK);
++		SWAP_CONN();
++		EndTransaction(SQL_ROLLBACK);
++		return 0;	/* no dirty read */
++	}
++
++	CHK(SQLFetch, (Statement));
++	ret = SQLFetch(Statement);
++	if (ret != SQL_NO_DATA)
++		ODBC_REPORT_ERROR("other rows ??");
++	SQLMoreResults(Statement);
++	EndTransaction(SQL_ROLLBACK);
++	SWAP_CONN();
++	EndTransaction(SQL_ROLLBACK);
++	return 1;
++}
++
++static int
++CheckNonrepeatableRead(void)
++{
++	SQLRETURN ret;
++
++	/* transaction 2 read a row */
++	SWAP_CONN();
++	CHK(CommandWithResult, (Statement, "SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1"));
++	SQLMoreResults(Statement);
++
++	/* transaction 1 change a row and commit */
++	SWAP_CONN();
++	ret = CommandWithResult(Statement, "UPDATE test_transaction SET t = 'second' WHERE n = 1");
++	if (ret == SQL_ERROR) {
++		EndTransaction(SQL_ROLLBACK);
++		SWAP_CONN();
++		EndTransaction(SQL_ROLLBACK);
++		SWAP_CONN();
++		return 0;	/* no dirty read */
++	}
++	EndTransaction(SQL_COMMIT);
++
++	SWAP_CONN();
++
++	/* second transaction try to fetch commited row */
++	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
++
++	CHK(SQLFetch, (Statement));
++	ret = SQLFetch(Statement);
++	if (ret != SQL_NO_DATA)
++		ODBC_REPORT_ERROR("other rows ??");
++	SQLMoreResults(Statement);
++	EndTransaction(SQL_ROLLBACK);
++	SWAP_CONN();
++	Command(Statement, "UPDATE test_transaction SET t = 'initial' WHERE n = 1");
++	EndTransaction(SQL_COMMIT);
++	return 1;
++}
++
++static int
++CheckPhantom(void)
++{
++	SQLRETURN ret;
++
++	/* transaction 2 read a row */
++	SWAP_CONN();
++	CHK(CommandWithResult, (Statement, "SELECT * FROM test_transaction WHERE t = 'initial'"));
++	SQLMoreResults(Statement);
++
++	/* transaction 1 insert a row that match critera */
++	SWAP_CONN();
++	ret = CommandWithResult(Statement, "INSERT INTO test_transaction(n, t) VALUES(2, 'initial')");
++	if (ret == SQL_ERROR) {
++		EndTransaction(SQL_ROLLBACK);
++		SWAP_CONN();
++		EndTransaction(SQL_ROLLBACK);
++		SWAP_CONN();
++		return 0;	/* no dirty read */
++	}
++	EndTransaction(SQL_COMMIT);
++
++	SWAP_CONN();
++
++	/* second transaction try to fetch commited row */
++	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial'");
++
++	CHK(SQLFetch, (Statement));
++	CHK(SQLFetch, (Statement));
++	ret = SQLFetch(Statement);
++	if (ret != SQL_NO_DATA)
++		ODBC_REPORT_ERROR("other rows ??");
++	SQLMoreResults(Statement);
++	EndTransaction(SQL_ROLLBACK);
++	SWAP_CONN();
++	Command(Statement, "DELETE test_transaction WHERE n = 2");
++	EndTransaction(SQL_COMMIT);
++	return 1;
++}
++
++static void
++Test(int txn, const char *expected)
++{
++	int dirty, repeatable, phantom;
++	char buf[128];
++
++	SWAP_CONN();
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
++	SWAP_CONN();
++
++	dirty = CheckDirtyRead();
++	repeatable = CheckNonrepeatableRead();
++	phantom = CheckPhantom();
++
++	sprintf(buf, "dirty %d non repeatable %d phantom %d", dirty, repeatable, phantom);
++	if (strcmp(buf, expected) != 0) {
++		fprintf(stderr, "detected wrong TXN\nexpected '%s' got '%s'\n", expected, buf);
++		exit(1);
++	}
++}
++
++int
++main(int argc, char *argv[])
++{
++	Connect();
++
++	/* here we can't use temporary table cause we use two connection */
++	Command(Statement, "IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
++	Command(Statement, "CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
++	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
++
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++
++	/* TODO test returned error */
++#if 0
++	/* SQL error S1009 -- Invalid argument value */
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0));
++#endif
++
++	AutoCommit(SQL_AUTOCOMMIT_OFF);
++
++	/* save this connection and do another */
++	SWAP_CONN();
++
++	Connect();
++
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++	AutoCommit(SQL_AUTOCOMMIT_OFF);
++
++	SWAP_CONN();
++
++	Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
++	Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
++	Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
++	Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
++
++	Disconnect();
++
++	SWAP_CONN();
++
++	EndTransaction(SQL_COMMIT);
++
++	/* Sybase do not accept DROP TABLE during a transaction */
++	AutoCommit(SQL_AUTOCOMMIT_ON);
++	Command(Statement, "DROP TABLE test_transaction");
++
++	Disconnect();
++	return 0;
++}
+
+commit 336e1d70c3f0bf03429a18400bf4889b3adeaef7
+Author: freddy77 <freddy77>
+Date:   Fri Mar 7 15:40:57 2008 +0000
+
+    improved transaction2 odbc test
+
+diff --git a/ChangeLog b/ChangeLog
+index 22bac52..5c9aed3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar 07 16:40:16 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/transaction2.c: improved
++
+ Fri Mar 07 11:57:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am:
+@@ -197,4 +200,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2497 2008/03/07 10:57:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2498 2008/03/07 15:40:57 freddy77 Exp $
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index c7a0fae..3842615 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,9 +3,26 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.1 2008/03/07 10:57:54 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.2 2008/03/07 15:40:57 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++static char odbc_err[256];
++static char odbc_sqlstate[6];
++
++static void
++ReadError(void)
++{
++	memset(odbc_err, 0, sizeof(odbc_err));
++	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
++	if (!SQL_SUCCEEDED
++	    (SQLGetDiagRec
++	     (SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
++		printf("SQLGetDiagRec should not fail\n");
++		exit(1);
++	}
++	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
++}
++
+ static void
+ AutoCommit(int onoff)
+ {
+@@ -134,6 +151,36 @@ CheckPhantom(void)
+ 	return 1;
+ }
+ 
++static int test_with_connect = 0;
++
++static void
++ConnectWithTxn(int txn)
++{
++	int res;
++	char command[512];
++
++	CHK(SQLAllocEnv, (&Environment));
++	CHK(SQLSetEnvAttr, (Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER));
++
++	CHK(SQLAllocConnect, (Environment, &Connection));
++
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
++	res = SQLConnect(Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS);
++	if (!SQL_SUCCEEDED(res))
++		ODBC_REPORT_ERROR("Unable to open data source\n");
++
++	CHK(SQLAllocStmt, (Connection, &Statement));
++
++	sprintf(command, "use %s", DATABASE);
++	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) command, SQL_NTS)))
++		ODBC_REPORT_ERROR("Unable to execute statement\n");
++
++#ifndef TDS_NO_DM
++	/* unixODBC seems to require it */
++	SQLMoreResults(Statement);
++#endif
++}
++
+ static void
+ Test(int txn, const char *expected)
+ {
+@@ -141,7 +188,14 @@ Test(int txn, const char *expected)
+ 	char buf[128];
+ 
+ 	SWAP_CONN();
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
++	if (test_with_connect) {
++		Disconnect();
++		ConnectWithTxn(txn);
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++		AutoCommit(SQL_AUTOCOMMIT_OFF);
++	} else {
++		CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
++	}
+ 	SWAP_CONN();
+ 
+ 	dirty = CheckDirtyRead();
+@@ -158,22 +212,55 @@ Test(int txn, const char *expected)
+ int
+ main(int argc, char *argv[])
+ {
++	SQLRETURN ret;
++
++	use_odbc_version3 = 1;
+ 	Connect();
+ 
++	/* Invalid argument value */
++	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0);
++	ReadError();
++	if (ret != SQL_ERROR || strcmp(odbc_sqlstate, "HY024") != 0) {
++		Disconnect();
++		fprintf(stderr, "Unexpected success\n");
++		return 1;
++	}
++
+ 	/* here we can't use temporary table cause we use two connection */
+ 	Command(Statement, "IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
+ 	Command(Statement, "CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
+-	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
+ 
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
+ 
+-	/* TODO test returned error */
+-#if 0
+-	/* SQL error S1009 -- Invalid argument value */
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0));
+-#endif
+-
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
++	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
++
++	/* test setting with active transaction "Operation invalid at this time" */
++	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0);
++	ReadError();
++	if (ret != SQL_ERROR || strcmp(odbc_sqlstate, "HY011") != 0) {
++		Disconnect();
++		fprintf(stderr, "Unexpected success\n");
++		return 1;
++	}
++
++	EndTransaction(SQL_COMMIT);
++
++	Command(Statement, "SELECT * FROM test_transaction");
++
++	/* test setting with pending data */
++	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0);
++	ReadError();
++	if (ret != SQL_ERROR || strcmp(odbc_sqlstate, "HY011") != 0) {
++		Disconnect();
++		fprintf(stderr, "Unexpected success\n");
++		return 1;
++	}
++
++	SQLMoreResults(Statement);
++
++	EndTransaction(SQL_COMMIT);
++
+ 
+ 	/* save this connection and do another */
+ 	SWAP_CONN();
+@@ -190,6 +277,13 @@ main(int argc, char *argv[])
+ 	Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
+ 	Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
+ 
++	test_with_connect = 1;
++
++	Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
++	Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
++	Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
++	Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
++
+ 	Disconnect();
+ 
+ 	SWAP_CONN();
+
+commit c1b8c70982ac0f6b1942c1f0a5e569f4dea2ed0f
+Author: freddy77 <freddy77>
+Date:   Tue Mar 11 08:36:41 2008 +0000
+
+    fix a problem with cvs and branches
+
+diff --git a/ChangeLog b/ChangeLog
+index 5c9aed3..f49e197 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Mar 11 09:36:11 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/encodings.pl: fix a problem with cvs and branches
++
+ Fri Mar 07 16:40:16 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/transaction2.c: improved
+ 
+@@ -200,4 +203,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2498 2008/03/07 15:40:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2499 2008/03/11 08:36:41 freddy77 Exp $
+diff --git a/src/tds/encodings.pl b/src/tds/encodings.pl
+index 2346c18..719482e 100755
+--- a/src/tds/encodings.pl
++++ b/src/tds/encodings.pl
+@@ -30,7 +30,7 @@ $filename = "${srcdir}sybase_character_sets.h";
+ open(OUT, ">$filename") or die qq($basename: could not open "$filename"\n);
+ print OUT "/*\n";
+ print OUT " * This file produced from $0\n";
+-print OUT ' * $Id: encodings.pl,v 1.10 2005/04/06 06:44:33 jklowden Exp $', "\n";
++print OUT ' * $Id: encodings.pl,v 1.11 2008/03/11 08:36:41 freddy77 Exp $', "\n";
+ print OUT " */\n";
+ 
+ # look up the canonical name
+@@ -64,7 +64,7 @@ while(<DATA>){
+ 
+ 		# grep for similar names, as an aid to the to programmer.  
+ 		$name =~ s/[\-\_]+//g;
+-		print STDERR "$Name:  $name alternative_character_sets.h\n";
++		print STDERR $Name.":  $name alternative_character_sets.h\n";
+ 	}
+ 	$comma = ',';
+ }
+@@ -77,7 +77,7 @@ close(OUT);
+ print "/*\n";
+ $date = localtime;
+ print " * This file produced from $0 on $date\n";
+-print ' * $Id: encodings.pl,v 1.10 2005/04/06 06:44:33 jklowden Exp $', "\n";
++print ' * $Id: encodings.pl,v 1.11 2008/03/11 08:36:41 freddy77 Exp $', "\n";
+ print " */\n";
+ 
+ %charsets = ();
+
+commit d40b619026bc96201e99ff093608c20dd3816867
+Author: freddy77 <freddy77>
+Date:   Tue Mar 11 08:42:30 2008 +0000
+
+    fix auto-commit off before connection
+
+diff --git a/ChangeLog b/ChangeLog
+index f49e197..127da9b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Mar 11 09:42:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix auto-commit off before connection
++
+ Tue Mar 11 09:36:11 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/encodings.pl: fix a problem with cvs and branches
+ 
+@@ -203,4 +206,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2499 2008/03/11 08:36:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2500 2008/03/11 08:42:30 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 190efbc..57d078c 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.474 2008/03/07 10:57:54 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.475 2008/03/11 08:42:30 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -224,6 +224,9 @@ change_autocommit(TDS_DBC * dbc, int state)
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
+ 		dbc->attr.autocommit = state;
++	} else {
++		/* if not connected we will change auto-commit after login */
++		dbc->attr.autocommit = state;
+ 	}
+ 	ODBC_RETURN_(dbc);
+ }
+@@ -358,7 +361,11 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 		dbc->cursor_support = 1;
+ 
+ 	if (dbc->attr.txn_isolation != SQL_TXN_READ_COMMITTED)
+-		if (change_txn(dbc, dbc->attr.txn_isolation) != SQL_SUCCESS)
++		if (!SQL_SUCCEEDED(change_txn(dbc, dbc->attr.txn_isolation)))
++			ODBC_RETURN_(dbc);
++
++	if (dbc->attr.autocommit != SQL_AUTOCOMMIT_ON)
++		if (!SQL_SUCCEEDED(change_autocommit(dbc, dbc->attr.autocommit)))
+ 			ODBC_RETURN_(dbc);
+ 
+ 	/* this overwrite any error arrived (wanted behavior, Sybase return error for conversion errors) */
+
+commit 265159a73de9867b225f5b6887466d299e1e7492
+Author: freddy77 <freddy77>
+Date:   Wed Mar 12 13:35:48 2008 +0000
+
+    improve auto-commit
+
+diff --git a/ChangeLog b/ChangeLog
+index 127da9b..7122046 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Wed Mar 12 14:34:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix auto-commit set
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	- make possible to override connection attributes
++	* src/odbc/unittests/transaction2.c:
++	- improve
++
+ Tue Mar 11 09:42:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix auto-commit off before connection
+ 
+@@ -206,4 +213,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2500 2008/03/11 08:42:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2501 2008/03/12 13:35:48 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 57d078c..12682e8 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.475 2008/03/11 08:42:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.476 2008/03/12 13:35:49 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -280,11 +280,10 @@ change_txn(TDS_DBC * dbc, SQLUINTEGER txn_isolation)
+ 	const char *level;
+ 	TDSSOCKET *tds = dbc->tds_socket;
+ 
+-	if (!tds)
+-		ODBC_RETURN(dbc, SQL_ERROR);
+-
+-	level = "READ COMMITTED";
+ 	switch (txn_isolation) {
++	case SQL_TXN_READ_COMMITTED:
++		level = "READ COMMITTED";
++		break;
+ 	case SQL_TXN_READ_UNCOMMITTED:
+ 		level = "READ UNCOMMITTED";
+ 		break;
+@@ -294,17 +293,28 @@ change_txn(TDS_DBC * dbc, SQLUINTEGER txn_isolation)
+ 	case SQL_TXN_SERIALIZABLE:
+ 		level = "SERIALIZABLE";
+ 		break;
++	default:
++		odbc_errs_add(&dbc->errs, "HY024", NULL);
++		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+-	sprintf(query, "SET TRANSACTION ISOLATION LEVEL %s", level);
+ 
+-	if (tds->state == TDS_IDLE)
+-		tds->query_timeout = dbc->default_query_timeout;
++	/* if not connected return success, will be set after connection */
++	if (!tds)
++		return SQL_SUCCESS;
++
++	if (tds->state != TDS_IDLE) {
++		odbc_errs_add(&dbc->errs, "HY011", NULL);
++		ODBC_RETURN(dbc, SQL_ERROR);
++	}
++
++	tds->query_timeout = dbc->default_query_timeout;
++	sprintf(query, "SET TRANSACTION ISOLATION LEVEL %s", level);
+ 	if (tds_submit_query(tds, query) != TDS_SUCCEED)
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	if (tds_process_simple_query(tds) != TDS_SUCCEED)
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 
+-	ODBC_RETURN_(dbc);
++	return SQL_SUCCESS;
+ }
+ 
+ static void
+@@ -361,7 +371,7 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 		dbc->cursor_support = 1;
+ 
+ 	if (dbc->attr.txn_isolation != SQL_TXN_READ_COMMITTED)
+-		if (!SQL_SUCCEEDED(change_txn(dbc, dbc->attr.txn_isolation)))
++		if (change_txn(dbc, dbc->attr.txn_isolation) != SQL_SUCCESS)
+ 			ODBC_RETURN_(dbc);
+ 
+ 	if (dbc->attr.autocommit != SQL_AUTOCOMMIT_ON)
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 78f58fe..f7b3283 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,13 +12,14 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.43 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.44 2008/03/12 13:35:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+ HDBC Connection;
+ HSTMT Statement;
+ int use_odbc_version3 = 0;
++void (*odbc_set_conn_attr)(void) = NULL;
+ 
+ char USER[512];
+ char SERVER[512];
+@@ -193,17 +194,18 @@ Connect(void)
+ 	printf("connection parameters:\nserver:   '%s'\nuser:     '%s'\npassword: '%s'\ndatabase: '%s'\n",
+ 	       SERVER, USER, "????" /* PASSWORD */ , DATABASE);
+ 
++	if (odbc_set_conn_attr)
++		(*odbc_set_conn_attr)();
++
+ 	res = SQLConnect(Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS);
+ 	if (!SQL_SUCCEEDED(res)) {
+ 		printf("Unable to open data source (ret=%d)\n", res);
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS) {
+ 		printf("Unable to allocate statement\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ 	sprintf(command, "use %s", DATABASE);
+@@ -212,7 +214,6 @@ Connect(void)
+ 	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) command, SQL_NTS))) {
+ 		printf("Unable to execute statement\n");
+ 		CheckReturn();
+-		exit(1);
+ 	}
+ 
+ #ifndef TDS_NO_DM
+@@ -311,8 +312,6 @@ CheckCols(int n, int line, const char * file)
+ 			return;
+ 		fprintf(stderr, "%s:%d: Unable to get column numbers\n", file, line);
+ 		CheckReturn();
+-		Disconnect();
+-		exit(1);
+ 	}
+ 
+ 	if (cols != n) {
+@@ -334,8 +333,6 @@ CheckRows(int n, int line, const char * file)
+ 			return;
+ 		fprintf(stderr, "%s:%d: Unable to get row\n", file, line);
+ 		CheckReturn();
+-		Disconnect();
+-		exit(1);
+ 	}
+ 
+ 	if (rows != n) {
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index b74e162..5e89ddf 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.22 2008/01/29 14:30:48 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.23 2008/03/12 13:35:50 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -37,6 +37,7 @@ extern HENV Environment;
+ extern HDBC Connection;
+ extern HSTMT Statement;
+ extern int use_odbc_version3;
++extern void (*odbc_set_conn_attr)(void);
+ 
+ extern char USER[512];
+ extern char SERVER[512];
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index 3842615..27353c4 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.2 2008/03/07 15:40:57 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.3 2008/03/12 13:35:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -153,32 +153,22 @@ CheckPhantom(void)
+ 
+ static int test_with_connect = 0;
+ 
++static int global_txn;
++
+ static void
+-ConnectWithTxn(int txn)
++my_attrs(void)
+ {
+-	int res;
+-	char command[512];
+-
+-	CHK(SQLAllocEnv, (&Environment));
+-	CHK(SQLSetEnvAttr, (Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER));
+-
+-	CHK(SQLAllocConnect, (Environment, &Connection));
+-
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
+-	res = SQLConnect(Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS);
+-	if (!SQL_SUCCEEDED(res))
+-		ODBC_REPORT_ERROR("Unable to open data source\n");
+-
+-	CHK(SQLAllocStmt, (Connection, &Statement));
+-
+-	sprintf(command, "use %s", DATABASE);
+-	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) command, SQL_NTS)))
+-		ODBC_REPORT_ERROR("Unable to execute statement\n");
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(global_txn), 0));
++	AutoCommit(SQL_AUTOCOMMIT_OFF);
++}
+ 
+-#ifndef TDS_NO_DM
+-	/* unixODBC seems to require it */
+-	SQLMoreResults(Statement);
+-#endif
++static void
++ConnectWithTxn(int txn)
++{
++	global_txn = txn;
++	odbc_set_conn_attr = my_attrs;
++	Connect();
++	odbc_set_conn_attr = NULL;
+ }
+ 
+ static void
+@@ -192,7 +182,6 @@ Test(int txn, const char *expected)
+ 		Disconnect();
+ 		ConnectWithTxn(txn);
+ 		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
+-		AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 	} else {
+ 		CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
+ 	}
+@@ -235,6 +224,7 @@ main(int argc, char *argv[])
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
+ 
++#if ENABLE_DEVELOPING
+ 	/* test setting with active transaction "Operation invalid at this time" */
+ 	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0);
+ 	ReadError();
+@@ -243,6 +233,7 @@ main(int argc, char *argv[])
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+ 	}
++#endif
+ 
+ 	EndTransaction(SQL_COMMIT);
+ 
+
+commit ec8cc96a5acd3d0ab0743a190ca77d0d04bf5ed2
+Author: freddy77 <freddy77>
+Date:   Wed Mar 12 13:54:32 2008 +0000
+
+    handle SQL_TIMESTAMP like SQL_TYPE_TIMESTAMP
+
+diff --git a/ChangeLog b/ChangeLog
+index 7122046..b2ec0c6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar 12 14:53:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: handle SQL_TIMESTAMP like SQL_TYPE_TIMESTAMP
++
+ Wed Mar 12 14:34:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix auto-commit set
+ 	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
+@@ -213,4 +216,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2501 2008/03/12 13:35:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2502 2008/03/12 13:54:32 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 12682e8..6529b73 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.476 2008/03/12 13:35:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.477 2008/03/12 13:54:33 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -1954,13 +1954,14 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 			*pfDesc = 15;
+ 			break;
+ 		}
+-		if (drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP) {
++		if (drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP || drec->sql_desc_concise_type == SQL_TIMESTAMP) {
+ 			*pfDesc = drec->sql_desc_precision ? 23 : 16;
+ 			break;
+ 		}
+ 	case SQL_DESC_PRECISION:	/* this section may be wrong */
+ 		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL
+-		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
++		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP
++		    || drec->sql_desc_concise_type == SQL_TIMESTAMP)
+ 			IOUT(SQLSMALLINT, drec->sql_desc_precision);
+ 		else
+ 			*pfDesc = drec->sql_desc_length;
+@@ -1969,7 +1970,9 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 	case SQL_COLUMN_SCALE:
+ 	case SQL_DESC_SCALE:	/* this section may be wrong */
+ 		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL
+-		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP || drec->sql_desc_concise_type == SQL_FLOAT)
++		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP
++		    || drec->sql_desc_concise_type == SQL_TIMESTAMP
++		    || drec->sql_desc_concise_type == SQL_FLOAT)
+ 			IOUT(SQLSMALLINT, drec->sql_desc_scale);
+ 		else
+ 			*pfDesc = 0;
+@@ -2403,7 +2406,9 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 		IOUT(SQLSMALLINT, drec->sql_desc_parameter_type);
+ 		break;
+ 	case SQL_DESC_PRECISION:
+-		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL || drec->sql_desc_concise_type == SQL_TIMESTAMP)
++		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL
++		    || drec->sql_desc_concise_type == SQL_TIMESTAMP
++		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
+ 			IOUT(SQLSMALLINT, drec->sql_desc_precision);
+ 		else
+ 			/* TODO support date/time */
+@@ -2416,7 +2421,9 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ #endif
+ 	case SQL_DESC_SCALE:
+ 		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL
+-		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP || drec->sql_desc_concise_type == SQL_FLOAT)
++		    || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP
++		    || drec->sql_desc_concise_type == SQL_TIMESTAMP
++		    || drec->sql_desc_concise_type == SQL_FLOAT)
+ 			IOUT(SQLSMALLINT, drec->sql_desc_scale);
+ 		else
+ 			*((SQLSMALLINT *) Value) = 0;
+@@ -2814,7 +2821,7 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 			return SQL_ERROR;
+ 
+ 		/* TODO other types for date ?? SQL_TYPE_DATE, SQL_TYPE_TIME */
+-		if (drec->sql_desc_concise_type == SQL_TIMESTAMP)
++		if (drec->sql_desc_concise_type == SQL_TIMESTAMP || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
+ 			drec->sql_desc_length = sizeof("2000-01-01 12:00:00.0000")-1;
+ 		else
+ 			drec->sql_desc_length = col->column_size;
+
+commit fef64066a20e845bb7db85a5dd0dbb620d636cee
+Author: freddy77 <freddy77>
+Date:   Wed Mar 12 14:26:07 2008 +0000
+
+    test proper handle type
+
+diff --git a/ChangeLog b/ChangeLog
+index b2ec0c6..0735575 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar 12 15:25:11 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/error.c: check proper handle type
++
+ Wed Mar 12 14:53:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: handle SQL_TIMESTAMP like SQL_TYPE_TIMESTAMP
+ 
+@@ -216,4 +219,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2502 2008/03/12 13:54:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2503 2008/03/12 14:26:07 freddy77 Exp $
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index f06d7d0..260e475 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.49 2007/10/16 15:12:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.50 2008/03/12 14:26:07 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -250,60 +250,64 @@ rank_errors(struct _sql_errors *errs)
+ 	struct _sql_error swapbuf;
+ 	char istrans;
+ 
+-	if (errs->ranked == 0 && errs->num_errors > 1) {
+-		/* Find the highest of all unranked errors until there are none left */
+-		for (settled = 0; settled < errs->num_errors; settled++) {
+-			best = -1;
+-			for (current = settled; current < errs->num_errors; current++) {
+-				istrans = 0;
+-				switch (errs->errs[current].native) {
+-				case 1205:
+-				case 1211:
+-				case 2625:
+-				case 3309:
+-				case 7112:
+-				case 266:
+-				case 277:
+-				case 611:
+-				case 628:
+-				case 3902:
+-				case 3903:
+-				case 3906:
+-				case 3908:
+-				case 6401:
++	/* already ranked or nothing to rank */
++	if (errs->ranked != 0 || errs->num_errors <= 1) {
++		errs->ranked = 1;
++		return;
++	}
++
++	/* Find the highest of all unranked errors until there are none left */
++	for (settled = 0; settled < errs->num_errors; settled++) {
++		best = -1;
++		for (current = settled; current < errs->num_errors; current++) {
++			istrans = 0;
++			switch (errs->errs[current].native) {
++			case 1205:
++			case 1211:
++			case 2625:
++			case 3309:
++			case 7112:
++			case 266:
++			case 277:
++			case 611:
++			case 628:
++			case 3902:
++			case 3903:
++			case 3906:
++			case 3908:
++			case 6401:
++				istrans = 1;
++				break;
++			}
++
++			if (istrans == 0) {
++				if (strcmp(errs->errs[current].state3,"25000") == 0)
++					istrans = 1;
++				else if (strcmp(errs->errs[current].state3,"S1012") == 0)
++					istrans = 1;
++				else if (strcmp(errs->errs[current].state3,"08007") == 0)
+ 					istrans = 1;
+-					break;
+-				}
+-
+-				if (istrans == 0) {
+-					if (strcmp(errs->errs[current].state3,"25000") == 0)
+-						istrans = 1;
+-					else if (strcmp(errs->errs[current].state3,"S1012") == 0)
+-						istrans = 1;
+-					else if (strcmp(errs->errs[current].state3,"08007") == 0)
+-						istrans = 1;
+-				}
+-
+-				/* Transaction errors are always best */
+-				if (istrans == 1 && errs->errs[current].msgstate >= 10)	{
+-					best = current;
+-					break;
+-				}
+-
+-				if (best == -1)
+-					best = current;
+-
+-				/* Non-terminating comparisons only below this point */
+-				if (errs->errs[current].msgstate > errs->errs[best].msgstate)
+-					best = current;
+ 			}
+ 
+-			/* swap settled position with best */
+-			if (best != settled) {
+-				swapbuf = errs->errs[settled];
+-				errs->errs[settled] = errs->errs[best];
+-				errs->errs[best] = swapbuf;
++			/* Transaction errors are always best */
++			if (istrans == 1 && errs->errs[current].msgstate >= 10)	{
++				best = current;
++				break;
+ 			}
++
++			if (best == -1)
++				best = current;
++
++			/* Non-terminating comparisons only below this point */
++			if (errs->errs[current].msgstate > errs->errs[best].msgstate)
++				best = current;
++		}
++
++		/* swap settled position with best */
++		if (best != settled) {
++			swapbuf = errs->errs[settled];
++			errs->errs[settled] = errs->errs[best];
++			errs->errs[best] = swapbuf;
+ 		}
+ 	}
+ 	errs->ranked = 1;
+@@ -506,6 +510,7 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	static const char msgprefix[] = "[FreeTDS][SQL Server]";
+ 
+ 	SQLINTEGER odbc_ver = SQL_OV_ODBC2;
++	SQLHANDLE parent;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n", 
+ 			handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+@@ -513,7 +518,7 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	if (numRecord <= 0 || cbErrorMsgMax < 0)
+ 		return SQL_ERROR;
+ 
+-	if (!handle)
++	if (!handle || ((struct _hchk *) handle)->htype != handleType)
+ 		return SQL_INVALID_HANDLE;
+ 
+ 	switch (handleType) {
+@@ -531,7 +536,14 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
+ 		errs = &((TDS_ENV *) handle)->errs;
+ 		break;
+-
++	case SQL_HANDLE_DESC:
++		parent = ((TDS_DESC *) handle)->parent;
++		if (((struct _hchk *) parent)->htype == SQL_HANDLE_DBC)
++			odbc_ver = ((TDS_DBC *) parent)->env->attr.odbc_version;
++		else
++			odbc_ver = ((TDS_STMT *) parent)->dbc->env->attr.odbc_version;
++		errs = &((TDS_DESC *) handle)->errs;
++		break;
+ 	default:
+ 		return SQL_INVALID_HANDLE;
+ 	}
+@@ -589,8 +601,6 @@ SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, S
+ 	} else
+ 		return SQL_INVALID_HANDLE;
+ 
+-	rank_errors(errs);
+-
+ 	result = _SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+ 
+ 	if (result == SQL_SUCCESS) {
+@@ -633,7 +643,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	if (cbBuffer < 0)
+ 		return SQL_ERROR;
+ 
+-	if (!handle)
++	if (!handle  || ((struct _hchk *) handle)->htype != handleType)
+ 		return SQL_INVALID_HANDLE;
+ 
+ 	switch (handleType) {
+
+commit 29a5ac91b1b3aa94cfcf116f1f8f755767865ee5
+Author: jklowden <jklowden>
+Date:   Wed Mar 12 21:34:09 2008 +0000
+
+    Posted 0.82RC3
+
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index b940620..d68c673 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.14 2008/02/28 23:27:10 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.15 2008/03/12 21:34:09 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -37,9 +37,23 @@ News&nbsp;&nbsp;|&nbsp;
+ <tr>
+ <td>
+ <br />
++Version 0.82RC3 is now available from 
++<a href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/current/freetds-rc.tgz">
++ftp.ibiblio.org</a>.  (12 March 2008)
++
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>Second Release Candidate available for 0.82</td></tr>
++<tr>
++<td>
++<br />
+ Version 0.82RC2 is now available from 
+ <a href="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/current/freetds-rc.tgz">
+-ftp.ibiblio.org</a>.  
++ftp.ibiblio.org</a>.  (28 February 2008)
+ <br />
+ <br />
+ </td>
+@@ -56,7 +70,7 @@ ftp.ibiblio.org</a>.  This important release will incorporate many new features,
+ 23,710 lines of code.  Detailed information can be found in the NEWS file included in the 
+ the distribution.  
+ <p>Version 0.82 will be the successor to 0.64, released in July 2006.  The jump in version 
+-number represents the progress toward version 1.0.  
++number represents the progress toward version 1.0.  (17 January 2008)
+ <br />
+ <br />
+ </td>
+
+commit 0e00d0b2474183daa11ee1f18cab3e6fba2ebc18
+Author: freddy77 <freddy77>
+Date:   Thu Mar 13 13:23:30 2008 +0000
+
+    simplify error.c
+
+diff --git a/ChangeLog b/ChangeLog
+index 0735575..cfa0bba 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Thu Mar 13 14:22:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/error.c:
++	- make errs offset constant in all odbc structures to make 
++	  error.c simpler
++	- support SQL_HANDLE_DESC in SQLGetDiagField 
++	* src/odbc/odbc.c: remove TODO comment
++	* src/odbc/odbc_checks.c: typo
++
+ Wed Mar 12 15:25:11 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/error.c: check proper handle type
+ 
+@@ -219,4 +227,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2503 2008/03/12 14:26:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2504 2008/03/13 13:23:30 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index a58d547..5efd600 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.104 2008/01/14 19:21:06 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.105 2008/03/13 13:23:31 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -177,11 +177,11 @@ struct _drecord
+ struct _hdesc
+ {
+ 	SQLSMALLINT htype;	/* do not reorder this field */
++	struct _sql_errors errs;	/* do not reorder this field */
+ 	int type;
+ 	SQLHANDLE parent;
+ 	struct _dheader header;
+ 	struct _drecord *records;
+-	struct _sql_errors errs;
+ };
+ 
+ typedef struct _hdesc TDS_DESC;
+@@ -202,13 +202,14 @@ struct _heattr
+ struct _hchk
+ {
+ 	SQLSMALLINT htype;	/* do not reorder this field */
++	struct _sql_errors errs;	/* do not reorder this field */
+ };
+ 
+ struct _henv
+ {
+ 	SQLSMALLINT htype;	/* do not reorder this field */
++	struct _sql_errors errs;	/* do not reorder this field */
+ 	TDSCONTEXT *tds_ctx;
+-	struct _sql_errors errs;
+ 	struct _heattr attr;
+ };
+ 
+@@ -242,6 +243,7 @@ struct _hstmt;
+ struct _hdbc
+ {
+ 	SQLSMALLINT htype;	/* do not reorder this field */
++	struct _sql_errors errs;	/* do not reorder this field */
+ 	struct _henv *env;
+ 	TDSSOCKET *tds_socket;
+ 	DSTR dsn;
+@@ -254,7 +256,6 @@ struct _hdbc
+ 	struct _hstmt *current_statement;
+ 	/** list of all statements allocated from this connection */
+ 	struct _hstmt *stmt_list;
+-	struct _sql_errors errs;
+ 	struct _hcattr attr;
+ 	/** descriptors associated to connection */
+ 	TDS_DESC *uad[TDS_MAX_APP_DESC];
+@@ -326,6 +327,7 @@ typedef enum
+ struct _hstmt
+ {
+ 	SQLSMALLINT htype;	/* do not reorder this field */
++	struct _sql_errors errs;	/* do not reorder this field */
+ 	struct _hdbc *dbc;
+ 	/** query to execute */
+ 	char *query;
+@@ -361,7 +363,6 @@ struct _hstmt
+ 	TDS_ODBC_ROW_STATUS row_status;
+ 	/* do NOT free dynamic, free from socket or attach to connection */
+ 	TDSDYNAMIC *dyn;
+-	struct _sql_errors errs;
+ 	TDS_DESC *ard, *ird, *apd, *ipd;
+ 	TDS_DESC *orig_ard, *orig_apd;
+ 	SQLULEN sql_rowset_size;
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 260e475..c9e0772 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.50 2008/03/12 14:26:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.51 2008/03/13 13:23:31 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -503,7 +503,7 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	       SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
+ {
+ 	SQLRETURN result;
+-	struct _sql_errors *errs = NULL;
++	struct _sql_errors *errs;
+ 	const char *msg;
+ 	char *p;
+ 
+@@ -518,31 +518,28 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	if (numRecord <= 0 || cbErrorMsgMax < 0)
+ 		return SQL_ERROR;
+ 
+-	if (!handle || ((struct _hchk *) handle)->htype != handleType)
++	if (!handle || ((TDS_CHK *) handle)->htype != handleType)
+ 		return SQL_INVALID_HANDLE;
+ 
++	errs = &((TDS_CHK *) handle)->errs;
+ 	switch (handleType) {
+ 	case SQL_HANDLE_STMT:
+ 		odbc_ver = ((TDS_STMT *) handle)->dbc->env->attr.odbc_version;
+-		errs = &((TDS_STMT *) handle)->errs;
+ 		break;
+ 
+ 	case SQL_HANDLE_DBC:
+ 		odbc_ver = ((TDS_DBC *) handle)->env->attr.odbc_version;
+-		errs = &((TDS_DBC *) handle)->errs;
+ 		break;
+ 
+ 	case SQL_HANDLE_ENV:
+ 		odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
+-		errs = &((TDS_ENV *) handle)->errs;
+ 		break;
+ 	case SQL_HANDLE_DESC:
+ 		parent = ((TDS_DESC *) handle)->parent;
+-		if (((struct _hchk *) parent)->htype == SQL_HANDLE_DBC)
++		if (((TDS_CHK *) parent)->htype == SQL_HANDLE_DBC)
+ 			odbc_ver = ((TDS_DBC *) parent)->env->attr.odbc_version;
+ 		else
+ 			odbc_ver = ((TDS_STMT *) parent)->dbc->env->attr.odbc_version;
+-		errs = &((TDS_DESC *) handle)->errs;
+ 		break;
+ 	default:
+ 		return SQL_INVALID_HANDLE;
+@@ -579,7 +576,6 @@ SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, S
+ 	 SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
+ {
+ 	SQLRETURN result;
+-	struct _sql_errors *errs = NULL;
+ 	SQLSMALLINT type;
+ 	SQLHANDLE handle;
+ 
+@@ -587,15 +583,12 @@ SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, S
+ 			henv, hdbc, hstmt, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+ 
+ 	if (hstmt) {
+-		errs = &((TDS_STMT *) hstmt)->errs;
+ 		handle = hstmt;
+ 		type = SQL_HANDLE_STMT;
+ 	} else if (hdbc) {
+-		errs = &((TDS_DBC *) hdbc)->errs;
+ 		handle = hdbc;
+ 		type = SQL_HANDLE_DBC;
+ 	} else if (henv) {
+-		errs = &((TDS_ENV *) henv)->errs;
+ 		handle = henv;
+ 		type = SQL_HANDLE_ENV;
+ 	} else
+@@ -605,7 +598,7 @@ SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, S
+ 
+ 	if (result == SQL_SUCCESS) {
+ 		/* remove first error */
+-		odbc_errs_pop(errs);
++		odbc_errs_pop(&((TDS_CHK *) handle)->errs);
+ 	}
+ 
+ 	return result;
+@@ -627,7 +620,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer)
+ {
+ 	SQLRETURN result = SQL_SUCCESS;
+-	struct _sql_errors *errs = NULL;
++	struct _sql_errors *errs;
+ 	const char *msg;
+ 
+ 	SQLINTEGER odbc_ver = SQL_OV_ODBC2;
+@@ -635,6 +628,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	TDS_STMT *stmt = NULL;
+ 	TDS_DBC *dbc = NULL;
+ 	TDS_ENV *env = NULL;
++	SQLHANDLE parent;
+ 	char tmp[16];
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagField(%d, %p, %d, %d, %p, %d, %p)\n", 
+@@ -643,7 +637,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	if (cbBuffer < 0)
+ 		return SQL_ERROR;
+ 
+-	if (!handle  || ((struct _hchk *) handle)->htype != handleType)
++	if (!handle  || ((TDS_CHK *) handle)->htype != handleType)
+ 		return SQL_INVALID_HANDLE;
+ 
+ 	switch (handleType) {
+@@ -651,23 +645,32 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		stmt = ((TDS_STMT *) handle);
+ 		dbc = stmt->dbc;
+ 		env = dbc->env;
+-		errs = &stmt->errs;
+ 		break;
+ 
+ 	case SQL_HANDLE_DBC:
+ 		dbc = ((TDS_DBC *) handle);
+ 		env = dbc->env;
+-		errs = &dbc->errs;
+ 		break;
+ 
+ 	case SQL_HANDLE_ENV:
+ 		env = ((TDS_ENV *) handle);
+-		errs = &env->errs;
++		break;
++
++	case SQL_HANDLE_DESC:
++		parent = ((TDS_DESC *) handle)->parent;
++		if (((TDS_CHK *) parent)->htype == SQL_HANDLE_DBC) {
++			dbc = (TDS_DBC *) parent;
++		} else {
++			stmt = (TDS_STMT *) parent;
++			dbc = stmt->dbc;
++		}
++		env = dbc->env;
+ 		break;
+ 
+ 	default:
+ 		return SQL_INVALID_HANDLE;
+ 	}
++	errs = &((TDS_CHK *) handle)->errs;
+ 	odbc_ver = env->attr.odbc_version;
+ 
+ 	/* header (numRecord ignored) */
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 6529b73..0938e37 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.477 2008/03/12 13:54:33 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.478 2008/03/13 13:23:31 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -5602,7 +5602,6 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 		SIVAL = SQL_TC_ALL;
+ 		break;
+ 	case SQL_TXN_ISOLATION_OPTION:
+-		/* TODO check SQLSetConnectAttr support */
+ 		UIVAL = SQL_TXN_READ_COMMITTED | SQL_TXN_READ_UNCOMMITTED | SQL_TXN_REPEATABLE_READ | SQL_TXN_SERIALIZABLE;
+ 		break;
+ 	case SQL_UNION:
+diff --git a/src/odbc/odbc_checks.c b/src/odbc/odbc_checks.c
+index a55e1a7..713bdcc 100644
+--- a/src/odbc/odbc_checks.c
++++ b/src/odbc/odbc_checks.c
+@@ -40,7 +40,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_checks.c,v 1.19 2007/05/17 10:33:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_checks.c,v 1.20 2008/03/13 13:23:31 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -113,7 +113,7 @@ odbc_check_struct_extra(void *p)
+ {
+ 	const int invalid_htype = 0;
+ 
+-	switch (((struct _hchk *) p)->htype) {
++	switch (((TDS_CHK *) p)->htype) {
+ 	case SQL_HANDLE_ENV:
+ 		odbc_check_env_extra((TDS_ENV *) p);
+ 		break;
+
+commit 02c780a076896bb6b3a36c379d11b4fa3add8231
+Author: freddy77 <freddy77>
+Date:   Tue Mar 18 08:19:25 2008 +0000
+
+    update
+
+diff --git a/doc/tds.html b/doc/tds.html
+index a0bdf38..28ab6de 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -389,7 +389,7 @@ auth   authentication data
+   <td>0x63</td><td>99</td><td>SYBNTEXT</td><td>7+</td><td>yes</td><td>4</td><td>yes</td>
+ </tr>
+ <tr>
+-  <td>0x67</td><td>103</td><td>SYBNVARCHAR</td><td>7+</td><td>yes</td><td>2</td><td>??</td>
++  <td>0x67</td><td>103</td><td>SYBNVARCHAR</td><td>7+</td><td>yes</td><td>1</td><td></td>
+ </tr>
+ <tr>
+   <td>0x68</td><td>104</td><td>SYBBITN</td><td></td><td>yes</td><td>1</td><td></td>
+@@ -416,10 +416,10 @@ auth   authentication data
+   <td>0x7F</td><td>127</td><td>SYBINT8</td><td></td><td>no</td><td>0</td><td></td>
+ </tr>
+ <tr>
+-  <td>0xA5</td><td>165</td><td>XSYBVARBINARY</td><td>7+</td><td>yes</td><td>2</td><td></td>
++  <td>0xA5</td><td>165</td><td>XSYBVARBINARY</td><td>7+</td><td>yes</td><td>2 *</td><td></td>
+ </tr>
+ <tr>
+-  <td>0xA7</td><td>167</td><td>XSYBVARCHAR</td><td>7+</td><td>yes</td><td>2</td><td>yes</td>
++  <td>0xA7</td><td>167</td><td>XSYBVARCHAR</td><td>7+</td><td>yes</td><td>2 *</td><td>yes</td>
+ </tr>
+ <tr>
+   <td>0xAD</td><td>173</td><td>XSYBBINARY</td><td>7+</td><td>yes</td><td>2</td><td></td>
+@@ -431,13 +431,23 @@ auth   authentication data
+   <td>0xE1</td><td>225</td><td>SYBLONGBINARY</td><td>5</td><td>yes</td><td>4</td><td></td>
+ </tr>
+ <tr>
+-  <td>0xE7</td><td>231</td><td>XSYBNVARCHAR</td><td>7+</td><td>yes</td><td>2</td><td>yes</td>
++  <td>0xE7</td><td>231</td><td>XSYBNVARCHAR</td><td>7+</td><td>yes</td><td>2 *</td><td>yes</td>
+ </tr>
+ <tr>
+   <td>0xEF</td><td>239</td><td>XSYBNCHAR</td><td>7+</td><td>yes</td><td>2</td><td>yes</td>
+ </tr>
+ </table>
+ <hr>
++<p>* Under TDS9+ these types allow size to be -1. These types represents varchar(max), varbinary(max) and nvarchar(max).
++Data representation for these types change in this way:
++<ul>
++ <li>size is 64 bit not 16 bit</li>
++ <li>if size is -1 meaning NULL</li>
++ <li>if size is -2 size is unknown</li>
++ <li>data is splitted in chunks where ever chunk start with a 32 bit size</li>
++ <li>a chunk with size &lt;= 0 is the terminal chunk</li>
++</ul>
++</p>
+ <p>
+ <a name="collate"></a>
+ <h2 class="section">Collate type - TDS8</h2>
+
+commit 69922d6709c73175d82bc4535850ed11e3a9fa54
+Author: freddy77 <freddy77>
+Date:   Tue Mar 18 08:22:23 2008 +0000
+
+    consistent test
+
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index 27353c4..8c54082 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.3 2008/03/12 13:35:50 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.4 2008/03/18 08:22:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -224,7 +224,7 @@ main(int argc, char *argv[])
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
+ 
+-#if ENABLE_DEVELOPING
++#ifdef ENABLE_DEVELOPING
+ 	/* test setting with active transaction "Operation invalid at this time" */
+ 	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0);
+ 	ReadError();
+
+commit caa5c9a05d262e85f96275bcebcddc27d148b877
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 17:29:57 2008 +0000
+
+    applied ML patches from Johnny C. Lam for calout locations
+     and gnutls test
+
+diff --git a/ChangeLog b/ChangeLog
+index cfa0bba..e822060 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sun Mar 23 13:14:05 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* configure.ac doc/Makefile.am
++	- applied ML patches from Johnny C. Lam for calout locations
++	- and gnutls test
++	
+ Thu Mar 13 14:22:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/error.c:
+ 	- make errs offset constant in all odbc structures to make 
+@@ -227,4 +232,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2504 2008/03/13 13:23:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2505 2008/03/23 17:29:57 jklowden Exp $
+diff --git a/configure.ac b/configure.ac
+index 26bf18f..8fed8b9 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.34 2008/02/15 11:00:40 freddy77 Exp $
++dnl $Id: configure.ac,v 1.35 2008/03/23 17:29:57 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.34 $)
++AC_REVISION($Revision: 1.35 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -621,7 +621,7 @@ AC_SUBST(ODBCNODMLIBAPP)
+ 
+ AC_ARG_WITH(gnutls,
+ AS_HELP_STRING([--with-gnutls], [build with TLS support]))
+-if test "$with_gnutls"; then
++if test "$with_gnutls" = "yes"; then
+ 	AC_DEFINE(HAVE_GNUTLS, 1, [Define to 1 if you have GNU tls.])
+ 	CPPFLAGS="$CPPFLAGS `libgnutls-config --cflags`"
+ 	NETWORK_LIBS="$NETWORK_LIBS `libgnutls-config --libs`"
+diff --git a/doc/Makefile.am b/doc/Makefile.am
+index d416361..cec6568 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -2,7 +2,7 @@
+ # Converting DocBook to HTML (several small files)
+ # http://www.freebsd.org/tutorials/docproj-primer/x3132.html#AEN3140
+ 
+-# $Id: Makefile.am,v 1.62 2008/01/08 15:38:23 jklowden Exp $
++# $Id: Makefile.am,v 1.63 2008/03/23 17:29:57 jklowden Exp $
+ 
+ SHELL = /bin/sh
+ TXT2MAN = $(srcdir)/txt2man
+@@ -55,7 +55,8 @@ man:	$(man_MANS)
+ installdirs: 
+ 	$(mkinstalldirs)	$(TARGET_DOCDIR)/userguide    \
+ 				$(TARGET_DOCDIR)/reference    \
+-				$(TARGET_DOCDIR)/images 2>&1
++				$(TARGET_DOCDIR)/images       \
++				$(TARGET_DOCDIR)/images/callouts 2>&1
+ 
+ MANOPTS = -I 'FreeTDS User Guide'  -v 'FreeTDS Utilities' -t $(PRODUCT) -r $(VERSION)
+ 
+@@ -117,8 +118,8 @@ install-data-local: installdirs $(DOCDIR)/reference/index.html $(DOCDIR)/usergui
+ 	if test -r $(DOCDIR)/reference ; then d=.; else d="$(srcdir)"; fi; \
+ 	find $$d/$(DOCDIR)/reference \( -type f -o -type l \) -exec \
+ 		$(INSTALL_DATA) {} $(TARGET_DOCDIR)/reference ';'
+-	find $(srcdir)/images -name \*.gif -exec \
+-		$(INSTALL_DATA) {} $(TARGET_DOCDIR)/images ';'
++	cd $(srcdir) && find images -name \*.gif -exec \
++		$(INSTALL_DATA) {} $(TARGET_DOCDIR)/{} ';'
+ 
+ uninstall-local:
+ 	rm -rf $(TARGET_DOCDIR)
+
+commit f64622af5a476514192cb713991cac89269b06e3
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 17:42:36 2008 +0000
+
+    s/calout/callout/
+
+diff --git a/ChangeLog b/ChangeLog
+index e822060..09d37bf 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,6 +1,6 @@
+ Sun Mar 23 13:14:05 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac doc/Makefile.am
+-	- applied ML patches from Johnny C. Lam for calout locations
++	- applied ML patches from Johnny C. Lam for callout locations
+ 	- and gnutls test
+ 	
+ Thu Mar 13 14:22:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+@@ -232,4 +232,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2505 2008/03/23 17:29:57 jklowden Exp $
++$Id: ChangeLog,v 1.2506 2008/03/23 17:42:36 jklowden Exp $
+
+commit 11557109942abc5e139a6bb8be76498d70edcd32
+Author: jklowden <jklowden>
+Date:   Sun Mar 23 20:56:37 2008 +0000
+
+    clarified localization
+
+diff --git a/ChangeLog b/ChangeLog
+index 09d37bf..9ceb525 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Mar 23 16:55:08 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml clarified localization 
++	
+ Sun Mar 23 13:14:05 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac doc/Makefile.am
+ 	- applied ML patches from Johnny C. Lam for callout locations
+@@ -232,4 +235,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2506 2008/03/23 17:42:36 jklowden Exp $
++$Id: ChangeLog,v 1.2507 2008/03/23 20:56:37 jklowden Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index e8d4c79..647648e 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/01/10 22:57:39 $</date>
+-		<releaseinfo>$Revision: 1.111 $</releaseinfo>
++		<date>$Date: 2008/03/23 20:56:38 $</date>
++		<releaseinfo>$Revision: 1.112 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.111 $</>
+-<member>$Date: 2008/01/10 22:57:39 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.111 2008/01/10 22:57:39 jklowden Exp $.</>
++<member>$Revision: 1.112 $</>
++<member>$Date: 2008/03/23 20:56:38 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.112 2008/03/23 20:56:38 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/01/10 22:57:39 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/03/23 20:56:38 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -928,7 +928,7 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	<row>
+ 	<entry id="clientcharset">client charset</entry>
+ 	<entry>any valid iconv character set</entry>
+-	<entry>ISO-8859-1<footnote><para>Valid for ISO 8859-1 character set.  See <link linkend="Nonwestern"><acronym>TDS</> 7.0 for Nonwestern Languages</link> for more information.  </para></footnote></entry>
++	<entry>ISO-8859-1<footnote><para>Valid for ISO 8859-1 character set.  See <link linkend="Localization">Localization and <acronym>TDS</> 7.0</link> for more information.  </para></footnote></entry>
+ 	<entry>Makes <productname>FreeTDS</productname> use iconv to convert to and from the specified character set from UCS-2 in <acronym>TDS</> 7.0/8.0.
+ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need to match the server's charset to insert any characters the server supports.</entry>
+ 	</row>
+@@ -1029,7 +1029,7 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ 	</tgroup>
+ </table>
+ 
+-	<para>For more about the wonder world of <productname>FreeTDS</productname>logs, see <link linkend="logging">Logging</link>.</para>
++	<para>For more about the wonderful world of <productname>FreeTDS</productname> logs, see <link linkend="logging">Logging</link>.</para>
+ 			</sect3>
+ 
+ 			<sect3><title>Deprecated options</>	
+@@ -1236,7 +1236,7 @@ When you're done, you should see something very like this:
+ 
+ 			<para>If you specify <literal><replaceable>dataserver</replaceable>\<replaceable>instance</replaceable></literal>
+ 			as dataserver during login, <productname>FreeTDS</productname> will attempt to connect to specified instance.
+-			Only Microsoft SQL Server instances are supported.  (This server feature was introduced with SQL Server 2000).
++			Only Microsoft SQL Server instances are supported.  (This server feature was introduced with SQL Server 2000.)
+ 			</para>
+ 
+ 			<para>Note that other <filename>freetds.conf</> properties still apply.
+@@ -1249,8 +1249,8 @@ When you're done, you should see something very like this:
+ 			
+ 			<sect2 id="tsql"><title><application>tsql</application></title>
+ 
+-			<para>
+-The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  <command>tsql</> can either use or bypass the configuration files, allowing you to see if it's your dataserver that's not responding, or your configuration files that are messed up. </para> 
++			<para>The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  </para>
++			<para><command>tsql</> can either use or bypass the configuration files.  By trying both options, you can usually determine if it's your dataserver that's not responding, or your configuration files that are messed up. </para> 
+ 
+ 			<bridgehead renderas='sect3'>Using <filename>freetds.conf</>:</bridgehead>
+ 			<para>
+@@ -1263,18 +1263,6 @@ The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for trou
+ </cmdsynopsis>
+ 			</para>
+ 
+-			<bridgehead renderas='sect3'>Bypassing <filename>freetds.conf</>:</bridgehead>
+-			<para>
+-<cmdsynopsis label="Syntax synopsis for tsql">
+-  <command>tsql</command> 
+-	<arg choice='req'>-H <replaceable>hostname</replaceable></arg>
+-	<arg choice='req'>-p <replaceable>port</replaceable></arg>
+-	<arg choice='req'>-U <replaceable>username</replaceable></arg>
+-	<arg choice='opt'>-P<replaceable>password</replaceable></arg>
+-	<arg choice='opt'>-C</arg>
+-</cmdsynopsis>
+-			</para>
+-
+ <example id="e.g.tsqlFail">
+ <title>Failing to connect with tsql</title>
+ <screen>
+@@ -1300,6 +1288,20 @@ There was a problem connecting to the server
+ </screen>
+ </example>
+ 
++			<bridgehead renderas='sect3'>Bypassing <filename>freetds.conf</>:</bridgehead>
++			<para>
++<cmdsynopsis label="Syntax synopsis for tsql">
++  <command>tsql</command> 
++	<arg choice='req'>-H <replaceable>hostname</replaceable></arg>
++	<arg choice='req'>-p <replaceable>port</replaceable></arg>
++	<arg choice='req'>-U <replaceable>username</replaceable></arg>
++	<arg choice='opt'>-P<replaceable>password</replaceable></arg>
++	<arg choice='opt'>-C</arg>
++</cmdsynopsis>
++
++			Keep in mind that the TDS protocol version normally comes from <filename>freetds.conf</>.  When using <command>tsql</> this way, the library uses the compiled-in default (set by the <filename>configure</> script).  If that's not what you want, override it using the <envar>TDSVER</> environment variable.  
++			</para>
++
+ <example id="e.g.tsqlhostname">
+ <title>Connect with <command>tsql</> using a hostname and port number</title>
+ <screen>
+@@ -1491,7 +1493,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ </tgroup>
+ </table>
+ 
+-<table id="tab.Connection.attributes.freetds.conf"><title>Connection attributes that may appear in <filename>freetds.conf</></title>
++<table id="tab.Connection.attributes.freetds.conf"><title>Connection attributes that may appear in <filename>odbc.ini</></title>
+ <tgroup cols="4">
+ <thead>
+ 	<row>
+@@ -1746,7 +1748,7 @@ This chapter details some advanced configurations that need expanded explanation
+ 			<para>
+ Several version of Microsoft SQL server have a bug that affects big endian clients.  This includes 7.0 GA and 7.0 SP1.  Furthermore, <acronym>TDS</> Protocol version 7.0 is natively little endian. <productname>SQL Server 2000</productname> is also reported not to work from big endian clients without little endian emulation turned on.
+ 			</para>
+-<Note><para>If you are unfamiliar with the terms <emphasis>big endian</emphasis> and <emphasis>little endian</emphasis>, they are terms that come originally from Gulliver's Travels.  What they refer to in computer science is the the order in which bytes are stored by a processor.  Big endian machines such as Sparc and PowerPC store the most significant byte in the first memory location of a multi-byte integer.  Little endian machines such as Intel and Alpha do it the other way around.  So the 16-bit number 258 would be 0x0102 on big endian and 0x0201 on little endian machines.</para></Note>
++<Note><para>The terms <emphasis>big endian</emphasis> and <emphasis>little endian</emphasis> come originally from Gulliver's Travels.  In computer science they refer to the the integer byte-order for a processor.  Big endian processors, such as Sparc and PowerPC store the most significant byte in the first memory location of a multi-byte integer.  Little endian processors, such as Intel and Alpha do it the other way around.  So the 16-bit number 258 would be 0x0102 on big endian and 0x0201 on little endian machines.</para></Note>
+ 
+ <para>
+ In this example we want to force connections to a server named <literal>mssql</literal> to emulate a little endian client.  We are using protocol version 4.2 here, version 7.0 and 8.0 will automatically emulate little endian mode regardless of the <filename>freetds.conf</filename> setting.
+@@ -1763,16 +1765,16 @@ In this example we want to force connections to a server named <literal>mssql</l
+ </programlisting>
+ </example>
+ 		</sect1>
+-		<sect1 id="Nonwestern">
+-			<title><acronym>TDS</> 7.0 for Nonwestern Languages</title>
++		<sect1 id="Localization">
++			<title>Localization and <acronym>TDS</> 7.0</title>
+ 			<para>
+-<acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.
++<acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.  (Background information on Unicode and how it affects <productname>FreeTDS</productname> can be found in the <link linkend="Unicode">appendix</link>.)
+ 			</para>
+ 			<para>
+-Since most Unix tools and languages do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> allows conversion by the client to other character sets using the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.  Background information on Unicode and how it affects <productname>FreeTDS</productname> can be found in the <link linkend="Unicode">appendix</link>.  If no iconv library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in iconv substitute, and will be capable of converting between only <acronym>ISO-8859-1</> and <acronym>UCS-2</>.  
++Because most Unix tools and environments do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> provides for conversion by the client to other character sets.  The mechanism used is determined by the <filename>configure</> script, which looks for a <function>iconv</>(3) function, an implementation of the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.    If no <function>iconv</> library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in <function>iconv</> substitute, and will be capable of converting among only <acronym>ISO 8859-1</>, <acronym>UTF-8</>, and <acronym>UCS-2</>.  
+ 			</para>
+ 			<para>
+-To learn what character set the client is using, <productname>FreeTDS</productname> examines the <link linkend="clientcharset"><filename>freetds.conf</></link> entry.  If it finds nothing there, it assumes the client is using <acronym>ISO-8859-1</>.   That is generally a safe assumption for western languages such as English or French, but produces garbage for other languages.
++To learn what character set the client wants, <productname>FreeTDS</productname> prefers the applicable <link linkend="clientcharset"><filename>freetds.conf</></link> <literal>client charset</> property.  If that is not set, it parses the <envar>LANG</> environment variable.  In either case, the found string is passed to <function>iconv</>(3) (or its built-in replacment).  <footnote><para>The built-in replacement expects GNU iconv names: <literal>ISO-8859-1</>, <literal>US-ASCII</>, or <literal>UTF-8</>.</para></footnote>.  If neither is found, <acronym>UCS-2</> data are converted to <acronym>ISO 8859-1</>.  
+ 			</para>
+ 
+ 			<para>
+@@ -1801,10 +1803,9 @@ In this example a server named <literal>mssql</literal> will return data encoded
+ If <productname>FreeTDS</productname> runs into a character it can not convert, its behavior varies according to the severity of the problem.  On retrieving data from the server, <productname>FreeTDS</productname> substitutes an <acronym>ASCII</> '?' in the character's place, and emits a warning message stating that some characters could not be converted.  On sending data to the server, <productname>FreeTDS</productname> aborts the query and emits an error message.  It is well to ensure that the data contained in the database is representable in the client's character set.</para>
+ 
+ 			<para>
+-If you have a mix of character data that can not be contained in a single byte character set, you may wish to use <acronym>UTF-8</>.  <acronym>UTF-8</> is a variable length unicode encoding that is compatible with <acronym>ASCII</> in the range 0 to 127.  With <acronym>UTF-8</>, you are guaranteed to never have an unconvertible character.</para>
++If you have a mix of character data that can not be contained in a single-byte character set, you may wish to use <acronym>UTF-8</>.  <acronym>UTF-8</> is a variable length unicode encoding that is compatible with <acronym>ASCII</> in the range 0 to 127.  With <acronym>UTF-8</>, you are guaranteed to never have an unconvertible character.</para>
+ 
+-<Important><para><productname>FreeTDS</productname> is not fully compatible with multi-byte character sets such as <acronym>UCS-2</>.  You must use an ASCII-extension charset (e.g., UTF-8, ISO-8859-*)<footnote><para>not EBCDIC or other weird charsets</para></footnote>. Extreme care should be taken with testing applications using these encodings. Specifically, many applications do not expect the number of characters returned to exceed the column size (in bytes).  On the other hand, support of <acronym>UTF-8</> and <acronym>UCS-2</> is a high priority for the developers.  Patches and bug reports in this area are especially welcome.  
+-</para></Important>
++<Important><para><productname>FreeTDS</productname> is not fully compatible with multi-byte character sets such as <acronym>UCS-2</>.  You must use an ASCII-extension charset (e.g., UTF-8, ISO-8859-*)<footnote><para>not EBCDIC or other weird charsets</para></footnote>. Great care should be taken testing applications using these encodings. Specifically, many applications do not expect the number of characters returned to exceed the column size (in bytes).  </para></Important>
+ 			<para>
+ In the following example, a server named <literal>mssql</literal> will return data encoded in the <acronym>UTF-8</> character set.
+ 			</para>
+@@ -3483,7 +3484,7 @@ But check!  No point in trying to use a null pointer.  </para></callout>
+ 			</para>
+ 
+ 			
+-			<para>Typically it's more convenient to have <symbol>db-lib</> convert the data into the desired for.  The function that does that is <function>dbind()</>.  So: after fetching the metadata, and before fetching the data, we usually prepare the bound columns.  </para>
++			<para>Typically it's more convenient to have <symbol>db-lib</> convert the data into the desired form.  The function that does that is <function>dbind()</>.  So: after fetching the metadata, and before fetching the data, we usually prepare the bound columns.  </para>
+ 
+ 			<bridgehead id="samplecode.results.fetching.data" renderas="sect3">Fetching Data</>
+ 			
+
+commit 57b81538c6041f8b6534fbe6511a070739770115
+Author: jklowden <jklowden>
+Date:   Fri Apr 18 19:43:52 2008 +0000
+
+    added version lable
+
+diff --git a/doc/tds.html b/doc/tds.html
+index 28ab6de..b6ecd7a 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -439,7 +439,7 @@ auth   authentication data
+ </table>
+ <hr>
+ <p>* Under TDS9+ these types allow size to be -1. These types represents varchar(max), varbinary(max) and nvarchar(max).
+-Data representation for these types change in this way:
++Data representation for these types change in this way: </p>
+ <ul>
+  <li>size is 64 bit not 16 bit</li>
+  <li>if size is -1 meaning NULL</li>
+@@ -447,7 +447,6 @@ Data representation for these types change in this way:
+  <li>data is splitted in chunks where ever chunk start with a 32 bit size</li>
+  <li>a chunk with size &lt;= 0 is the terminal chunk</li>
+ </ul>
+-</p>
+ <p>
+ <a name="collate"></a>
+ <h2 class="section">Collate type - TDS8</h2>
+@@ -1516,6 +1515,8 @@ The following people have contributed to this document:
+ <p>
+ (short list)
+ 
++<h2>Document Status </h2>
++<P>$Id: tds.html,v 1.37 2008/04/18 19:43:52 jklowden Exp $</p>
+ <p>
+     <a href="http://validator.w3.org/check?uri=referer"><img
+         src="http://www.w3.org/Icons/valid-html401"
+
+commit 4a779fc55d9a653f619267338212726b81c0af1c
+Author: jklowden <jklowden>
+Date:   Wed Apr 23 21:35:45 2008 +0000
+
+    removed spurious 0xA0 from output
+
+diff --git a/ChangeLog b/ChangeLog
+index 9ceb525..33b692a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Wed Apr 23 17:25:58 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c removed spurious 0xA0 from output
++	* src/odbc/odbc.c add error diagnostic to SQLGetData
++	* include/tds.h src/tds/log.c src/tds/login.c
++	* src/tds/token.c
++	- add tdsdump_col()
++
+ Sun Mar 23 16:55:08 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml clarified localization 
+ 	
+@@ -235,4 +242,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2507 2008/03/23 20:56:37 jklowden Exp $
++$Id: ChangeLog,v 1.2508 2008/04/23 21:35:45 jklowden Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index aa87180..ba4f26b 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -45,7 +45,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.32 2007/12/06 19:00:24 freddy77 Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.33 2008/04/23 21:35:45 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+@@ -869,7 +869,7 @@ msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *m
+ 	fprintf(stderr, "%s\n", msgtext);
+ 	
+ 	if (severity > 10) {
+-		fprintf(stderr, "%s: error: severity %d > 10, exiting\n", options.appname, severity);
++		fprintf(stderr, "%s: error: severity %d > 10, exiting\n", options.appname, severity);
+ 		exit(severity);
+ 	}
+ 
+
+commit f991c8282649826762b9dbd0c17215bcea1c373c
+Author: jklowden <jklowden>
+Date:   Wed Apr 23 21:35:54 2008 +0000
+
+    add error diagnostic to SQLGetData
+
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0938e37..62f7222 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.478 2008/03/13 13:23:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.479 2008/04/23 21:35:54 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4637,7 +4637,10 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	}
+ 
+ 	/* read data from TDS only if current statement */
+-	if ((stmt->cursor == NULL && stmt->dbc->current_statement != stmt) || stmt->row_status == PRE_NORMAL_ROW || stmt->row_status == NOT_IN_ROW) {
++	if ((stmt->cursor == NULL && stmt->dbc->current_statement != stmt) 
++		|| stmt->row_status == PRE_NORMAL_ROW 
++		|| stmt->row_status == NOT_IN_ROW) 
++	{
+ 		odbc_errs_add(&stmt->errs, "24000", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -4649,16 +4652,16 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 
+ 	tds = stmt->dbc->tds_socket;
+ 	context = stmt->dbc->env->tds_ctx;
+-	resinfo = tds->current_results;
+-	if (!resinfo) {
++
++	if (!tds->current_results) {
+ 		odbc_errs_add(&stmt->errs, "HY010", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+-	if (icol <= 0 || icol > resinfo->num_cols) {
++	if (icol <= 0 || icol > tds->current_results->num_cols) {
+ 		odbc_errs_add(&stmt->errs, "07009", "Column out of range");
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+-	colinfo = resinfo->columns[icol - 1];
++	colinfo = tds->current_results->columns[icol - 1];
+ 
+ 	if (colinfo->column_cur_size < 0) {
+ 		*pcbValue = SQL_NULL_DATA;
+@@ -4700,22 +4703,23 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		}
+ 
+ 		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+-			/* calc how many bytes was readed */
+-			int readed = cbValueMax;
++			/* calculate how many bytes were read */
++			int remaining = cbValueMax;
+ 
+ 			/* FIXME test on destination char ??? */
+-			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && readed > 0)
+-				--readed;
+-			if (readed > *pcbValue)
+-				readed = *pcbValue;
+-			colinfo->column_text_sqlgetdatapos += readed;
++			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && remaining > 0)
++				--remaining;
++			if (remaining > *pcbValue)
++				remaining = *pcbValue;
++			colinfo->column_text_sqlgetdatapos += remaining;
+ 			/* avoid infinite SQL_SUCCESS on empty strings */
+ 			if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ 				++colinfo->column_text_sqlgetdatapos;
+-			/* not all readed ?? */
+-			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size)
+-				/* TODO add diagnostic */
++			
++			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {	/* not all read ?? */
++				odbc_errs_add(&stmt->errs, "1004", "String data, right truncated");
+ 				ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
++			}
+ 		} else {
+ 			colinfo->column_text_sqlgetdatapos = colinfo->column_size;
+ 		}
+
+commit f0a6eca4f74069613ae324b645498827b96a7679
+Author: jklowden <jklowden>
+Date:   Wed Apr 23 21:36:01 2008 +0000
+
+    add tdsdump_col()
+
+diff --git a/include/tds.h b/include/tds.h
+index 1a5eafa..50d0282 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.285 2008/01/18 13:37:12 freddy77 Exp $ */
++/* $Id: tds.h,v 1.286 2008/04/23 21:36:01 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1535,18 +1535,22 @@ void tds_set_parent(TDSSOCKET * tds, void *the_parent);
+ void *tds_get_parent(TDSSOCKET * tds);
+ int tds_swap_bytes(unsigned char *buf, int bytes);
+ int tds_version(TDSSOCKET * tds_socket, char *pversion_string);
++unsigned int tds_gettime_ms(void);
++
++/* log.c */
+ void tdsdump_off(void);
+ void tdsdump_on(void);
+ int tdsdump_open(const char *filename);
+ void tdsdump_close(void);
+ void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, int length);
+-void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...) 
++void tdsdump_col(const TDSCOLUMN *col);
++void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
++
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ 	__attribute__ ((__format__ (__printf__, 3, 4)))
+ #endif
+ ;
+ extern int tds_debug_flags;
+-unsigned int tds_gettime_ms(void);
+ 
+ /* net.c */
+ int tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 2de151f..4c9ee5d 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.4 2007/11/12 22:17:28 jklowden Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.5 2008/04/23 21:36:01 jklowden Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALLLVL | TDS_DBGFLAG_SOURCE;
+@@ -111,7 +111,7 @@ tdsdump_on(void)
+ 
+ 
+ /**
+- * This creates and truncates a human readable dump file for the TDS
++ * Create and truncate a human readable dump file for the TDS
+  * traffic.  The name of the file is specified by the filename
+  * parameter.  If that is given as NULL or an empty string,
+  * any existing log file will be closed.
+@@ -362,7 +362,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con
+ 
+ 
+ /**
+- * This function write a message to the debug log.  
++ * Write a message to the debug log.  
+  * \param file name of the log file
+  * \param level_line kind of detail to be included
+  * \param fmt       printf-like format string
+@@ -415,3 +415,79 @@ tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+ }				/* tdsdump_log()  */
+ 
++/**
++ * Write a column value to the debug log.  
++ * \param file name of the log file
++ * \param col column to dump
++ */
++void
++tdsdump_col(const TDSCOLUMN *col)
++{
++	const char* typename;
++	char* data;
++	TDS_SMALLINT type;
++	
++	assert(col);
++	assert(col->column_data);
++	
++	typename = tds_prtype(col->column_type);
++	type = col->column_type;
++	
++	switch(type) {
++	case SYBINTN:
++		switch(col->column_cur_size) {
++		case sizeof(TDS_INT):
++			type = SYBINT4;
++			break;
++		case sizeof(TDS_SMALLINT):
++			type = SYBINT2;
++			break;
++		case sizeof(TDS_TINYINT):
++			type = SYBINT1;
++			break;
++		}
++		break;
++	case SYBFLTN:
++		switch(col->column_cur_size) {
++		case sizeof(TDS_REAL):
++			type = SYBREAL;
++			break;
++		case sizeof(TDS_FLOAT):
++			type = SYBFLT8;
++			break;
++		}
++		break;
++	}
++	
++	switch(type) {
++	case SYBCHAR: 
++	case SYBVARCHAR: 
++		data = calloc(1, 1 + col->column_cur_size);
++		if( !data ) {
++			tdsdump_log(TDS_DBG_FUNC, "no memory to log data for type %s\n", typename);
++			return;
++		}
++		memcpy(data, col->column_data, col->column_cur_size);
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value \"%s\"\n", typename, data); 
++		free(data);
++		break;
++	case SYBINT1: 
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value %d\n", typename, (int)*(TDS_TINYINT*)col->column_data); 
++		break;
++	case SYBINT2: 
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value %d\n", typename, (int)*(TDS_SMALLINT*)col->column_data); 
++		break;
++	case SYBINT4: 
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value %d\n", typename, (int)*(TDS_INT*)col->column_data); 
++		break;
++	case SYBREAL: 
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value %f\n", typename, (double)*(TDS_REAL*)col->column_data); 
++		break;
++	case SYBFLT8: 
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value %d\n", typename, (double)*(TDS_FLOAT*)col->column_data); 
++		break;
++	default:
++		tdsdump_log(TDS_DBG_FUNC, "cannot log data for type %s\n", typename);
++		break;
++	}
++}
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 1bcbd0c..58deec6 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.172 2007/12/31 10:06:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.173 2008/04/23 21:36:01 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -533,6 +533,9 @@ tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	int len;
+ 	char blockstr[16];
+ 
++	/* override lservname field for ASA servers */	
++	const char *lservname = getenv("ASA_DATABASE")? getenv("ASA_DATABASE") : tds_dstr_cstr(&connection->server_name);
++
+ 	if (strchr(tds_dstr_cstr(&connection->user_name), '\\') != NULL) {
+ 		tdsdump_log(TDS_DBG_ERROR, "NT login not support using TDS 4.x or 5.0\n");
+ 		return TDS_FAIL;
+@@ -579,7 +582,7 @@ tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	}
+ 	tds_put_n(tds, magic3, 3);
+ 	tds_put_login_string(tds, tds_dstr_cstr(&connection->app_name), TDS_MAX_LOGIN_STR_SZ);
+-	tds_put_login_string(tds, tds_dstr_cstr(&connection->server_name), TDS_MAX_LOGIN_STR_SZ);
++	tds_put_login_string(tds, lservname, TDS_MAX_LOGIN_STR_SZ);
+ 	if (IS_TDS42(tds)) {
+ 		tds_put_login_string(tds, tds_dstr_cstr(&connection->password), 255);
+ 	} else {
+diff --git a/src/tds/token.c b/src/tds/token.c
+index e6d5a6d..445c4b1 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.344 2008/01/13 20:01:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.345 2008/04/23 21:36:01 jklowden Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -1223,6 +1223,7 @@ tds_process_param_result(TDSSOCKET * tds, TDSPARAMINFO ** pinfo)
+ 		return TDS_FAIL;
+ 
+ 	token = tds_get_data(tds, curparam);
++	tdsdump_col(curparam);
+ 
+ 	/*
+ 	 * Real output parameters will either be unnamed or will have a valid
+@@ -1573,6 +1574,8 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
++	tdsdump_log(TDS_DBG_INFO1, "tds_get_data_info(%p, %p, %d) %s", tds, curcol, is_param, is_param? "[for parameter]" : "");
++
+ 	curcol->column_namelen = tds_get_string(tds, tds_get_byte(tds), curcol->column_name, sizeof(curcol->column_name) - 1);
+ 	curcol->column_name[curcol->column_namelen] = '\0';
+ 
+@@ -1585,11 +1588,52 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 		curcol->column_writeable = (curcol->column_flags & 0x10) > 1;
+ 		curcol->column_nullable = (curcol->column_flags & 0x20) > 1;
+ 		curcol->column_identity = (curcol->column_flags & 0x40) > 1;
+-	}
+-	/* TODO what's these bytes ?? */
+-	if (IS_TDS90(tds))
+-		tds_get_n(tds, NULL, 2);
++#if 0
++		/****************************************
++		 * NumParts=BYTE; (introduced in TDS 7.2) 
++		 * PartName=US_VARCHAR;(introduced in TDS 7.2) 
++		 * TableName=NumParts, {PartName}-; 
++		 * ColName= HYPERLINK \l "B_VARCHAR_Def" B_VARCHAR; 
++		 * ColumnData=UserType, Flags, [TableName], // <Only specified if text, //ntext or image columns are included //in the rowset being described> ColName; 
++		 * NoMetaData='0xFF', '0xFF';
++		 */
++		enum column_flag_bits_according_to_microsoft {
++			  case_sensitive	= 0x0001
++			, nullable		= 0x0002
++			, updateable		= 0x0004
++			, might_be_updateable	= 0x0008
++			, identity		= 0x0010
++			, computed		= 0x0020
++			, us_reserved_odbc	= 0x0040 | 0x0080
++			, is_fixed_len_clr_type = 0x0100
++			, is_hidden_browse_pk	= 0x0200
++			, is_browse_pk		= 0x0400
++			, might_be_nullable	= 0x0800 
++		};
++		/* TODO: implement members in TDSCOLUMN */
++		if (IS_TDS90(tds)) {
++			curcol->is_computed = 		(curcol->column_flags & (1 << 4)) > 1;
++			curcol->us_reserved_odbc1 = 	(curcol->column_flags & (1 << 5)) > 1;
++			curcol->us_reserved_odbc2 = 	(curcol->column_flags & (1 << 6)) > 1;
++			curcol->is_fixed_len_clr_type = (curcol->column_flags & (1 << 7)) > 1;
++		}
++#endif 
++	} 
+ 
++	if (IS_TDS90(tds)) {
++		tds_get_n(tds, NULL, 2);
++#if 0
++		/* TODO: implement members in TDSCOLUMN, values untested */
++		curcol->us_reserved1 = (curcol->column_flags & 0x01);
++		curcol->us_reserved2 = (curcol->column_flags & 0x02);
++		curcol->us_reserved3 = (curcol->column_flags & 0x04);
++		curcol->us_reserved4 = (curcol->column_flags & 0x08);
++		curcol->is_hidden = (curcol->column_flags & 0x10);
++		curcol->is_key = (curcol->column_flags & 0x20);
++		curcol->is_nullable_unknown = (curcol->column_flags & 0x40);
++#endif
++	}
++	
+ 	curcol->column_usertype = tds_get_int(tds);
+ 	tds_set_column_type(tds, curcol, tds_get_byte(tds));
+ 
+
+commit 48d88d459db8323e2d69866ccd0862856e1d331e
+Author: jklowden <jklowden>
+Date:   Thu Apr 24 15:59:29 2008 +0000
+
+    small clarifications
+
+diff --git a/ChangeLog b/ChangeLog
+index 33b692a..0357601 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 24 11:57:24 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/htdoc/faq.html small clarifications
++
+ Wed Apr 23 17:25:58 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/bsqldb.c removed spurious 0xA0 from output
+ 	* src/odbc/odbc.c add error diagnostic to SQLGetData
+@@ -242,4 +245,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2508 2008/04/23 21:35:45 jklowden Exp $
++$Id: ChangeLog,v 1.2509 2008/04/24 15:59:29 jklowden Exp $
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index 76126b3..d49ac66 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,7 +3,7 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.18 2006/12/10 21:07:47 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.19 2008/04/24 15:59:29 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+@@ -41,10 +41,6 @@
+   last release, and to answer perennial questions (there are
+   some).</p>
+ 
+-  <div align="right">
+-    <i>$Id: faq.html,v 1.18 2006/12/10 21:07:47 jklowden Exp $</i>
+-  </div>
+-
+   <ol>
+     <li>General Questions
+ 
+@@ -126,18 +122,12 @@
+       </ul>
+     </li>
+ 
+-    <li>Problems Running
+-
+-      <ul>
+-        <li><a href="#syb.result.type">With <tt>DBD::Sybase</tt>,
+-        why do I sometimes get an unexpected 1-column result
+-        set?</a></li>
+-
+-         <li><a href="#ms.output.parameters">
+-         I'm not getting my output parameters returned</a>, but I seem
+-         to be doing everything right!</li>
++    <li>Problems Running <ul>	
++	<li><a href="#ms.output.parameters">
++        I'm not getting my output parameters returned</a>, but I seem
++        to be doing everything right!</li>
+ 
+-       <li><a href="#unknownmarker">What does this <tt>unknown
++	<li><a href="#unknownmarker">What does this <tt>unknown
+         marker</tt> message mean?</a></li>
+ 
+         <li><a href="#connectionrefused">What if I get a
+@@ -172,10 +162,6 @@
+   with a number of APIs (Application Programming Interfaces). The
+   APIs are DB-Lib, CT-Lib, and ODBC.</p>
+ 
+-  <p>A JDBC driver has also been contributed under a BSDish license
+-  and is available from the download page. It does not require the
+-  FreeTDS C libraries.</p>
+-
+   <h3>Where do I get FreeTDS?</h3>
+   	<a name="Where.do.I.get.FreeTDS" id="Where.do.I.get.FreeTDS"></a>
+ 
+@@ -414,12 +400,18 @@
+   <h3>Is there any documentation on the TDS protocol?</h3>
+   	<a name="protocol" id="protocol"></a>
+ 
+-  <p>Yes, there is some <a href="tds.html">preliminary
++  <p>There is <a href="tds.html">preliminary
+   documentation</a> available. The most up to date version is in
+   the User Guide.</p>
+ 
+   <p>Sybase publishes its <a href="http://www.sybase.com/content/1040983/Sybase-tds38-102306.pdf" >TDS 5.0 Functional Specification</a>.</p>
+-  <hr />
++  
++  <p>Microsoft published its specification, too.  
++  It can currently be found on <a href="http://msdn2.microsoft.com/en-us/library/cc448436.aspx"
++  	>MSDN</a> or search the web for 
++	&ldquo;ms-tds tabular data stream site:microsoft.com&rdquo;.</p>
++  
++  <hr/>
+   <!-- Implementation -->
+ 
+   <h2>Implementation</h2>
+@@ -631,13 +623,6 @@
+ 
+   <h2>Problems Running</h2>
+ 
+-  <h3>With <tt>DBD::Sybase</tt>, why do I sometimes get an
+-  unexpected 1-column result set?</h3>
+-  	<a name="syb.result.type" id="syb.result.type"></a>
+-
+-  <p>Use a more recent release of FreeTDS. This problem was
+-  corrected with version 0.63.</p>
+-
+   <h3>Output Parameters</h3>
+ 	<a name="ms.output.parameters" id="ms.output.parameters"></a>
+ 	
+@@ -801,20 +786,23 @@
+   <p>The <tt>text</tt> data type is different from <tt>char</tt>
+   and <tt>varchar</tt> types. The maximum data length of a
+   <tt>text</tt> column is governed by the <tt>textsize</tt>
+-  variable on the server. Microsoft <i>claims</i> in their
++  connection option. Microsoft <i>claims</i> in their
+   documentation to use a default <tt>textsize</tt> of 4000
+   characters, but in fact their implementation is inconsistent.
+   Sometimes <tt>text</tt> columns are returned with a size of 4
+   GB!</p>
+ 
+-  <p>The best solution is to make sure you set <tt>textsize</tt> to
++  <p>The best solution is to make sure you set the <tt>textsize</tt> option to
+   a reasonable value when establishing a connection. For
+-  example:</p><!-- example set textsize 1000 (see UG) -->
++  example:</p>
+   <pre class="screen">
+ <tt class="userinput">
+-<b>set <tt class="envar">textsize</tt> 10000</b></tt>
++1&gt; <b>set <tt class="envar">textsize</tt> 10000</b></tt>
++2&gt; <b>go</b>
+ </pre>
+ 
++  See also the &ldquo;<tt>text size</tt>&rdquo; option in <tt>freetds.conf</tt>.
++
+   <h3>My dates aren't formatted right!</h3>
+   	<a name="dateformat" id="dateformat"></a>
+ 
+@@ -853,7 +841,10 @@
+   Guide for details.</p><!-- footer -->
+   <hr size="1" />
+   <font size="-1">Updates and comments <a href=
+-  "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a></font>
++  "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
++  <br/>
++    <i>$Id: faq.html,v 1.19 2008/04/24 15:59:29 jklowden Exp $</i>
++	</font>
+ <hr/>
+   <p>
+     <a href="http://validator.w3.org/check?uri=referer"><img
+
+commit 5cacbb2ee75e5b4c628ff34c3ca2ff49d75d98d9
+Author: freddy77 <freddy77>
+Date:   Tue Apr 29 15:08:56 2008 +0000
+
+    typo error on error code
+
+diff --git a/ChangeLog b/ChangeLog
+index 0357601..3bedd29 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 29 16:54:49 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: typo error
++
+ Thu Apr 24 11:57:24 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/htdoc/faq.html small clarifications
+ 
+@@ -10,12 +13,12 @@ Wed Apr 23 17:25:58 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 
+ Sun Mar 23 16:55:08 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml clarified localization 
+-	
++
+ Sun Mar 23 13:14:05 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac doc/Makefile.am
+ 	- applied ML patches from Johnny C. Lam for callout locations
+ 	- and gnutls test
+-	
++
+ Thu Mar 13 14:22:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/error.c:
+ 	- make errs offset constant in all odbc structures to make 
+@@ -245,4 +248,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2509 2008/04/24 15:59:29 jklowden Exp $
++$Id: ChangeLog,v 1.2510 2008/04/29 15:08:56 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 62f7222..3f4f497 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.479 2008/04/23 21:35:54 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.480 2008/04/29 15:08:56 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4717,7 +4717,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 				++colinfo->column_text_sqlgetdatapos;
+ 			
+ 			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {	/* not all read ?? */
+-				odbc_errs_add(&stmt->errs, "1004", "String data, right truncated");
++				odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ 				ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ 			}
+ 		} else {
+
+commit b99084ae0bac3f2358f9bcfef3e9658b2e4c3077
+Author: jklowden <jklowden>
+Date:   Wed Apr 30 14:09:52 2008 +0000
+
+    added missing break to nested switch in _dbresults
+
+diff --git a/ChangeLog b/ChangeLog
+index 3bedd29..12da7d1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Apr 30 10:07:37 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c added missing break to nested switch
++	- in _dbresults
++
+ Thu Apr 29 16:54:49 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: typo error
+ 
+@@ -248,4 +252,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2510 2008/04/29 15:08:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2511 2008/04/30 14:09:52 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index b9baa7e..4056b75 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.322 2008/02/15 16:27:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.323 2008/04/30 14:09:53 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1593,8 +1593,7 @@ _dbresults(DBPROCESS * dbproc)
+ {
+ 	RETCODE retcode = FAIL;
+ 	TDSSOCKET *tds;
+-	int result_type;
+-	int done_flags;
++	int result_type, done_flags;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbresults(%p)\n", dbproc);
+ 	CHECK_DBPROC();
+@@ -1602,9 +1601,6 @@ _dbresults(DBPROCESS * dbproc)
+ 
+ 	tds = dbproc->tds_socket;
+ 
+-	if (IS_TDSDEAD(tds))
+-		return FAIL;
+-
+ 	tdsdump_log(TDS_DBG_FUNC, "dbresults: dbresults_state is %d (%s)\n", 
+ 					dbproc->dbresults_state, prdbresults_state(dbproc->dbresults_state));
+ 	switch ( dbproc->dbresults_state ) {
+@@ -1681,7 +1677,7 @@ _dbresults(DBPROCESS * dbproc)
+ 					assert(0);
+ 					break;
+ 				}
+-				
++				break;
+ 
+ 			case TDS_DONEINPROC_RESULT:
+ 				/* 
+
+commit e6fec4a8988fbd6a5d92ee57b405f93ab4cbca89
+Author: freddy77 <freddy77>
+Date:   Fri May 2 10:04:15 2008 +0000
+
+    fixed printf format problem
+
+diff --git a/ChangeLog b/ChangeLog
+index 12da7d1..0baacac 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri May 02 12:03:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/log.c: fixed printf format problem
++
+ Wed Apr 30 10:07:37 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c added missing break to nested switch
+ 	- in _dbresults
+@@ -252,4 +255,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2511 2008/04/30 14:09:52 jklowden Exp $
++$Id: ChangeLog,v 1.2512 2008/05/02 10:04:15 freddy77 Exp $
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 4c9ee5d..377d63d 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.5 2008/04/23 21:36:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.6 2008/05/02 10:04:15 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALLLVL | TDS_DBGFLAG_SOURCE;
+@@ -484,7 +484,7 @@ tdsdump_col(const TDSCOLUMN *col)
+ 		tdsdump_log(TDS_DBG_FUNC, "type %s has value %f\n", typename, (double)*(TDS_REAL*)col->column_data); 
+ 		break;
+ 	case SYBFLT8: 
+-		tdsdump_log(TDS_DBG_FUNC, "type %s has value %d\n", typename, (double)*(TDS_FLOAT*)col->column_data); 
++		tdsdump_log(TDS_DBG_FUNC, "type %s has value %f\n", typename, (double)*(TDS_FLOAT*)col->column_data); 
+ 		break;
+ 	default:
+ 		tdsdump_log(TDS_DBG_FUNC, "cannot log data for type %s\n", typename);
+
+commit 056faf46e351fd76f5c3f28926aeb4abb725f79f
+Author: jklowden <jklowden>
+Date:   Tue May 6 00:14:01 2008 +0000
+
+    applied CS_BIGINT patch from Stephen Degler
+
+diff --git a/ChangeLog b/ChangeLog
+index 0baacac..4320aec 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon May  5 20:11:58 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/cstypes.h src/ctlib/ct.c
++	- applied CS_BIGINT patch from Stephen Degler
++	
+ Fri May 02 12:03:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/log.c: fixed printf format problem
+ 
+@@ -255,4 +259,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2512 2008/05/02 10:04:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2513 2008/05/06 00:14:01 jklowden Exp $
+diff --git a/include/cstypes.h b/include/cstypes.h
+index aa494b1..841129c 100644
+--- a/include/cstypes.h
++++ b/include/cstypes.h
+@@ -30,36 +30,37 @@ extern "C"
+ #endif
+ #endif
+ 
+-static const char rcsid_cstypes_h[] = "$Id: cstypes.h,v 1.6 2005/09/21 14:46:00 freddy77 Exp $";
++static const char rcsid_cstypes_h[] = "$Id: cstypes.h,v 1.7 2008/05/06 00:14:02 jklowden Exp $";
+ static const void *const no_unused_cstypes_h_warn[] = { rcsid_cstypes_h, no_unused_cstypes_h_warn };
+ 
++typedef tds_sysdep_int32_type 		CS_INT;
++typedef unsigned tds_sysdep_int32_type 	CS_UINT;
++typedef tds_sysdep_int64_type 		CS_BIGINT;
++typedef unsigned tds_sysdep_int64_type 	CS_UBIGINT;
++typedef tds_sysdep_int16_type 		CS_SMALLINT;
++typedef unsigned tds_sysdep_int16_type 	CS_USMALLINT;
++typedef unsigned char 			CS_TINYINT;
++typedef char 				CS_CHAR;
++typedef unsigned char 			CS_BYTE;
++typedef tds_sysdep_real32_type 		CS_REAL;
++typedef tds_sysdep_real64_type 		CS_FLOAT;
++typedef tds_sysdep_int32_type 		CS_BOOL;
++typedef void 				CS_VOID;
++typedef unsigned char 			CS_IMAGE;
++typedef unsigned char 			CS_TEXT;
++typedef unsigned char 			CS_LONGBINARY;
++typedef unsigned char 			CS_LONGCHAR;
++typedef long 				CS_LONG;
++typedef unsigned char 			CS_BINARY;
++typedef unsigned tds_sysdep_int16_type 	CS_USHORT;
++typedef unsigned char 			CS_BIT;
+ 
+-typedef tds_sysdep_int32_type CS_INT;
+-typedef unsigned tds_sysdep_int32_type CS_UINT;
+-typedef tds_sysdep_int16_type CS_SMALLINT;
+-typedef unsigned char CS_TINYINT;
+-typedef char CS_CHAR;
+-typedef unsigned char CS_BYTE;
+-typedef tds_sysdep_real32_type CS_REAL;
+-typedef tds_sysdep_real64_type CS_FLOAT;
+-typedef tds_sysdep_int32_type CS_BOOL;
+-typedef void CS_VOID;
+-typedef unsigned char CS_IMAGE;
+-typedef unsigned char CS_TEXT;
+-typedef unsigned char CS_LONGBINARY;
+-typedef unsigned char CS_LONGCHAR;
+-typedef long CS_LONG;
+-typedef unsigned char CS_BINARY;
+-typedef unsigned tds_sysdep_int16_type CS_USHORT;
+-typedef unsigned char CS_BIT;
+ typedef CS_INT CS_RETCODE;
+ 
+-
+-
+ #define CS_MAX_NAME 132
+ #define CS_MAX_SCALE 77
+ #define CS_MAX_PREC 77		/* used by php */
+-#define CS_MAX_NUMLEN 33		/* used by roguewave */
++#define CS_MAX_NUMLEN 33	/* used by roguewave */
+ #define CS_MAX_MSG 1024
+ #define CS_SQLSTATE_SIZE 8
+ #define CS_OBJ_NAME 400
+@@ -138,6 +139,10 @@ typedef struct _cs_money4
+ 	CS_INT mny4;
+ } CS_MONEY4;
+ 
++typedef CS_INT CS_DATE;
++
++typedef CS_INT CS_TIME;
++
+ typedef struct _cs_datetime
+ {
+ 	CS_INT dtdays;
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 3e4db22..7a59712 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.177 2007/12/21 15:23:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.178 2008/05/06 00:14:02 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -1898,7 +1898,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_CHAR_TYPE;
+ 		break;
+ 	case SYBINT8:
+-		return CS_LONG_TYPE;
++		return CS_BIGINT_TYPE;
+ 		break;
+ 	case SYBINT4:
+ 		return CS_INT_TYPE;
+@@ -1912,7 +1912,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 	case SYBINTN:
+ 		switch (size) {
+ 		case 8:
+-			return CS_LONG_TYPE;
++			return CS_BIGINT_TYPE;
+ 		case 4:
+ 			return CS_INT_TYPE;
+ 		case 2:
+@@ -2015,6 +2015,7 @@ _ct_get_server_type(int datatype)
+ 		return SYBCHAR;
+ 		break;
+ 	case CS_LONG_TYPE:
++	case CS_BIGINT_TYPE:
+ 		return SYBINT8;
+ 		break;
+ 	case CS_INT_TYPE:
+
+commit 980f832b840e6705bee521913f0111b4fe4438d6
+Author: jklowden <jklowden>
+Date:   Tue May 6 17:42:43 2008 +0000
+
+    updated links to external docs
+
+diff --git a/ChangeLog b/ChangeLog
+index 4320aec..1f0b9d0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue May  6 13:41:32 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml updated links to external docs
++
+ Mon May  5 20:11:58 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cstypes.h src/ctlib/ct.c
+ 	- applied CS_BIGINT patch from Stephen Degler
+@@ -259,4 +262,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2513 2008/05/06 00:14:01 jklowden Exp $
++$Id: ChangeLog,v 1.2514 2008/05/06 17:42:43 jklowden Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 647648e..317983c 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/03/23 20:56:38 $</date>
+-		<releaseinfo>$Revision: 1.112 $</releaseinfo>
++		<date>$Date: 2008/05/06 17:42:44 $</date>
++		<releaseinfo>$Revision: 1.113 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.112 $</>
+-<member>$Date: 2008/03/23 20:56:38 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.112 2008/03/23 20:56:38 jklowden Exp $.</>
++<member>$Revision: 1.113 $</>
++<member>$Date: 2008/05/06 17:42:44 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.113 2008/05/06 17:42:44 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/03/23 20:56:38 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/05/06 17:42:44 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -3092,17 +3092,31 @@ the extent to which it is implemented.  The <emphasis>Status</> field may be:
+ 
+ 		<sect1 id="dblib.api.summary">
+ 			<title>db-lib API Implementation Summary</title>
+-			<para>Microsoft's version of db-lib is <ulink url="http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dblibc/dbc_pdc04a_6qsl.asp">online</ulink>.   Sybase's is both <ulink url="http://sybooks.sybase.com/onlinebooks/group-cn/cng1251e/dblib/@Generic__BookView">online</ulink>  and can be <ulink url="http://download.sybase.com/pdfdocs/cng1250j/dblib.pdf">downloaded</ulink>  as a PDF file.  <footnote><para>Links such as these are quite perishable.  Should you find them broken, please check the <ulink url="http://www.freetds.org/userguide/dblib.api.summary.htm">FreeTDS User Guide</ulink> posted on our website.  If it's out of date, please let us know, so we can correct it.  Thanks.  </para></footnote></para>
++			<para>Microsoft's version of db-lib is 
++			<ulink url="http://msdn.microsoft.com/en-us/library/aa936988(SQL.80).aspx">online</ulink>.  
++			Sybase's is both 
++			<ulink url="http://manuals.sybase.com/onlinebooks/group-cnarc/cng1110e/dblib/@Generic__BookTextView;pt=4602;nh=1">online</ulink>  
++			and can be 
++			<ulink url="http://download.sybase.com/pdfdocs/cng1250j/dblib.pdf">downloaded</ulink>  
++			as a PDF file.  
++			
++			<footnote><para>Links such as these are quite perishable.  Should you find them broken, please check the <ulink url="http://www.freetds.org/userguide/dblib.api.summary.htm">FreeTDS User Guide</ulink> posted on our website.  If it's out of date, please let us know, so we can correct it.  Thanks.  </para></footnote></para>
+ 			&dblibapisgml;
+ 		</sect1>
++
+ 		<sect1 id="ctlib.api.summary">
+ 			<title>ct-lib API Implementation Summary</title>
+-			<para>Sybase ct-lib documentation can be found <ulink url="http://sybooks.sybase.com/onlinebooks/group-cn/cng1251e/ctref/@Generic__BookView">online</ulink> and in <ulink url="http://download.sybase.com/pdfdocs/cng1000e/ref.pdf">PDF</ulink> form. <footnote><para>Links such as these are quite perishable.  Should you find them broken, please check the <ulink url="http://www.freetds.org/userguide/ctlib.api.summary.htm">FreeTDS User Guide</ulink> posted on our website.  If it's out of date, please let us know, so we can correct it.  Thanks.  </para></footnote> </para>
++			<para>Sybase ct-lib documentation can be found 
++			<ulink url="http://manuals.sybase.com/onlinebooks/group-cnarc/cng1110e/ctref/@Generic__BookView">online</ulink> 
++			and in <ulink url="http://download.sybase.com/pdfdocs/cng1000e/ref.pdf">PDF</ulink> form. <footnote><para>Links such as these are quite perishable.  Should you find them broken, please check the <ulink url="http://www.freetds.org/userguide/ctlib.api.summary.htm">FreeTDS User Guide</ulink> posted on our website.  If it's out of date, please let us know, so we can correct it.  Thanks.  </para></footnote> </para>
+ 			&ctlibapisgml;
+ 		</sect1>
+ 	
+ 		<sect1 id="odbc.api.summary">
+ 			<title>ODBC API Implementation Summary</title>
++			<para>Microsoft's ODBC documentation is 
++			<ulink url="http://msdn.microsoft.com/en-us/library/ms714177.aspx">online</ulink>. </para>
++			
+ 			<para>The functions are linked to the reference page on Microsoft's website.  <footnote><para>Links such as these are quite perishable.  Should you find them broken, please check the <ulink url="http://www.freetds.org/userguide/odbc.api.summary.htm">FreeTDS User Guide</ulink> posted on our website.  If it's out of date, please let us know, so we can correct it.  Thanks.  </para></footnote></para>
+ 			&odbcapisgml;
+ 		</sect1>
+
+commit 5253c1567b219accfbdd9c6e817c26d5ae6e0024
+Author: freddy77 <freddy77>
+Date:   Wed May 7 08:42:30 2008 +0000
+
+    added new odbcss.h to support some constants
+
+diff --git a/ChangeLog b/ChangeLog
+index 1f0b9d0..9259213 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,10 +1,14 @@
++Wed May  7 10:41:43 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/Makefile.am include/odbcss.h(added) src/odbc/error.c:
++	- added new odbcss.h to support some constants
++
+ Tue May  6 13:41:32 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml updated links to external docs
+ 
+ Mon May  5 20:11:58 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cstypes.h src/ctlib/ct.c
+ 	- applied CS_BIGINT patch from Stephen Degler
+-	
++
+ Fri May 02 12:03:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/log.c: fixed printf format problem
+ 
+@@ -262,4 +266,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2514 2008/05/06 17:42:43 jklowden Exp $
++$Id: ChangeLog,v 1.2515 2008/05/07 08:42:30 freddy77 Exp $
+diff --git a/include/Makefile.am b/include/Makefile.am
+index 8e417b0..c257cf9 100644
+--- a/include/Makefile.am
++++ b/include/Makefile.am
+@@ -3,7 +3,7 @@ AUTOMAKE_OPTIONS	=	1.5.3
+ include_HEADERS	=	bkpublic.h cspublic.h cstypes.h ctpublic.h \
+ 			sqldb.h sqlfront.h \
+ 			sybdb.h sybfront.h \
+-			syberror.h
++			syberror.h odbcss.h
+ 
+ nodist_include_HEADERS	=	tds_sysdep_public.h
+ 
+diff --git a/include/odbcss.h b/include/odbcss.h
+new file mode 100644
+index 0000000..66e1c61
+--- /dev/null
++++ b/include/odbcss.h
+@@ -0,0 +1,24 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2008  Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/* $Id: odbcss.h,v 1.1 2008/05/07 08:42:30 freddy77 Exp $ */
++
++#define SQL_DIAG_SS_MSGSTATE	(-1150)
++#define SQL_DIAG_SS_LINE	(-1154)
++
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index c9e0772..5606f5a 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -36,18 +36,15 @@
+ #include <assert.h>
+ 
+ #include "tdsodbc.h"
++#include "odbcss.h"
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-#if HAVE_ODBCSS_H
+-#include <odbcss.h>
+-#endif
+-
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.51 2008/03/13 13:23:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.52 2008/05/07 08:42:30 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -733,23 +730,19 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		*(SQLINTEGER *) buffer = SQL_COLUMN_NUMBER_UNKNOWN;
+ 		break;
+ 
+-#ifdef SQL_DIAG_SS_MSGSTATE
+ 	case SQL_DIAG_SS_MSGSTATE:
+ 		if (errs->errs[numRecord].msgstate == 0)
+ 			return SQL_ERROR;
+ 		else
+ 			*(SQLINTEGER *) buffer = errs->errs[numRecord].msgstate;
+ 		break;
+-#endif
+ 
+-#ifdef SQL_DIAG_SS_LINE
+ 	case SQL_DIAG_SS_LINE:
+ 		if (errs->errs[numRecord].linenum == 0)
+ 			return SQL_ERROR;
+ 		else
+ 			*(SQLUSMALLINT *) buffer = errs->errs[numRecord].linenum;
+ 		break;
+-#endif
+ 
+ 	case SQL_DIAG_CONNECTION_NAME:
+ 		if (dbc && dbc->tds_socket && dbc->tds_socket->spid > 0)
+
+commit 4989ef0fe6235df67fe6da44f6b0ef514d25118a
+Author: freddy77 <freddy77>
+Date:   Wed May 7 12:16:34 2008 +0000
+
+    small update
+
+diff --git a/doc/tds.html b/doc/tds.html
+index b6ecd7a..f219226 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -215,6 +215,7 @@ byte  var type  description
+                 0x80 enable warning messages if SET LANGUAGE issued
+                 0x40 change to initial database must succeed
+                 0x20 enable warning messages if USE &lt;database&gt; issued
++                0x10 enable BCP
+  25   INT8	option flags 2
+                 0x80 enable domain login security
+                 0x02 client is an ODBC driver
+@@ -1516,7 +1517,7 @@ The following people have contributed to this document:
+ (short list)
+ 
+ <h2>Document Status </h2>
+-<P>$Id: tds.html,v 1.37 2008/04/18 19:43:52 jklowden Exp $</p>
++<P>$Id: tds.html,v 1.38 2008/05/07 12:16:34 freddy77 Exp $</p>
+ <p>
+     <a href="http://validator.w3.org/check?uri=referer"><img
+         src="http://www.w3.org/Icons/valid-html401"
+
+commit 93183ccf8823bca0a44203e57a4622661e0c579e
+Author: jklowden <jklowden>
+Date:   Thu May 8 02:44:12 2008 +0000
+
+    0.82 released
+
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index d68c673..d225215 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.15 2008/03/12 21:34:09 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.16 2008/05/08 02:44:12 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -33,7 +33,22 @@ News&nbsp;&nbsp;|&nbsp;
+ <table summary="layout" width="80%" align="center">
+ 
+ <!--  item  -->
+-<tr bgcolor="#c9c9ff"><td>Second Release Candidate available for 0.82</td></tr>
++<tr bgcolor="#c9c9ff"><td>Version 0.82 Released</td></tr>
++<tr>
++<td>
++<br />
++Version 0.82 is now available from 
++<a href="http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/freetds-stable.tgz">
++ftp.ibiblio.org</a>.  This is a major release, almost two years in the 
++making.  See NEWS and ChangeLog-0.82, included in the distribution, for details.  
++(8 May 2008)
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
++<tr bgcolor="#c9c9ff"><td>Third Release Candidate available for 0.82</td></tr>
+ <tr>
+ <td>
+ <br />
+
+commit 512e07dcac4db8f4377deed1ed182d4c2a145190
+Author: jklowden <jklowden>
+Date:   Thu May 8 18:37:21 2008 +0000
+
+    s/nobase_data/noinst/ per jlam on ML
+
+diff --git a/ChangeLog b/ChangeLog
+index 9259213..68334a5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May  8 14:29:50 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am s/nobase_data/noinst/ per jlam on ML
++
+ Wed May  7 10:41:43 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/Makefile.am include/odbcss.h(added) src/odbc/error.c:
+ 	- added new odbcss.h to support some constants
+@@ -266,4 +269,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2515 2008/05/07 08:42:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2516 2008/05/08 18:37:21 jklowden Exp $
+diff --git a/doc/Makefile.am b/doc/Makefile.am
+index cec6568..a03f624 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -2,7 +2,7 @@
+ # Converting DocBook to HTML (several small files)
+ # http://www.freebsd.org/tutorials/docproj-primer/x3132.html#AEN3140
+ 
+-# $Id: Makefile.am,v 1.63 2008/03/23 17:29:57 jklowden Exp $
++# $Id: Makefile.am,v 1.64 2008/05/08 18:37:21 jklowden Exp $
+ 
+ SHELL = /bin/sh
+ TXT2MAN = $(srcdir)/txt2man
+@@ -40,7 +40,7 @@ EXTRA_DIST =	api_status.txt bcp.txt cap.txt getting_started.txt \
+ man_MANS	= freebcp.1 tsql.1 osql.1 bsqldb.1 bsqlodbc.1 defncopy.1 datacopy.1 fisql.1 \
+ 		  freetds.conf.5
+  
+-nobase_data_DATA	= $(DOCDIR)/reference/index.html $(DOCDIR)/userguide/index.htm
++noinst_DATA	= $(DOCDIR)/reference/index.html $(DOCDIR)/userguide/index.htm
+ 
+ $(DOCDIR)/userguide: $(DOCDIR)/userguide/index.htm
+ 
+@@ -110,7 +110,7 @@ datacopy.1: datacopy.txt
+ 
+ # If we built the documentation ourselves, install that, 
+ # else if we have access to distributed documentation, install that.  
+-install-data-local: installdirs $(DOCDIR)/reference/index.html $(DOCDIR)/userguide/index.htm
++install-data-local: installdirs $(noinst_DATA)
+ 	$(mkinstalldirs) $(DOCDIR) 2>&1
+ 	if test -r $(DOCDIR)/userguide ; then d=.; else d="$(srcdir)"; fi; \
+ 	find $$d/$(DOCDIR)/userguide \( -type f -o -type l \) -exec \
+
+commit bdb9653eec772ddd9d3ea2d6a28571f9f43924d1
+Author: jklowden <jklowden>
+Date:   Fri May 9 18:49:03 2008 +0000
+
+    handle 'server = ipaddr' in odbc.ini
+
+diff --git a/ChangeLog b/ChangeLog
+index 68334a5..6b21c25 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri May  9 14:47:15 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql handle 'server = ipaddr' in odbc.ini
++
+ Thu May  8 14:29:50 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/Makefile.am s/nobase_data/noinst/ per jlam on ML
+ 
+@@ -269,4 +272,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2516 2008/05/08 18:37:21 jklowden Exp $
++$Id: ChangeLog,v 1.2517 2008/05/09 18:49:03 jklowden Exp $
+diff --git a/src/apps/osql b/src/apps/osql
+index 20b2bfc..12e9bdc 100755
+--- a/src/apps/osql
++++ b/src/apps/osql
+@@ -1,5 +1,5 @@
+ #! /bin/sh
+-# $Id: osql,v 1.6 2007/02/06 02:51:18 jklowden Exp $
++# $Id: osql,v 1.7 2008/05/09 18:49:04 jklowden Exp $
+ #
+ # Check odbc.ini, odbcinst, and, optionally, freetds.conf, 
+ # then execute isql (assume it's unixODBC's isql).  
+@@ -301,7 +301,7 @@ then
+ else # odbc.ini contains a "server", a DNS host
+ 	HOST=$(echo ${SERVER_LINE} | awk '{print $3}')
+ 	echo "\"${ATTRIBUTE}\" found, not using freetds.conf"
+-	echo "FreeTDS servername is \"${HOST}\""
++	echo "${ATTRIBUTE} is \"${HOST}\""
+ 	if [ -z "${HOST}" ]
+ 	then
+ 		echo "$(basename $0): no value found for \"${ATTRIBUTE}\" entry in $(basename ${ODBC_INI})"
+@@ -309,12 +309,23 @@ else # odbc.ini contains a "server", a DNS host
+ 	fi
+ fi
+ 
+-# Now we have a DNS hostname for the server in HOST
++# If the "host" is an ip address, look up the name, for neatness, e.g. 
++## $ host 10.81.36.39
++## 39.36.81.10.IN-ADDR.ARPA domain name pointer ntc5003.eg.com
++if [ "${HOST}" = "$(echo ${HOST} | sed 's/[^.0-9]*//')" ]
++then 
++	ADDRESS=${HOST}
++	echo 'looking up hostname for ip address' ${ADDRESS}
++	HOST=$(host ${HOST} | awk '/domain/ {print $5}' | sed 's/\.$//')
++	if [ -z "${HOST}" ]
++	then
++		echo "$(basename $0): warning: no DNS hostname found for \"${ADDRESS}\""
++	fi
++fi
+ 
+-CMD="host ${HOST}"
++# Now we have a DNS hostname for the server in HOST
+ 
+-OUTPUT=$(${CMD})
+-ADDRESS=$(echo ${OUTPUT} | sed 's/..*has address //')
++ADDRESS=$(host ${HOST} | awk '/has address/ {print $4}' | head -1)
+ if [ -z "${ADDRESS}" ]
+ then
+ 	echo "$(basename $0): no IP address found for \"${HOST}\""
+@@ -327,11 +338,12 @@ echo ${HOST} has address ${ADDRESS}
+ 
+ printf "\n";
+ printf "%30s:\t%-30s\n" DSN ${DSN}
++printf "%30s:\t%-30s\n" Driver ${DRIVER}
+ printf "%30s:\t%-30s\n" "Server's hostname" ${HOST}
+ printf "%30s:\t%-30s\n" Address ${ADDRESS}
+-printf "%30s:\t%-30s\n" Driver ${DRIVER}
+ printf "\n";
+ 
+-echo Attempting connection as ${USERNAME}... 
++echo Attempting connection as ${USERNAME} ... 
++set -x
+ exec isql ${DSN} ${USERNAME} ${PASSWORD} -v
+ 
+
+commit 309e23918de64082b20c803e5ac23cf98f4707f0
+Author: castellano <castellano>
+Date:   Sun May 11 23:44:04 2008 +0000
+
+    cast to unsigned char when calling ctype macros
+
+diff --git a/ChangeLog b/ChangeLog
+index 6b21c25..58d8385 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun May 11 19:40:29 EDT 2008	Nick Castellano <entropy@freetds.org>
++	* src/replacements/readpassphrase.c:
++	- cast to unsigned char when calling ctype macros
++
+ Fri May  9 14:47:15 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/osql handle 'server = ipaddr' in odbc.ini
+ 
+@@ -272,4 +276,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2517 2008/05/09 18:49:03 jklowden Exp $
++$Id: ChangeLog,v 1.2518 2008/05/11 23:44:04 castellano Exp $
+diff --git a/src/replacements/readpassphrase.c b/src/replacements/readpassphrase.c
+index 007a45e..40c4069 100644
+--- a/src/replacements/readpassphrase.c
++++ b/src/replacements/readpassphrase.c
+@@ -171,9 +171,9 @@ restart:
+ 				ch &= 0x7f;
+ 			if (isalpha((unsigned char) ch)) {
+ 				if ((flags & RPP_FORCELOWER))
+-					ch = tolower(ch);
++					ch = tolower((unsigned char) ch);
+ 				if ((flags & RPP_FORCEUPPER))
+-					ch = toupper(ch);
++					ch = toupper((unsigned char) ch);
+ 			}
+ 			*p++ = ch;
+ 		}
+
+commit dc9b3b3b4f0c43228577218c0ff66bf78e0f7e86
+Author: jklowden <jklowden>
+Date:   Tue May 13 14:04:39 2008 +0000
+
+    added libtds.so question
+
+diff --git a/ChangeLog b/ChangeLog
+index 58d8385..5b66631 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,9 +1,12 @@
++Tue May 13 10:02:37 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/htdoc/faq.html added libtds.so question
++
+ Sun May 11 19:40:29 EDT 2008	Nick Castellano <entropy@freetds.org>
+ 	* src/replacements/readpassphrase.c:
+ 	- cast to unsigned char when calling ctype macros
+ 
+ Fri May  9 14:47:15 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* src/apps/osql handle 'server = ipaddr' in odbc.ini
++	* src/apps/osql handles 'server = ipaddr' in odbc.ini
+ 
+ Thu May  8 14:29:50 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/Makefile.am s/nobase_data/noinst/ per jlam on ML
+@@ -276,4 +279,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2518 2008/05/11 23:44:04 castellano Exp $
++$Id: ChangeLog,v 1.2519 2008/05/13 14:04:39 jklowden Exp $
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index d49ac66..ac1e3c2 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,7 +3,7 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.19 2008/04/24 15:59:29 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.20 2008/05/13 14:04:40 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+@@ -103,6 +103,8 @@
+         <tt>db-lib</tt>, <tt>ct-lib</tt>, and
+         <tt>ODBC</tt>?</a></li>
+ 
++        <li><a href="where.is.libtds.so">Where is <kbd>libtds.so</kbd>?</a></li>
++
+         <li><a href="#Which.Perl.library.should.I.use">Which Perl
+         library should I use?</a></li>
+ 
+@@ -482,6 +484,25 @@
+   which client API to write to, you might want to peruse our
+   <a href="which_api.html">brief discussion</a>. </p>
+ 
++  <h3 id="Where.is.libtds.so">
++  	Where is <kbd>libtds.so</kbd>?</h3>
++	
++  <p>As of version 0.82, the TDS utility library is not built 
++  as a shared object.  There is a static library <kbd>libtds.a</kbd>, 
++  although it's not installed by <b><kbd>make install</kbd></b>.  
++  <kbd>libtds</kbd> is statically linked to the "official" client 
++  libraries, <kbd>ct-lib</kbd>, <kbd>db-lib</kbd>, and <kbd>ODBC</kbd>.  
++  
++  <p>Distributing <kbd>libtds</kbd> as a shared object did more harm
++  than good.  Proper versioning and support was a burden on the 
++  developers, and it was just one more thing for a client application
++  to link in.  The only benefit was to programs that use more than
++  one client library. 
++  
++  <p>Of course, it's still free software, and you're free to build a 
++  shared object of it if you want to.  It's just not done "out of the box"
++  by the distributed makefiles.  
++
+   <h3>Which Perl library should I use?</h3>
+ 	<a name="Which.Perl.library.should.I.use" 
+ 	     id="Which.Perl.library.should.I.use"></a>
+@@ -843,7 +864,7 @@
+   <font size="-1">Updates and comments <a href=
+   "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
+   <br/>
+-    <i>$Id: faq.html,v 1.19 2008/04/24 15:59:29 jklowden Exp $</i>
++    <i>$Id: faq.html,v 1.20 2008/05/13 14:04:40 jklowden Exp $</i>
+ 	</font>
+ <hr/>
+   <p>
+
+commit 994d597992b09b68f6389ea8417d3019ca98c1b9
+Author: jklowden <jklowden>
+Date:   Tue May 13 14:11:54 2008 +0000
+
+    corrected bookmark
+
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index ac1e3c2..29e8c1b 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,7 +3,7 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.20 2008/05/13 14:04:40 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.21 2008/05/13 14:11:54 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+@@ -103,7 +103,7 @@
+         <tt>db-lib</tt>, <tt>ct-lib</tt>, and
+         <tt>ODBC</tt>?</a></li>
+ 
+-        <li><a href="where.is.libtds.so">Where is <kbd>libtds.so</kbd>?</a></li>
++        <li><a href="#where.is.libtds.so">Where is <kbd>libtds.so</kbd>?</a></li>
+ 
+         <li><a href="#Which.Perl.library.should.I.use">Which Perl
+         library should I use?</a></li>
+@@ -484,7 +484,7 @@
+   which client API to write to, you might want to peruse our
+   <a href="which_api.html">brief discussion</a>. </p>
+ 
+-  <h3 id="Where.is.libtds.so">
++  <h3 id="where.is.libtds.so">
+   	Where is <kbd>libtds.so</kbd>?</h3>
+ 	
+   <p>As of version 0.82, the TDS utility library is not built 
+@@ -864,7 +864,7 @@
+   <font size="-1">Updates and comments <a href=
+   "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
+   <br/>
+-    <i>$Id: faq.html,v 1.20 2008/05/13 14:04:40 jklowden Exp $</i>
++    <i>$Id: faq.html,v 1.21 2008/05/13 14:11:54 jklowden Exp $</i>
+ 	</font>
+ <hr/>
+   <p>
+
+commit 5a5de2ff8877d5b07442701a9e34912d5736fdb3
+Author: jklowden <jklowden>
+Date:   Thu May 15 15:49:52 2008 +0000
+
+    corrected odbc_nodm help string
+
+diff --git a/ChangeLog b/ChangeLog
+index 5b66631..9044b88 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May 15 11:43:18 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* configure.ac corrected odbc_nodm help string
++
+ Tue May 13 10:02:37 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/htdoc/faq.html added libtds.so question
+ 
+@@ -279,4 +282,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2519 2008/05/13 14:04:39 jklowden Exp $
++$Id: ChangeLog,v 1.2520 2008/05/15 15:49:52 jklowden Exp $
+diff --git a/configure.ac b/configure.ac
+index 8fed8b9..308c930 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.35 2008/03/23 17:29:57 jklowden Exp $
++dnl $Id: configure.ac,v 1.36 2008/05/15 15:49:52 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.35 $)
++AC_REVISION($Revision: 1.36 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -481,7 +481,7 @@ if test "$with_unixodbc"; then
+ fi
+ 
+ AC_ARG_WITH(odbc_nodm,
+-AS_HELP_STRING([--with-odbc-nodm=DIR], [build odbc without driver manager (headers in DIR)]))
++AS_HELP_STRING([--with-odbc-nodm=DIR], [build odbc using headers in DIR/include]))
+ if test "$with_odbc_nodm"; then
+ 	if echo "$with_odbc_nodm" | grep -v '^/'; then
+ 		with_odbc_nodm="$PWD/$with_odbc_nodm"
+
+commit 7d3358368bd06fd95447a6297a97cc2345b006ba
+Author: jklowden <jklowden>
+Date:   Thu May 22 01:32:29 2008 +0000
+
+    Blindly applied suggestion from S. Magne on ML  to fix ct_cancel for CS_CANCEL_ALL
+
+diff --git a/ChangeLog b/ChangeLog
+index 9044b88..e32e059 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed May 21 21:13:31 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* TODO doc/api_status.txt src/ctlib/ct.c
++	- Blindly applied suggestion from S. Magne on ML 
++	- to fix ct_cancel for CS_CANCEL_ALL
++
+ Thu May 15 11:43:18 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac corrected odbc_nodm help string
+ 
+@@ -282,4 +287,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2520 2008/05/15 15:49:52 jklowden Exp $
++$Id: ChangeLog,v 1.2521 2008/05/22 01:32:29 jklowden Exp $
+diff --git a/TODO b/TODO
+index 55b0fbf..5517ce6 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.167 2008/01/10 22:57:39 jklowden Exp $
++To Do List	$Id: TODO,v 1.168 2008/05/22 01:32:30 jklowden Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -21,6 +21,9 @@ Must be fixed:
+ . cancellation
+   . ctlib seems to hang reading row while in IDLE state
+     (tds_peek if not in pending state hang... update)
++    Applied but could not test fix from ML 21 May 2008: 
++    	"Problem with FreeTDS validating SQL commands 
++         (actually a ct_cancel() error)" 
+ 
+ Broken:
+ . Passing invalid character set names to server with tsql?
+diff --git a/doc/api_status.txt b/doc/api_status.txt
+index 811212f..f071889 100644
+--- a/doc/api_status.txt
++++ b/doc/api_status.txt
+@@ -1,7 +1,7 @@
+ #!/usr/pkg/bin/perl
+ # API status document
+ #
+-# $Id: api_status.txt,v 1.59 2007/12/17 00:11:09 jklowden Exp $s
++# $Id: api_status.txt,v 1.60 2008/05/22 01:32:31 jklowden Exp $s
+ #
+ # This tab-delimited file is a database of the "readiness" of the various
+ # APIs.  Please feel free to modify it if you notice something is missing or 
+@@ -507,7 +507,7 @@ ctlib	(all)	cs_ctx_drop	OK	Deallocate a CS_CONTEXT structure.
+ ctlib	(all)	cs_ctx_global	OK	Allocate or return a CS_CONTEXT structure.
+ ctlib	(all)	cs_diag	OK	Manage inline error handling.
+ ctlib	(all)	cs_dt_crack	OK	Convert a machine-readable datetime value into a user-accessible format.
+-ctlib	(all)	cs_dt_info	OK	Set or retrieve language-specific datetime information.
++ctlib	(all)	cs_dt_info	stub	Set or retrieve language-specific datetime information.
+ ctlib	(all)	cs_loc_alloc	OK	Allocate a CS_LOCALE structure.
+ ctlib	(all)	cs_loc_drop	OK	Deallocate a CS_LOCALE structure.
+ ctlib	(all)	cs_locale	partial	Load a CS_LOCALE structure with localization values or retrieve the locale name previously used to load a CS_LOCALE structure.
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 7a59712..9dabd00 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.178 2008/05/06 00:14:02 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.179 2008/05/22 01:32:32 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2242,6 +2242,7 @@ ct_cancel(CS_CONNECTION * conn, CS_COMMAND * cmd, CS_INT type)
+ 					tds_send_cancel(cmd_conn->tds_socket);
+ 					tds_process_cancel(cmd_conn->tds_socket);
+ 					_ct_initialise_cmd(cmd);
++					cmd->cancel_state = _CS_CANCEL_PENDING;
+ 					break;
+ 			}
+ 		}
+@@ -2263,6 +2264,7 @@ ct_cancel(CS_CONNECTION * conn, CS_COMMAND * cmd, CS_INT type)
+ 						tds_send_cancel(conn->tds_socket);
+ 						tds_process_cancel(conn->tds_socket);
+ 						_ct_initialise_cmd(conn_cmd);
++						conn_cmd->cancel_state = _CS_CANCEL_PENDING;
+ 					break;
+ 				}
+ 			}
+
+commit 96d0d49a19913677030a8e73d37c28e4eb5add03
+Author: jklowden <jklowden>
+Date:   Thu May 22 03:53:16 2008 +0000
+
+    applied ML patch from Craig A. Berry
+
+diff --git a/ChangeLog b/ChangeLog
+index e32e059..647f15f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed May 21 23:51:21 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/odbc/unittests/common.c
++	* vms/config_h.vms vms/descrip_mms.template
++	- applied ML patch from Craig A. Berry
++
+ Wed May 21 21:13:31 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* TODO doc/api_status.txt src/ctlib/ct.c
+ 	- Blindly applied suggestion from S. Magne on ML 
+@@ -287,4 +292,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2521 2008/05/22 01:32:29 jklowden Exp $
++$Id: ChangeLog,v 1.2522 2008/05/22 03:53:16 jklowden Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index f7b3283..4d65095 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.44 2008/03/12 13:35:49 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.45 2008/05/22 03:53:17 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -104,13 +104,21 @@ read_login_info(void)
+ 	/* find our driver */
+ 	if (!getcwd(path, sizeof(path)))
+ 		return 0;
++#ifdef __VMS
++	{
++	    /* A hard-coded driver path has to be in unix syntax to be recognized as such. */
++	    const char *unixspec = decc$translate_vms(path);
++	    if ( (int)unixspec != 0 && (int)unixspec != -1 ) strcpy(path, unixspec);
++	}
++#endif
+ 	len = strlen(path);
+ 	if (len < 10 || strcmp(path + len - 10, "/unittests") != 0)
+ 		return 0;
+ 	path[len - 9] = 0;
+ 	/* TODO this must be extended with all possible systems... */
+ 	if (!check_lib(path, ".libs/libtdsodbc.so") && !check_lib(path, ".libs/libtdsodbc.sl")
+-	    && !check_lib(path, ".libs/libtdsodbc.dll") && !check_lib(path, ".libs/libtdsodbc.dylib"))
++	    && !check_lib(path, ".libs/libtdsodbc.dll") && !check_lib(path, ".libs/libtdsodbc.dylib")
++	    && !check_lib(path, "_libs/libtdsodbc.exe"))
+ 		return 0;
+ 	strcpy(DRIVER, path);
+ 
+diff --git a/vms/config_h.vms b/vms/config_h.vms
+index e27183f..945185c 100644
+--- a/vms/config_h.vms
++++ b/vms/config_h.vms
+@@ -1,4 +1,4 @@
+-/* $Id: config_h.vms,v 1.7 2007/08/11 06:52:06 freddy77 Exp $ */
++/* $Id: config_h.vms,v 1.8 2008/05/22 03:53:18 jklowden Exp $ */
+ 
+ /* include/config.h.in.  Generated from configure.in by autoheader.  */
+ /* and edited by hand for VMS */
+@@ -18,6 +18,9 @@
+ /* Define to 1 if you have the <arpa/inet.h> header file. */
+ #define HAVE_ARPA_INET_H 1
+ 
++/* Define to 1 if you have the `alarm' function. */
++#define HAVE_ALARM 1
++
+ /* Define to 1 if you have the `asprintf' function. */
+ #define HAVE_ASPRINTF @D_ASPRINTF@
+ 
+@@ -339,7 +342,10 @@ char * readpassphrase(const char *, char *, size_t, int);
+     typedef __size_t socklen_t;
+ #endif
+ 
+-/* We only support unixODBC, so we do have this */
++/* We only support unixODBC, so we do have these */
+ #define HAVE_SQLGETPRIVATEPROFILESTRING 1
++#define HAVE_SQLLEN 1
++#define HAVE_SQLSETPOSIROW 1
++#define TDS_SQLCOLATTRIBUTE_SQLLEN 1
+ 
+ #endif /* CONFIG_H_LOADED */
+diff --git a/vms/descrip_mms.template b/vms/descrip_mms.template
+index f921372..8d9fe9f 100644
+--- a/vms/descrip_mms.template
++++ b/vms/descrip_mms.template
+@@ -16,7 +16,7 @@
+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ # Boston, MA 02111-1307, USA.
+ # 
+-# $Id: descrip_mms.template,v 1.12 2007/08/11 06:52:06 freddy77 Exp $
++# $Id: descrip_mms.template,v 1.13 2008/05/22 03:53:18 jklowden Exp $
+ 
+ # OpenVMS description file for FreeTDS
+ 
+@@ -384,7 +384,10 @@ dblibcheck :
+ tdsodbccheck : 
+ 	@ set default [.src.odbc.unittests]
+ 	@ define/nolog FREETDSCONF [---]freetds.conf
+-	@ define/nolog LIBTDSODBC [---]libtdsodbc$(E)
++	@ define/nolog ODBCINI SYS$DISK:[]ODBC.INI
++	@ define/nolog ODBCSYSINI SYS$DISK:[]
++	@ create/directory [-._libs]
++	@ copy [---]libtdsodbc$(E) [-._libs]
+ 	@ run/nodebug []t0001$(E)
+ 	@ run/nodebug []t0002$(E)
+ 	@ run/nodebug []t0003$(E)
+@@ -412,6 +415,7 @@ tdsodbccheck :
+ 	@ run/nodebug []data$(E)
+ 	@ run/nodebug []error$(E)
+ 	@ run/nodebug []rebindpar$(E)
++	@ run/nodebug []rpc$(E)
+ 	@ run/nodebug []convert_error$(E)
+ 	@ run/nodebug []typeinfo$(E)
+ 	@ run/nodebug []const_params$(E)
+@@ -420,6 +424,29 @@ tdsodbccheck :
+ 	@ run/nodebug []timeout$(E)
+ 	@ run/nodebug []array$(E)
+ 	@ run/nodebug []array_out$(E)
++	@ run/nodebug []cursor1$(E)
++	@ run/nodebug []scroll$(E)
++	@ run/nodebug []cursor2$(E)
++	@ run/nodebug []describecol$(E)
++	@ run/nodebug []copydesc$(E)
++	@ run/nodebug []prepclose$(E)
++	@ run/nodebug []warning$(E)
++	@ run/nodebug []paramcore$(E)
++	@ run/nodebug []timeout2$(E)
++	@ run/nodebug []timeout3$(E)
++	@ run/nodebug []connect2$(E)
++	@ run/nodebug []timeout4$(E)
++	@ run/nodebug []freeclose$(E)
++	@ run/nodebug []cursor3$(E)
++	@ run/nodebug []cursor4$(E)
++	@ run/nodebug []cursor5$(E)
++	@ run/nodebug []attributes$(E)
++	@ run/nodebug []hidden$(E)
++	@ run/nodebug []blob1$(E)
++	@ run/nodebug []cancel$(E)
++	@ run/nodebug []wchar$(E)
++	@ run/nodebug []rowset$(E)
++	@ run/nodebug []transaction2$(E)
+ 	@ set default [---]
+ 
+ buildchecks : libtdstests ctlibtests dblibtests $(ODBCTESTS)
+@@ -468,10 +495,19 @@ odbctests : [.src.odbc.unittests]t0001$(E) [.src.odbc.unittests]t0002$(E) [.src.
+ 	[.src.odbc.unittests]transaction$(E) [.src.odbc.unittests]genparams$(E) [.src.odbc.unittests]preperror$(E) \
+ 	[.src.odbc.unittests]prepare_results$(E) [.src.odbc.unittests]testodbc$(E) \
+ 	[.src.odbc.unittests]data$(E) [.src.odbc.unittests]error$(E) [.src.odbc.unittests]rebindpar$(E) \
+-	[.src.odbc.unittests]convert_error$(E) [.src.odbc.unittests]typeinfo$(E) \
++	[.src.odbc.unittests]rpc$(E) [.src.odbc.unittests]convert_error$(E) [.src.odbc.unittests]typeinfo$(E) \
+ 	[.src.odbc.unittests]const_params$(E) [.src.odbc.unittests]insert_speed$(E) \
+ 	[.src.odbc.unittests]compute$(E) [.src.odbc.unittests]timeout$(E) \
+-	[.src.odbc.unittests]array$(E) [.src.odbc.unittests]array_out$(E)
++	[.src.odbc.unittests]array$(E) [.src.odbc.unittests]array_out$(E) \
++	[.src.odbc.unittests]cursor1$(E) [.src.odbc.unittests]scroll$(E) [.src.odbc.unittests]cursor2$(E) \
++	[.src.odbc.unittests]describecol$(E) [.src.odbc.unittests]copydesc$(E) \
++	[.src.odbc.unittests]prepclose$(E) [.src.odbc.unittests]warning$(E) \
++	[.src.odbc.unittests]paramcore$(E) [.src.odbc.unittests]timeout2$(E) [.src.odbc.unittests]timeout3$(E) \
++	[.src.odbc.unittests]connect2$(E) [.src.odbc.unittests]timeout4$(E) [.src.odbc.unittests]freeclose$(E) \
++	[.src.odbc.unittests]cursor3$(E) [.src.odbc.unittests]cursor4$(E) [.src.odbc.unittests]cursor5$(E) \
++	[.src.odbc.unittests]attributes$(E) [.src.odbc.unittests]hidden$(E) [.src.odbc.unittests]blob1$(E) \
++	[.src.odbc.unittests]cancel$(E) [.src.odbc.unittests]wchar$(E) [.src.odbc.unittests]rowset$(E) \
++	[.src.odbc.unittests]transaction2$(E)
+ 	@ continue
+ 
+ # libtds test detailed dependencies
+@@ -1064,6 +1100,12 @@ odbctests : [.src.odbc.unittests]t0001$(E) [.src.odbc.unittests]t0002$(E) [.src.
+ [.src.odbc.unittests]rebindpar$(OBJ) : [.src.odbc.unittests]rebindpar.c [.src.odbc.unittests]common.h
+ 	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
+ 
++[.src.odbc.unittests]rpc$(E) : [.src.odbc.unittests]rpc$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]rpc$(OBJ) : [.src.odbc.unittests]rpc.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
+ [.src.odbc.unittests]convert_error$(E) : [.src.odbc.unittests]convert_error$(OBJ) [.src.odbc.unittests]common$(OBJ)
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
+ 
+@@ -1112,6 +1154,144 @@ odbctests : [.src.odbc.unittests]t0001$(E) [.src.odbc.unittests]t0002$(E) [.src.
+ [.src.odbc.unittests]array_out$(OBJ) : [.src.odbc.unittests]array_out.c [.src.odbc.unittests]common.h
+ 	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
+ 
++[.src.odbc.unittests]cursor1$(E) : [.src.odbc.unittests]cursor1$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]cursor1$(OBJ) : [.src.odbc.unittests]cursor1.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]scroll$(E) : [.src.odbc.unittests]scroll$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]scroll$(OBJ) : [.src.odbc.unittests]scroll.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]cursor2$(E) : [.src.odbc.unittests]cursor2$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]cursor2$(OBJ) : [.src.odbc.unittests]cursor2.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]describecol$(E) : [.src.odbc.unittests]describecol$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]describecol$(OBJ) : [.src.odbc.unittests]describecol.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]copydesc$(E) : [.src.odbc.unittests]copydesc$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]copydesc$(OBJ) : [.src.odbc.unittests]copydesc.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]prepclose$(E) : [.src.odbc.unittests]prepclose$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]prepclose$(OBJ) : [.src.odbc.unittests]prepclose.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]warning$(E) : [.src.odbc.unittests]warning$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]warning$(OBJ) : [.src.odbc.unittests]warning.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]paramcore$(E) : [.src.odbc.unittests]paramcore$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]paramcore$(OBJ) : [.src.odbc.unittests]paramcore.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]timeout2$(E) : [.src.odbc.unittests]timeout2$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]timeout2$(OBJ) : [.src.odbc.unittests]timeout2.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]timeout3$(E) : [.src.odbc.unittests]timeout3$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]timeout3$(OBJ) : [.src.odbc.unittests]timeout3.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]connect2$(E) : [.src.odbc.unittests]connect2$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]connect2$(OBJ) : [.src.odbc.unittests]connect2.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]timeout4$(E) : [.src.odbc.unittests]timeout4$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]timeout4$(OBJ) : [.src.odbc.unittests]timeout4.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]freeclose$(E) : [.src.odbc.unittests]freeclose$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]freeclose$(OBJ) : [.src.odbc.unittests]freeclose.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]cursor3$(E) : [.src.odbc.unittests]cursor3$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]cursor3$(OBJ) : [.src.odbc.unittests]cursor3.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]cursor4$(E) : [.src.odbc.unittests]cursor4$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]cursor4$(OBJ) : [.src.odbc.unittests]cursor4.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]cursor5$(E) : [.src.odbc.unittests]cursor5$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]cursor5$(OBJ) : [.src.odbc.unittests]cursor5.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]attributes$(E) : [.src.odbc.unittests]attributes$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]attributes$(OBJ) : [.src.odbc.unittests]attributes.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]hidden$(E) : [.src.odbc.unittests]hidden$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]hidden$(OBJ) : [.src.odbc.unittests]hidden.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]blob1$(E) : [.src.odbc.unittests]blob1$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]blob1$(OBJ) : [.src.odbc.unittests]blob1.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]rowset$(E) : [.src.odbc.unittests]rowset$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]rowset$(OBJ) : [.src.odbc.unittests]rowset.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]cancel$(E) : [.src.odbc.unittests]cancel$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]cancel$(OBJ) : [.src.odbc.unittests]cancel.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]wchar$(E) : [.src.odbc.unittests]wchar$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]wchar$(OBJ) : [.src.odbc.unittests]wchar.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[.src.odbc.unittests]transaction2$(E) : [.src.odbc.unittests]transaction2$(OBJ) [.src.odbc.unittests]common$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[.vms]libodbc.opt/options
++
++[.src.odbc.unittests]transaction2$(OBJ) : [.src.odbc.unittests]transaction2.c [.src.odbc.unittests]common.h
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.odbc.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
+ # Clean up
+ 
+ distclean :
+@@ -1119,6 +1299,8 @@ distclean :
+ 	@ if f$search("[...]*.LIS") .nes. "" then delete/noconfirm [...]*.LIS;*
+ 	@ if f$search("[...]*.MAP") .nes. "" then delete/noconfirm [...]*.MAP;*
+ 	@ if f$search("[...unittests]*$(E)") .nes. "" then delete/noconfirm [...unittests]*$(E);*
++	@ if f$search("[.src.odbc._libs]*$(E)") .nes. "" then delete/noconfirm [.src.odbc._libs]*$(E);*
++	@ if f$search("[...unittests]*.ini") .nes. "" then delete/noconfirm [...unittests]*.ini;*
+ 	@ if f$search("*$(OLB)") .nes. "" then purge/noconfirm *$(OLB)
+ 	@ if f$search("*$(E)") .nes. "" then purge/noconfirm *$(E)
+ 
+
+commit f1df4bd9beabb55ed3364dc3e031b58f40c9d818
+Author: freddy77 <freddy77>
+Date:   Mon May 26 13:56:48 2008 +0000
+
+    fix some memory problems
+
+diff --git a/ChangeLog b/ChangeLog
+index 647f15f..4e5919a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Wed May  7 15:56:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	(monstly from Coverity reports)
++	* include/tdsbytes.h: remove warning
++	* src/apps/tsql.c src/dblib/bcp.c src/dblib/dblib.c:
++	- remove some leaks
++	* src/tds/mem.c: avoid deference of null pointer
++
+ Wed May 21 23:51:21 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/odbc/unittests/common.c
+ 	* vms/config_h.vms vms/descrip_mms.template
+@@ -292,4 +299,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2522 2008/05/22 03:53:16 jklowden Exp $
++$Id: ChangeLog,v 1.2523 2008/05/26 13:56:48 freddy77 Exp $
+diff --git a/include/tdsbytes.h b/include/tdsbytes.h
+index 8529651..baf4a79 100644
+--- a/include/tdsbytes.h
++++ b/include/tdsbytes.h
+@@ -20,7 +20,7 @@
+ #ifndef _tdsbytes_h_
+ #define _tdsbytes_h_
+ 
+-/* $Id: tdsbytes.h,v 1.2 2005/08/10 12:06:03 freddy77 Exp $ */
++/* $Id: tdsbytes.h,v 1.3 2008/05/26 13:56:49 freddy77 Exp $ */
+ 
+ #ifndef _tds_h_
+ #error tds.h must be included before tdsbytes.h
+@@ -61,9 +61,9 @@
+ #define TDS_GET_A2BE(ptr) TDS_GET_UA2BE(ptr)
+ 
+ #define TDS_PUT_UA2LE(ptr,val) do {\
+- ((TDS_UCHAR*)(ptr))[1] = (val)>>8; ((TDS_UCHAR*)(ptr))[0] = (val); } while(0)
++ ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)(val); } while(0)
+ #define TDS_PUT_UA2BE(ptr,val) do {\
+- ((TDS_UCHAR*)(ptr))[0] = (val)>>8; ((TDS_UCHAR*)(ptr))[1] = (val); } while(0)
++ ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)(val); } while(0)
+ #define TDS_PUT_A2LE(ptr,val) TDS_PUT_UA2LE(ptr,val)
+ #define TDS_PUT_A2BE(ptr,val) TDS_PUT_UA2BE(ptr,val)
+ 
+@@ -78,11 +78,11 @@
+ #define TDS_GET_A4BE(ptr) TDS_GET_UA4BE(ptr)
+ 
+ #define TDS_PUT_UA4LE(ptr,val) do {\
+- ((TDS_UCHAR*)(ptr))[3] = (val)>>24; ((TDS_UCHAR*)(ptr))[2] = (val)>>16;\
+- ((TDS_UCHAR*)(ptr))[1] = (val)>>8; ((TDS_UCHAR*)(ptr))[0] = (val); } while(0)
++ ((TDS_UCHAR*)(ptr))[3] = (TDS_UCHAR)((val)>>24); ((TDS_UCHAR*)(ptr))[2] = (TDS_UCHAR)((val)>>16);\
++ ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)(val); } while(0)
+ #define TDS_PUT_UA4BE(ptr,val) do {\
+- ((TDS_UCHAR*)(ptr))[0] = (val)>>24; ((TDS_UCHAR*)(ptr))[1] = (val)>>16;\
+- ((TDS_UCHAR*)(ptr))[2] = (val)>>8; ((TDS_UCHAR*)(ptr))[3] = (val); } while(0)
++ ((TDS_UCHAR*)(ptr))[0] = (TDS_UCHAR)((val)>>24); ((TDS_UCHAR*)(ptr))[1] = (TDS_UCHAR)((val)>>16);\
++ ((TDS_UCHAR*)(ptr))[2] = (TDS_UCHAR)((val)>>8); ((TDS_UCHAR*)(ptr))[3] = (TDS_UCHAR)(val); } while(0)
+ #define TDS_PUT_A4LE(ptr,val) TDS_PUT_UA4LE(ptr,val)
+ #define TDS_PUT_A4BE(ptr,val) TDS_PUT_UA4BE(ptr,val)
+ 
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 17268ef..a298b79 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.113 2008/01/11 12:43:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.114 2008/05/26 13:56:49 freddy77 Exp $");
+ 
+ enum
+ {
+@@ -524,6 +524,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 	}
+ 
+ 	/* free up all the memory */
++	free(confile);
+ 	free(hostname);
+ 	free(username);
+ 	free(password);
+@@ -572,6 +573,7 @@ slurp_input_file(char *fname, char **mybuf, int *bufsz, size_t *buflen, int *lin
+ 		tsql_add_history(s);
+ 		(*line)++;
+ 	}
++	fclose(fp);
+ }
+ 
+ extern const char STD_DATETIME_FMT[];
+@@ -709,7 +711,7 @@ main(int argc, char **argv)
+ 		 *  The rest of the line may include options that apply to the batch, 
+ 		 *  and perhaps whitespace.  
+ 		 */
+-		if (0 == strncasecmp(s, "go", 2) && (strlen(s) == 2 || isspace(s[2]))) {
++		if (0 == strncasecmp(s, "go", 2) && (strlen(s) == 2 || TDS_ISSPACE(s[2]))) {
+ 			char *go_line = strdup(s);
+ 			assert(go_line);
+ 			line = 0;
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index d238783..2810fcb 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -71,7 +71,7 @@ typedef struct _pbcb
+ }
+ TDS_PBCB;
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.171 2008/01/08 15:38:31 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.172 2008/05/26 13:56:49 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -799,11 +799,13 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 
+ 	if (dbproc->bcpinfo->direction == DB_QUERYOUT ) {
+ 		if (tds_submit_query(tds, dbproc->bcpinfo->tablename) == TDS_FAIL) {
++			fclose(hostfile);
+ 			return FAIL;
+ 		}
+ 	} else {
+ 		/* TODO quote if needed */
+ 		if (tds_submit_queryf(tds, "select * from %s", dbproc->bcpinfo->tablename) == TDS_FAIL) {
++			fclose(hostfile);
+ 			return FAIL;
+ 		}
+ 	}
+@@ -1061,6 +1063,7 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 					break;
+ 				}
+ 				if( plen != 0 && written != 1 ) {
++					fclose(hostfile);
+ 					dbperror(dbproc, SYBEBCWE, errno);
+ 					return FAIL;
+ 				}
+@@ -1073,6 +1076,7 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 				if (buflen > 0) {
+ 					written = fwrite(hostcol->bcp_column_data->data, buflen, 1, hostfile);
+ 					if (written < 1) {
++						fclose(hostfile);
+ 						dbperror(dbproc, SYBEBCWE, errno);
+ 						return FAIL;
+ 					}
+@@ -1082,6 +1086,7 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 				if (hostcol->terminator && hostcol->term_len > 0) {
+ 					written = fwrite(hostcol->terminator, hostcol->term_len, 1, hostfile);
+ 					if (written < 1) {
++						fclose(hostfile);
+ 						dbperror(dbproc, SYBEBCWE, errno);
+ 						return FAIL;
+ 					}
+@@ -1094,6 +1099,7 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 		dbperror(dbproc, SYBEBCUC, errno);
+ 		return (FAIL);
+ 	}
++	hostfile = NULL;
+ 
+ 	if (dbproc->hostfileinfo->firstrow > 0 && row_of_query < dbproc->hostfileinfo->firstrow) {
+ 		/* 
+@@ -1896,8 +1902,10 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 		return FAIL;
+ 	}
+ 
+-	if (_bcp_start_copy_in(dbproc) == FAIL)
++	if (_bcp_start_copy_in(dbproc) == FAIL) {
++		fclose(hostfile);
+ 		return FAIL;
++	}
+ 
+ 	tds->out_flag = TDS_BULK;
+ 	tds_set_state(tds, TDS_QUERYING);
+@@ -1922,6 +1930,7 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 
+ 			if (errfile == NULL && dbproc->hostfileinfo->errorfile) {
+ 				if (!(errfile = fopen(dbproc->hostfileinfo->errorfile, "w"))) {
++					fclose(hostfile);
+ 					dbperror(dbproc, SYBEBUOE, 0);
+ 					return FAIL;
+ 				}
+@@ -2003,6 +2012,7 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 						if (tds_process_simple_query(tds) != TDS_SUCCEED) {
+ 							if (errfile)
+ 								fclose(errfile);
++							fclose(hostfile);
+ 							return FAIL;
+ 						}
+ 							
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 4056b75..0d40af7 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.323 2008/04/30 14:09:53 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.324 2008/05/26 13:56:49 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -3321,8 +3321,10 @@ dbprrow(DBPROCESS * dbproc)
+ 			computeid = status;
+ 
+ 			for (i = 0;; ++i) {
+-				if (i >= tds->num_comp_info)
++				if (i >= tds->num_comp_info) {
++					free(col_printlens);
+ 					return FAIL;
++				}
+ 				resinfo = tds->comp_info[i];
+ 				if (resinfo->computeid == computeid)
+ 					break;
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 66a5a40..35953b2 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.175 2007/12/31 10:06:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.176 2008/05/26 13:56:50 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -1040,6 +1040,9 @@ tds_free_locale(TDSLOCALE * locale)
+ void
+ tds_free_connection(TDSCONNECTION * connection)
+ {
++	if (!connection)
++		return;
++
+ 	tds_dstr_free(&connection->server_name);
+ 	tds_dstr_free(&connection->client_host_name);
+ 	tds_dstr_free(&connection->server_host_name);
+
+commit ff84b60a1f87fa51b6c5138613972cb8737813b8
+Author: freddy77 <freddy77>
+Date:   Tue May 27 08:00:56 2008 +0000
+
+    fix possible buffer overflow
+
+diff --git a/ChangeLog b/ChangeLog
+index 4e5919a..35d0b69 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,4 +1,7 @@
+-Wed May  7 15:56:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Tue May 27 10:0:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: fix possible buffer overflow
++
++Mon May 26 15:56:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	(monstly from Coverity reports)
+ 	* include/tdsbytes.h: remove warning
+ 	* src/apps/tsql.c src/dblib/bcp.c src/dblib/dblib.c:
+@@ -299,4 +302,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2523 2008/05/26 13:56:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2524 2008/05/27 08:00:56 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 50d0282..fcffb2f 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.286 2008/04/23 21:36:01 jklowden Exp $ */
++/* $Id: tds.h,v 1.287 2008/05/27 08:00:57 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -747,7 +747,7 @@ typedef enum tds_encryption_level {
+ 
+ 
+ #define TDS_MAX_CAPABILITY	22
+-#define MAXPRECISION 		80
++#define MAXPRECISION 		77
+ #define TDS_MAX_CONN		4096
+ #define TDS_MAX_DYNID_LEN	30
+ 
+
+commit b92452491c54bf5e885b3bc2ebe43af1c1f22819
+Author: freddy77 <freddy77>
+Date:   Tue May 27 08:25:04 2008 +0000
+
+    compile fix, add compile time test
+
+diff --git a/ChangeLog b/ChangeLog
+index 35d0b69..b836129 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,4 +1,8 @@
+-Tue May 27 10:0:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Tue May 27 10:23:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: compile fix
++	* src/tds/numeric.c: add test to avoid future buffer overflows
++
++Tue May 27 10:00:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h: fix possible buffer overflow
+ 
+ Mon May 26 15:56:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+@@ -302,4 +306,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2524 2008/05/27 08:00:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2525 2008/05/27 08:25:04 freddy77 Exp $
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index a298b79..c394745 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,9 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.114 2008/05/26 13:56:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.115 2008/05/27 08:25:04 freddy77 Exp $");
++
++#define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+ enum
+ {
+diff --git a/src/tds/numeric.c b/src/tds/numeric.c
+index 57a0e1a..9d8cff2 100644
+--- a/src/tds/numeric.c
++++ b/src/tds/numeric.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: numeric.c,v 1.42 2006/12/26 14:56:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: numeric.c,v 1.43 2008/05/27 08:25:05 freddy77 Exp $");
+ 
+ /* 
+  * these routines use arrays of unsigned char to handle arbitrary
+@@ -63,8 +63,8 @@ const int tds_numeric_bytes_per_prec[] = {
+ 	 * core if for some bug it's 0...
+ 	 */
+ 	1, 
+-	2, 2, 3, 3, 4, 4, 4, 5, 5,
+-	6, 6, 6, 7, 7, 8, 8, 9, 9, 9,
++	2,  2,  3,  3,  4,  4,  4,  5,  5,
++	6,  6,  6,  7,  7,  8,  8,  9,  9,  9,
+ 	10, 10, 11, 11, 11, 12, 12, 13, 13, 14,
+ 	14, 14, 15, 15, 16, 16, 16, 17, 17, 18,
+ 	18, 19, 19, 19, 20, 20, 21, 21, 21, 22,
+@@ -73,6 +73,21 @@ const int tds_numeric_bytes_per_prec[] = {
+ 	31, 31, 31, 32, 32, 33, 33, 33
+ };
+ 
++#if ENABLE_EXTRA_CHECKS
++
++#if defined(__GNUC__) && __GNUC__ >= 2
++#define COMPILE_CHECK(name,check) \
++    extern int name[(check)?1:-1] __attribute__ ((unused))
++#else
++#define COMPILE_CHECK(name,check) \
++    extern int name[(check)?1:-1]
++#endif
++
++COMPILE_CHECK(maxprecision, 
++	MAXPRECISION < TDS_VECTOR_SIZE(tds_numeric_bytes_per_prec) );
++
++#endif
++
+ /*
+  * money is a special case of numeric really...that why its here
+  */
+
+commit 71ee1e4c71bbcb5a2663695bab03eb15941d0fd0
+Author: jklowden <jklowden>
+Date:   Tue May 27 22:24:48 2008 +0000
+
+    include arpa/inet.h
+
+diff --git a/ChangeLog b/ChangeLog
+index b836129..2cc0fb7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue May 27 18:21:46 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/tds.h include arpa/inet.h
++
+ Tue May 27 10:23:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/tsql.c: compile fix
+ 	* src/tds/numeric.c: add test to avoid future buffer overflows
+@@ -306,4 +309,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2525 2008/05/27 08:25:04 freddy77 Exp $
++$Id: ChangeLog,v 1.2526 2008/05/27 22:24:48 jklowden Exp $
+diff --git a/include/tds.h b/include/tds.h
+index fcffb2f..ec2cecd 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,12 +20,16 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.287 2008/05/27 08:00:57 freddy77 Exp $ */
++/* $Id: tds.h,v 1.288 2008/05/27 22:24:49 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <time.h>
+ 
++#if HAVE_ARPA_INET_H
++#include <arpa/inet.h>
++#endif /* HAVE_ARPA_INET_H */
++
+ /* forward declaration */
+ typedef struct tdsiconvinfo TDSICONV;
+ typedef struct tds_socket TDSSOCKET;
+
+commit 9b6fadfc272c9a8941ca245c40fd22c9be66d112
+Author: jklowden <jklowden>
+Date:   Wed May 28 13:44:19 2008 +0000
+
+    reset getopt(3) portably
+
+diff --git a/ChangeLog b/ChangeLog
+index 2cc0fb7..dc9ff25 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed May 28 09:41:16 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* configure.ac src/apps/tsql.c  
++	- reset getopt(3) portably
++
+ Tue May 27 18:21:46 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h include arpa/inet.h
+ 
+@@ -309,4 +313,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2526 2008/05/27 22:24:48 jklowden Exp $
++$Id: ChangeLog,v 1.2527 2008/05/28 13:44:19 jklowden Exp $
+diff --git a/configure.ac b/configure.ac
+index 308c930..1e37fdf 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.36 2008/05/15 15:49:52 jklowden Exp $
++dnl $Id: configure.ac,v 1.37 2008/05/28 13:44:19 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.36 $)
++AC_REVISION($Revision: 1.37 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -240,7 +240,7 @@ AC_CHECK_MEMBERS([struct tm.__tm_zone],,,[#include <sys/types.h>
+ ])
+ AC_CHECK_HEADERS([unistd.h errno.h wchar.h sys/time.h sys/types.h \
+ sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h \
+-signal.h libgen.h poll.h])
++signal.h libgen.h poll.h getopt.h])
+ if test $tds_mingw = no; then
+ 	AC_CHECK_HEADERS([sys/socket.h arpa/inet.h netdb.h netinet/in.h \
+ netinet/tcp.h paths.h sys/ioctl.h langinfo.h])
+@@ -347,6 +347,16 @@ AC_EGREP_CPP(yes,
+ 
+ TYPE_SOCKLEN_T
+ 
++AC_MSG_CHECKING([whether getopt has optreset support])
++AC_TRY_LINK([#ifdef HAVE_GETOPT_H
++#include <getopt.h>
++#endif], [extern int optreset; optreset = 0;],
++[AC_MSG_RESULT(yes)
++AC_DEFINE(HAVE_GETOPT_OPTRESET, 1, [Define if your getopt(3) defines and uses optreset])],
++[AC_MSG_RESULT(no)]
++)
++
++
+ # ------------------------------------------------------------
+ # Checks for compiler characteristics.
+ # ------------------------------------------------------------
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index c394745..cb4ae36 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.115 2008/05/27 08:25:04 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.116 2008/05/28 13:44:19 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -303,6 +303,15 @@ tsql_print_usage(const char *progname)
+ 		progname, progname);
+ }
+ 
++static int
++reset_getopt(void)
++{
++#ifdef HAVE_GETOPT_OPTRESET
++	optreset = 1;
++#endif
++	optind = 1;
++}
++
+ /*
+  * The 'GO' command may be followed by options that apply to the batch.
+  * If they don't appear to be right, assume the letters "go" are part of the
+@@ -326,7 +335,7 @@ get_opt_flags(char *s, int *opt_flags)
+ 		s = NULL;
+ 
+ 	*opt_flags = 0;
+-	optind = 0;		/* reset getopt */
++	reset_getopt();
+ 	opterr = 0;		/* suppress error messages */
+ 	while ((opt = getopt(argc, argv, "fhqtv")) != -1) {
+ 		switch (opt) {
+
+commit 37d026f04c81794aad8ea7fee821062a102df561
+Author: freddy77 <freddy77>
+Date:   Wed May 28 20:08:48 2008 +0000
+
+    fix minor memory leaks
+
+diff --git a/ChangeLog b/ChangeLog
+index dc9ff25..3a2af23 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed May 28 22:08:36 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/freebcp.c src/apps/tsql.c:
++	- fix minor memory leaks
++
+ Wed May 28 09:41:16 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac src/apps/tsql.c  
+ 	- reset getopt(3) portably
+@@ -313,4 +317,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2527 2008/05/28 13:44:19 jklowden Exp $
++$Id: ChangeLog,v 1.2528 2008/05/28 20:08:48 freddy77 Exp $
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 0cc051f..86d9a2b 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -45,7 +45,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.48 2006/12/01 21:51:11 jklowden Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.49 2008/05/28 20:08:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -351,6 +351,8 @@ login_to_database(BCPPARAMDATA * pdata, DBPROCESS ** pdbproc)
+ 	 */
+ 
+ 	login = dblogin();
++	if (!login)
++		return FALSE;
+ 
+ 	DBSETLUSER(login, pdata->user);
+ 	DBSETLPWD(login, pdata->pass);
+@@ -372,8 +374,11 @@ login_to_database(BCPPARAMDATA * pdata, DBPROCESS ** pdbproc)
+ 
+ 	if ((*pdbproc = dbopen(login, pdata->server)) == NULL) {
+ 		fprintf(stderr, "Can't connect to server \"%s\".\n", pdata->server);
++		dbloginfree(login);
+ 		return (FALSE);
+ 	}
++	dbloginfree(login);
++	login = NULL;
+ 
+ 	/* set hint if any */
+ 	if (pdata->hint) {
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index cb4ae36..edb1c08 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.116 2008/05/28 13:44:19 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.117 2008/05/28 20:08:48 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -407,24 +407,24 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 			opt_flags_str = optarg;
+ 			break;
+ 		case 'H':
+-			hostname = (char *) malloc(strlen(optarg) + 1);
+-			strcpy(hostname, optarg);
++			free(hostname);
++			hostname = strdup(optarg);
+ 			break;
+ 		case 'S':
+-			servername = (char *) malloc(strlen(optarg) + 1);
+-			strcpy(servername, optarg);
++			free(servername);
++			servername = strdup(optarg);
+ 			break;
+ 		case 'U':
+-			username = (char *) malloc(strlen(optarg) + 1);
+-			strcpy(username, optarg);
++			free(username);
++			username = strdup(optarg);
+ 			break;
+ 		case 'P':
+-			password = (char *) malloc(strlen(optarg) + 1);
+-			strcpy(password, optarg);
++			free(password);
++			password = strdup(optarg);
+ 			break;
+ 		case 'I':
+-			confile = (char *) malloc(strlen(optarg) + 1);
+-			strcpy(confile, optarg);
++			free(confile);
++			confile = strdup(optarg);
+ 			break;
+ 		case 'p':
+ 			port = atoi(optarg);
+
+commit 8c308956ba3bcc83020e15e59f1739127d33c013
+Author: freddy77 <freddy77>
+Date:   Wed May 28 21:08:32 2008 +0000
+
+    prevent NULL access
+
+diff --git a/ChangeLog b/ChangeLog
+index 3a2af23..9273abb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 28 23:08:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/server/server.c: fix possible NULL access
++
+ Wed May 28 22:08:36 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/freebcp.c src/apps/tsql.c:
+ 	- fix minor memory leaks
+@@ -317,4 +320,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2528 2008/05/28 20:08:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2529 2008/05/28 21:08:32 freddy77 Exp $
+diff --git a/src/server/server.c b/src/server/server.c
+index 4937708..673b36f 100644
+--- a/src/server/server.c
++++ b/src/server/server.c
+@@ -30,7 +30,7 @@
+ #include "tds.h"
+ #include "tdssrv.h"
+ 
+-static char software_version[] = "$Id: server.c,v 1.24 2008/01/07 14:07:21 freddy77 Exp $";
++static char software_version[] = "$Id: server.c,v 1.25 2008/05/28 21:08:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void
+@@ -117,13 +117,17 @@ tds_send_msg(TDSSOCKET * tds, int msgno, int msgstate, int severity,
+ 	     const char *msgtext, const char *srvname, const char *procname, int line)
+ {
+ 	int msgsz;
++	size_t len;
+ 
+ 	tds_put_byte(tds, TDS_INFO_TOKEN);
++	if (!procname)
++		procname = "";
++	len = strlen(procname);
+ 	msgsz = 4		/* msg no    */
+ 		+ 1		/* msg state */
+ 		+ 1		/* severity  */
+ 		/* FIXME ucs2 */
+-		+ (IS_TDS7_PLUS(tds) ? 2 : 1) * (strlen(msgtext) + 1 + strlen(srvname) + 1 + strlen(procname))
++		+ (IS_TDS7_PLUS(tds) ? 2 : 1) * (strlen(msgtext) + 1 + strlen(srvname) + 1 + len)
+ 		+ 1 + 2;	/* line number */
+ 	tds_put_smallint(tds, msgsz);
+ 	tds_put_int(tds, msgno);
+@@ -135,10 +139,10 @@ tds_send_msg(TDSSOCKET * tds, int msgno, int msgstate, int severity,
+ 	tds_put_byte(tds, strlen(srvname));
+ 	/* FIXME ucs2 */
+ 	tds_put_string(tds, srvname, strlen(srvname));
+-	if (procname && strlen(procname)) {
+-		tds_put_byte(tds, strlen(procname));
++	if (len) {
++		tds_put_byte(tds, len);
+ 		/* FIXME ucs2 */
+-		tds_put_string(tds, procname, strlen(procname));
++		tds_put_string(tds, procname, len);
+ 	} else {
+ 		tds_put_byte(tds, 0);
+ 	}
+
+commit 2fd670b39708a09c1f9ce946a9627f416763af88
+Author: freddy77 <freddy77>
+Date:   Sat May 31 08:54:31 2008 +0000
+
+    remove warning
+
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index edb1c08..7a668cd 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.117 2008/05/28 20:08:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.118 2008/05/31 08:54:31 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -303,7 +303,7 @@ tsql_print_usage(const char *progname)
+ 		progname, progname);
+ }
+ 
+-static int
++static void
+ reset_getopt(void)
+ {
+ #ifdef HAVE_GETOPT_OPTRESET
+
+commit c003018ad0a0595ed82147f242adb4c76cc6fd67
+Author: jklowden <jklowden>
+Date:   Mon Jun 2 14:18:44 2008 +0000
+
+    applied ML patch of 19 May 2008 for BLK_VERSION for sqsh
+
+diff --git a/ChangeLog b/ChangeLog
+index 9273abb..ee00309 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri May 30 17:47:59 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/cspublic.h 
++	- applied ML patch of 19 May 2008 for BLK_VERSION for sqsh
++
+ Wed May 28 23:08:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/server/server.c: fix possible NULL access
+ 
+@@ -320,4 +324,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2529 2008/05/28 21:08:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2530 2008/06/02 14:18:44 jklowden Exp $
+diff --git a/include/cspublic.h b/include/cspublic.h
+index 69914c3..954b24f 100644
+--- a/include/cspublic.h
++++ b/include/cspublic.h
+@@ -34,7 +34,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.58 2007/06/25 09:48:20 freddy77 Exp $";
++static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.59 2008/06/02 14:18:44 jklowden Exp $";
+ static const void *const no_unused_cspublic_h_warn[] = { rcsid_cspublic_h, no_unused_cspublic_h_warn };
+ 
+ #define CS_PUBLIC
+@@ -447,6 +447,9 @@ enum
+ 
+ #define BLK_VERSION_100 CS_VERSION_100
+ #define BLK_VERSION_110 CS_VERSION_100
++#define BLK_VERSION_120 CS_VERSION_120
++#define BLK_VERSION_125 CS_VERSION_125
++#define BLK_VERSION_150 CS_VERSION_150
+ 
+ #define CS_FORCE_EXIT	300
+ #define CS_FORCE_CLOSE  301
+
+commit fb859d1d726b540f0d8ce9bd8fcc7f849a79637f
+Author: freddy77 <freddy77>
+Date:   Thu Jun 5 16:08:46 2008 +0000
+
+    add new test
+
+diff --git a/ChangeLog b/ChangeLog
+index ee00309..f1fb9c4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jun 05 18:08:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor6.c(added):
++	- added new test
++
+ Fri May 30 17:47:59 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cspublic.h 
+ 	- applied ML patch of 19 May 2008 for BLK_VERSION for sqsh
+@@ -324,4 +328,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2530 2008/06/02 14:18:44 jklowden Exp $
++$Id: ChangeLog,v 1.2531 2008/06/05 16:08:46 freddy77 Exp $
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index b8adb7f..c1a686e 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -61,6 +61,7 @@ freeclose
+ cursor3
+ cursor4
+ cursor5
++cursor6
+ attributes
+ hidden
+ blob1
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 6254689..ad4ee0f 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.74 2008/03/07 10:57:54 freddy77 Exp $
++# $Id: Makefile.am,v 1.75 2008/06/05 16:12:19 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -21,7 +21,8 @@ TESTS		=	\
+ 			connect2$(EXEEXT) timeout4$(EXEEXT) freeclose$(EXEEXT) \
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+-			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT)
++			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT) \
++			cursor6$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -84,6 +85,7 @@ rowset_SOURCES	= rowset.c common.c common.h
+ cancel_SOURCES = cancel.c common.c common.h
+ wchar_SOURCES = wchar.c common.c common.h
+ transaction2_SOURCES = transaction2.c common.c common.h
++cursor6_SOURCES	= cursor6.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c
+new file mode 100755
+index 0000000..430788a
+--- /dev/null
++++ b/src/odbc/unittests/cursor6.c
+@@ -0,0 +1,135 @@
++#include "common.h"
++
++/* Test SQLFetchScroll with no binded columns */
++
++static char software_version[] = "$Id: cursor6.c,v 1.1 2008/06/05 16:08:46 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static int bind_all = 0;
++static int normal_fetch = 0;
++static int use_cursors = 1;
++
++static void Test(void)
++{
++#define ROWS 5
++	struct data_t {
++		SQLINTEGER i;
++		SQLLEN ind_i;
++		char c[20];
++		SQLLEN ind_c;
++	} data[ROWS];
++	SQLUSMALLINT statuses[ROWS];
++	SQLULEN num_row;
++
++	ResetStatement();
++
++	/* this should not fail or return warnings */
++	if (use_cursors) {
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0));
++		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0));
++	}
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT c, i FROM #cursor6_test", SQL_NTS));
++	CHK(SQLExecute, (Statement));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, statuses, 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
++	if (bind_all)
++		CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c));
++	CHK(SQLBindCol, (Statement, 2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i));
++
++#define FILL(s, n) do { \
++	int _n; for (_n = 0; _n < sizeof(s)/sizeof(s[0]); ++_n) s[_n] = n; \
++} while(0)
++	FILL(statuses, 9876);
++	num_row = -3;
++	data[0].i = 0xdeadbeef;
++	data[1].i = 0xdeadbeef;
++	if (normal_fetch)
++		CHK(SQLFetch, (Statement));
++	else
++		CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
++
++	/* now check row numbers */
++	printf("num_row %d statuses[0] %d statuses[1] %d odbc3 %d\n", (int) num_row,
++		(int) statuses[0], (int) statuses[1], use_odbc_version3);
++
++	if (use_odbc_version3 || !normal_fetch) {
++		if (num_row != ROWS || statuses[0] != SQL_ROW_SUCCESS || statuses[1] != SQL_ROW_SUCCESS) {
++			fprintf(stderr, "result error 1\n");
++			exit(1);
++		}
++	} else {
++		if (data[0].i != 1 || data[1].i != 0xdeadbeef) {
++			fprintf(stderr, "result error 2\n");
++			exit(1);
++		}
++	}
++
++	FILL(statuses, 8765);
++	num_row = -3;
++	if (normal_fetch)
++		CHK(SQLFetch, (Statement));
++	else
++		CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
++}
++
++static void Init(void)
++{
++	int i;
++	char sql[128];
++
++	Command(Statement, "CREATE TABLE #cursor6_test (i INT, c VARCHAR(20))");
++	for (i = 1; i <= 10; ++i) {
++		sprintf(sql, "INSERT INTO #cursor6_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
++		Command(Statement, sql);
++	}
++
++}
++
++int
++main(int argc, char *argv[])
++{
++	unsigned char sqlstate[6];
++	unsigned char msg[256];
++	SQLRETURN retcode;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE,  (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
++	if (retcode != SQL_SUCCESS) {
++		CHK(SQLGetDiagRec, (SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL));
++		sqlstate[5] = 0;
++		if (strcmp((const char*) sqlstate, "S1092") == 0) {
++			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
++			Disconnect();
++			exit(0);
++		}
++		ODBC_REPORT_ERROR("SQLSetConnectAttr");
++	}
++
++	Init();
++
++#define ALL(n) for (n = 0; n < 2; ++n)
++	ALL(use_cursors)
++		ALL(bind_all)
++			ALL(normal_fetch)
++				Test();
++
++	Disconnect();
++
++	use_odbc_version3 = 0;
++
++	Connect();
++	Init();
++
++	ALL(use_cursors)
++		ALL(bind_all)
++			ALL(normal_fetch)
++				Test();
++
++	Disconnect();
++	
++	return 0;
++}
+
+commit 003527e70e4e2d8b55e1ffe453399ca579860449
+Author: freddy77 <freddy77>
+Date:   Thu Jun 5 16:21:50 2008 +0000
+
+    fix some SQLFetch/SQLFetchScroll issues
+
+diff --git a/ChangeLog b/ChangeLog
+index f1fb9c4..49e1eb2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jun 05 18:21:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- fix cursor6 test
++	- SQLFetch odbc 2 compliant
++
+ Thu Jun 05 18:08:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor6.c(added):
+ 	- added new test
+@@ -328,4 +333,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2531 2008/06/05 16:08:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2532 2008/06/05 16:21:50 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 3f4f497..a69da4f 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.480 2008/04/29 15:08:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.481 2008/06/05 16:21:54 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3670,10 +3670,6 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 					truncated = 1;
+ 					stmt->errs.lastrc = SQL_SUCCESS_WITH_INFO;
+ 				}
+-			} else {
+-				/* TODO change when we code cursors support... */
+-				/* stop looping, forward cursor support only one row */
+-				num_rows = 1;
+ 			}
+ 			if (drec_ard->sql_desc_octet_length_ptr)
+ 				*AT_ROW(drec_ard->sql_desc_octet_length_ptr, SQLLEN) = len;
+@@ -3710,11 +3706,33 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ SQLRETURN ODBC_API
+ SQLFetch(SQLHSTMT hstmt)
+ {
++	SQLRETURN ret;
++	SQLULEN  save_sql_desc_array_size;
++	SQLULEN *save_sql_desc_rows_processed_ptr;
++	SQLUSMALLINT *save_sql_desc_array_status_ptr;
++
+ 	INIT_HSTMT;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLFetch(%p)\n", hstmt);
+ 
+-	ODBC_RETURN(stmt, _SQLFetch(stmt, SQL_FETCH_NEXT, 0));
++	if (stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3) {
++		save_sql_desc_array_size = stmt->ard->header.sql_desc_array_size;
++		stmt->ard->header.sql_desc_array_size = 1;
++		save_sql_desc_rows_processed_ptr = stmt->ird->header.sql_desc_rows_processed_ptr;
++		stmt->ird->header.sql_desc_rows_processed_ptr = NULL;
++		save_sql_desc_array_status_ptr = stmt->ird->header.sql_desc_array_status_ptr;
++		stmt->ird->header.sql_desc_array_status_ptr = NULL;
++	}
++
++	ret = _SQLFetch(stmt, SQL_FETCH_NEXT, 0);
++
++	if (stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3) {
++		stmt->ard->header.sql_desc_array_size = save_sql_desc_array_size;
++		stmt->ird->header.sql_desc_rows_processed_ptr = save_sql_desc_rows_processed_ptr;
++		stmt->ird->header.sql_desc_array_status_ptr = save_sql_desc_array_status_ptr;
++	}
++
++	ODBC_RETURN(stmt, ret);
+ }
+ 
+ #if (ODBCVER >= 0x0300)
+
+commit 43f35180ab1d3236db67df43792eeb4674bd83cf
+Author: jklowden <jklowden>
+Date:   Thu Jun 12 00:00:25 2008 +0000
+
+    added PHP message
+
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index d225215..3c3ece5 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.16 2008/05/08 02:44:12 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.17 2008/06/12 00:00:25 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -33,6 +33,30 @@ News&nbsp;&nbsp;|&nbsp;
+ <table summary="layout" width="80%" align="center">
+ 
+ <!--  item  -->
++<tr bgcolor="#c9c9ff"><td>PHP msdblib niggle encountered</td></tr>
++<tr>
++<td>
++<br />
++In configuring your new version of PHP to work with FreeTDS 0.82, 
++you may encounter:
++<blockquote>  
++	<tt>configure: error: Directory /usr/local/freetds-0.82 is not a FreeTDS installation directory</tt>
++</blockquote>  
++PHP tests for a FreeTDS installation by looking for files 
++that FreeTDS no longer installs.  To assure PHP that FreeTDS is installed, 
++create two files where FreeTDS was installed e.g.:
++<blockquote><pre>$ <b>touch /usr/local/freetds-0.82/include/tds.h</b>
++$ <b>touch /usr/local/freetds-0.82/lib/libtds.a</b></pre>
++</blockquote>  
++The file that needs to be changed is used by autoconf when the distribution 
++tarball is constructed.  Cf. revision 1.13 of <a href="http://cvs.php.net/viewvc.cgi/php-src/ext/mssql/config.m4?revision=1.13&amp;view=markup">PHP source file <tt>config.m4</tt></a>.
++(12 June 2008)
++<br />
++<br />
++</td>
++</tr>
++
++<!--  item  -->
+ <tr bgcolor="#c9c9ff"><td>Version 0.82 Released</td></tr>
+ <tr>
+ <td>
+
+commit 0fc63140232c0ff2fa6a932fb2bd90b0dcf4ba9d
+Author: jklowden <jklowden>
+Date:   Thu Jun 12 01:00:48 2008 +0000
+
+    small improvements to style, logging, and error messages
+
+diff --git a/ChangeLog b/ChangeLog
+index 49e1eb2..bfe1a42 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sat Jun  7 17:52:24 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c src/dblib/rpc.c src/dblib/unittests/rpc.c
++	* src/tds/convert.c
++	- small improvements to style, logging, and error messages
++
+ Thu Jun 05 18:21:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c:
+ 	- fix cursor6 test
+@@ -33,7 +38,7 @@ Tue May 27 10:00:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h: fix possible buffer overflow
+ 
+ Mon May 26 15:56:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+-	(monstly from Coverity reports)
++	(mostly from Coverity reports)
+ 	* include/tdsbytes.h: remove warning
+ 	* src/apps/tsql.c src/dblib/bcp.c src/dblib/dblib.c:
+ 	- remove some leaks
+@@ -333,4 +338,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2532 2008/06/05 16:21:50 freddy77 Exp $
++$Id: ChangeLog,v 1.2533 2008/06/12 01:00:48 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 0d40af7..96d7de4 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.324 2008/05/26 13:56:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.325 2008/06/12 01:00:48 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1258,7 +1258,7 @@ dbcmd(DBPROCESS * dbproc, const char *cmdstring)
+ 	if (dbproc->dbbufsz == 0) {
+ 		dbproc->dbbuf = malloc(strlen(cmdstring) + 1);
+ 		if (dbproc->dbbuf == NULL) {
+-			dbperror(NULL, SYBEMEM, errno);
++			dbperror(dbproc, SYBEMEM, errno);
+ 			return FAIL;
+ 		}
+ 		strcpy((char *) dbproc->dbbuf, cmdstring);
+@@ -1266,7 +1266,7 @@ dbcmd(DBPROCESS * dbproc, const char *cmdstring)
+ 	} else {
+ 		newsz = strlen(cmdstring) + dbproc->dbbufsz;
+ 		if ((p = realloc(dbproc->dbbuf, newsz)) == NULL) {
+-			dbperror(NULL, SYBEMEM, errno);
++			dbperror(dbproc, SYBEMEM, errno);
+ 			return FAIL;
+ 		}
+ 		dbproc->dbbuf = (unsigned char *) p;
+@@ -1335,7 +1335,7 @@ dbuse(DBPROCESS * dbproc, const char *name)
+ 	/* quote name */
+ 	query = malloc(tds_quote_id(dbproc->tds_socket, NULL, name, -1) + 6);
+ 	if (!query) {
+-		dbperror(NULL, SYBEMEM, errno);
++		dbperror(dbproc, SYBEMEM, errno);
+ 		return FAIL;
+ 	}
+ 	strcpy(query, "use ");
+@@ -2715,7 +2715,7 @@ dbclrbuf(DBPROCESS * dbproc, DBINT n)
+ DBBOOL
+ dbwillconvert(int srctype, int desttype)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "dbwillconvert(%d, %d)\n", srctype, desttype);
++	tdsdump_log(TDS_DBG_FUNC, "dbwillconvert(%s, %s)\n", tds_prdatatype(srctype), tds_prdatatype(desttype));
+ 	return tds_willconvert(srctype, desttype);
+ }
+ 
+@@ -3270,7 +3270,7 @@ dbprrow(DBPROCESS * dbproc)
+ 
+ 			if (col_printlens == NULL) {
+ 				if ((col_printlens = calloc(resinfo->num_cols, sizeof(TDS_SMALLINT))) == NULL) {
+-					dbperror(NULL, SYBEMEM, errno);
++					dbperror(dbproc, SYBEMEM, errno);
+ 					return FAIL;
+ 				}
+ 			}
+@@ -4718,7 +4718,7 @@ dbbylist(DBPROCESS * dbproc, int computeid, int *size)
+ 		unsigned int n;
+ 		TDS_TINYINT *p = malloc(sizeof(info->bycolumns[0]) + info->by_cols);
+ 		if (!p) {
+-			dbperror(NULL, SYBEMEM, errno);
++			dbperror(dbproc, SYBEMEM, errno);
+ 			return NULL;
+ 		}
+ 		for (n = 0; n < info->by_cols; ++n)
+diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c
+index 525c934..4b26de4 100644
+--- a/src/dblib/rpc.c
++++ b/src/dblib/rpc.c
+@@ -54,7 +54,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: rpc.c,v 1.64 2007/12/06 18:32:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: rpc.c,v 1.65 2008/06/12 01:00:48 jklowden Exp $");
+ 
+ static void rpc_clear(DBREMOTE_PROC * rpc);
+ static void param_clear(DBREMOTE_PROC_PARAM * pparam);
+@@ -86,6 +86,11 @@ dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options)
+ 	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+ 	CHECK_NULP(rpcname, "dbrpcinit", 2, FAIL);
+ 
++	/*
++	 * TODO: adhere to docs.  Only Microsoft supports DBRPCRESET.  They say:
++	 * "Cancels a single stored procedure or a batch of stored procedures. 
++	 *  If rpcname is specified, that new stored procedure is initialized after the cancellation is complete."
++	 */
+ 	if (options & DBRPCRESET) {
+ 		rpc_clear(dbproc->rpc);
+ 		dbproc->rpc = NULL;
+@@ -99,27 +104,27 @@ dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options)
+ 	/* all other options except DBRPCRECOMPILE are invalid */
+ 	DBPERROR_RETURN3(options, SYBEIPV, (int) options, "options", "dbrpcinit");
+ 
+-	/* to allocate, first find a free node */
++	/* find a free node */
+ 	for (rpc = &dbproc->rpc; *rpc != NULL; rpc = &(*rpc)->next) {
+ 		/* check existing nodes for name match (there shouldn't be one) */
+-		if (!(*rpc)->name)
+-			return FAIL;
+-		if (strcmp((*rpc)->name, rpcname) == 0)
+-			return FAIL /* dbrpcsend should free pointer */ ;
++		if ((*rpc)->name == NULL  || strcmp((*rpc)->name, rpcname) == 0) {
++			tdsdump_log(TDS_DBG_INFO1, "error: dbrpcinit called twice for procedure \"%s\"\n", rpcname);
++			return FAIL; 
++		}
+ 	}
+ 
+ 	/* rpc now contains the address of the dbproc's first empty (null) DBREMOTE_PROC* */
+ 
+ 	/* allocate */
+-	*rpc = (DBREMOTE_PROC *) malloc(sizeof(DBREMOTE_PROC));
+-	if (*rpc == NULL)
++	if ((*rpc = (DBREMOTE_PROC *) calloc(1, sizeof(DBREMOTE_PROC))) == NULL) {
++		dbperror(dbproc, SYBEMEM, errno);
+ 		return FAIL;
+-	memset(*rpc, 0, sizeof(DBREMOTE_PROC));
++	}
+ 
+-	(*rpc)->name = strdup(rpcname);
+-	if ((*rpc)->name == NULL) {
++	if (((*rpc)->name = strdup(rpcname)) == NULL) {
+ 		free(*rpc);
+ 		*rpc = NULL;
++		dbperror(dbproc, SYBEMEM, errno);
+ 		return FAIL;
+ 	}
+ 
+@@ -143,7 +148,8 @@ dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options)
+  *        If not used, parameters will be passed in order instead of by name. 
+  * \param status must be DBRPCRETURN, if this parameter is a return parameter, else 0. 
+  * \param type datatype of the value parameter e.g., SYBINT4, SYBCHAR.
+- * \param maxlen Maximum output size of the parameter's value to be returned by the stored procedure, usually the size of your host variable. 
++ * \param maxlen Maximum output size of the parameter's value to be returned by the stored procedure, 
++ *  	  usually the size of your host variable. 
+  *        Fixed-length datatypes take -1 (NULL or not).  
+  *        Non-OUTPUT parameters also use -1.  
+  *	   Use 0 to send a NULL value for a variable length datatype.  
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index e9e8bb4..82deff0 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.32 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.33 2008/06/12 01:00:48 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[4096];
+@@ -27,6 +27,7 @@ static const char procedure_sql[] =
+ 			", @nullout int OUTPUT\n"
+ 			", @nrows int OUTPUT \n"
+ 			", @c varchar(20)\n"
++			", @nv nvarchar(20) = N'hello'\n"
+ 		"AS \n"
+ 		"BEGIN \n"
+ 			"select @null_input = max(convert(varchar(30), name)) from systypes \n"
+@@ -35,7 +36,7 @@ static const char procedure_sql[] =
+ 			"select distinct convert(varchar(30), name) as 'type'  from systypes \n"
+ 				"where name in ('int', 'char', 'text') \n"
+ 			"select @nrows = @@rowcount \n"
+-			"select distinct convert(varchar(30), name) as name  from sysobjects where type = 'S' \n"
++			"select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' \n"
+ 			"return 42 \n"
+ 		"END \n";
+ 
+@@ -123,6 +124,13 @@ ignore_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char
+ 	return erc;
+ }
+ 
++int 
++colwidth( DBPROCESS * dbproc, int icol ) 
++{
++	int width = dbwillconvert(dbcoltype(dbproc, icol), SYBCHAR);
++	return 255 == width? dbcollen(dbproc, icol) : width;
++}
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -130,29 +138,28 @@ main(int argc, char **argv)
+ 	DBPROCESS *dbproc;
+ 	RETPARAM save_param;
+ 	
+-	int i, r;
+ 	char teststr[1024];
+-	int failed = 0;
+ 	char *retname = NULL;
+-	int rettype = 0, retlen = 0;
+-	int return_status = 0;
++	int i, failed = 0;
++	int rettype = 0, retlen = 0, return_status = 0;
+ 	char proc[] = "#t0022", 
+ 	     param0[] = "@null_input", 
+ 	     param1[] = "@first_type", 
+ 	     param2[] = "@nullout",
+ 	     param3[] = "@nrows",
+-	     param4[] = "@c";
++	     param4[] = "@c",
++	     param5[] = "@nv";
+ 	char *proc_name = proc;
+ 
+ 	char param_data1[64];
+-	int param_data2;
+-	int param_data3;
++	int param_data2, param_data3;
++	int num_resultset = 0, num_empty_resultset = 0;
++
++	static const char dashes30[] = "------------------------------";
++	static const char  *dashes5 = dashes30 + (sizeof(dashes30) - 5), 
++			  *dashes15 = dashes30 + (sizeof(dashes30) - 15);
++
+ 	RETCODE erc, row_code;
+-	int num_resultset = 0;
+-	int num_empty_resultset = 0;
+-	static const char dashes5[]  = "-----", 
+-			  dashes15[] = "---------------", 
+-			  dashes30[] = "------------------------------";
+ 
+ 	set_malloc_options();
+ 	
+@@ -212,35 +219,35 @@ main(int argc, char **argv)
+ 	printf("executing dbrpcinit\n");
+ 	erc = dbrpcinit(dbproc, proc_name, 0);	/* no options */
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcinit\n");
++		fprintf(stderr, "Failed line %d: dbrpcinit\n", __LINE__);
+ 		failed = 1;
+ 	}
+ 
+ 	printf("executing dbrpcparam\n");
+ 	erc = dbrpcparam(dbproc, param0, DBRPCRETURN, SYBCHAR, /*maxlen= */ -1, /* datlen= */ 0, NULL);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcparam\n");
++		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+ 		failed = 1;
+ 	}
+ 
+ 	printf("executing dbrpcparam\n");
+ 	erc = dbrpcparam(dbproc, param1, DBRPCRETURN, SYBCHAR, /*maxlen= */ sizeof(param_data1), /* datlen= */ 0, (BYTE *) & param_data1);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcparam\n");
++		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+ 		failed = 1;
+ 	}
+ 
+ 	printf("executing dbrpcparam\n");
+ 	erc = dbrpcparam(dbproc, param2, DBRPCRETURN, SYBINT4, /*maxlen= */ -1, /* datalen= */ 0, (BYTE *) & param_data2);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcparam\n");
++		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+ 		failed = 1;
+ 	}
+ 
+ 	printf("executing dbrpcparam\n");
+ 	erc = dbrpcparam(dbproc, param3, DBRPCRETURN, SYBINT4, /*maxlen= */ -1, /* datalen= */ -1, (BYTE *) & param_data3);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcparam\n");
++		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+ 		failed = 1;
+ 	}
+ 
+@@ -248,7 +255,14 @@ main(int argc, char **argv)
+ 	printf("executing dbrpcparam\n");
+ 	erc = dbrpcparam(dbproc, param4, 0, SYBVARCHAR, /*maxlen= */ 0, /* datalen= */ 0, NULL);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcparam\n");
++		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
++		failed = 1;
++	}
++
++	printf("executing dbrpcparam\n");
++	erc = dbrpcparam(dbproc, param5, 0, SYBVARCHAR, /*maxlen= */ -1, /* datalen= */ 2, &"OK:");
++	if (erc == FAIL) {
++		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+ 		failed = 1;
+ 	}
+ 
+@@ -256,7 +270,7 @@ main(int argc, char **argv)
+ 	param_data3 = 0x11223344;
+ 	erc = dbrpcsend(dbproc);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbrpcsend\n");
++		fprintf(stderr, "Failed line %d: dbrpcsend\n", __LINE__);
+ 		exit(1);
+ 	}
+ 
+@@ -264,27 +278,47 @@ main(int argc, char **argv)
+ 	printf("executing dbsqlok\n");
+ 	erc = dbsqlok(dbproc);
+ 	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbsqlok\n");
++		fprintf(stderr, "Failed line %d: dbsqlok\n", __LINE__);
+ 		exit(1);
+ 	}
+ 
+ 	add_bread_crumb();
+ 
+ 	/* retrieve outputs per usual */
+-	r = 0;
++	printf("fetching results\n");
+ 	while ((erc = dbresults(dbproc)) != NO_MORE_RESULTS) {
++		printf("fetched resultset %d %s:\n", 1+num_resultset, erc==SUCCEED? "successfully":"unsuccessfully");
+ 		if (erc == SUCCEED) { 
+-			const int ncols = dbnumcols(dbproc);
+-			int empty_resultset = 1;
++			const int ncol = dbnumcols(dbproc);
++			int empty_resultset = 1, c;
++			enum {buflen=1024, nbuf=5};
++			char bound_buffers[nbuf][buflen] = { "one", "two", "three", "four", "five" };
++
+ 			++num_resultset;
+-			printf("bound 1 of %d columns ('%s') in result %d.\n", ncols, dbcolname(dbproc, 1), ++r);
+-			dbbind(dbproc, 1, STRINGBIND, 0, (BYTE *) teststr);
+ 			
+-			printf("\t%s\n\t-----------\n", dbcolname(dbproc, 1));
++			for( c=0; c < ncol && c < nbuf; c++ ) {
++				printf("column %d (%s) is %d wide, ", c+1, dbcolname(dbproc, c+1), colwidth(dbproc, c+1));
++				printf("buffer initialized to '%s'\n", bound_buffers[c]);
++			}
++			for( c=0; c < ncol && c < nbuf; c++ ) {
++				erc = dbbind(dbproc, c+1, STRINGBIND, 0, (BYTE *) bound_buffers[c]);
++				if (erc == FAIL) {
++					fprintf(stderr, "Failed line %d: dbbind\n", __LINE__);
++					exit(1);
++				}
++
++				printf("%-*s ", colwidth(dbproc, c+1), dbcolname(dbproc, c+1));
++			}
++			printf("\n");
++
+ 			while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {
+ 				empty_resultset = 0;
+ 				if (row_code == REG_ROW) {
+-					printf("\t%s\n", teststr);
++					int c;
++					for( c=0; c < ncol && c < nbuf; c++ ) {
++						printf("%-*s ", colwidth(dbproc, c+1), bound_buffers[c]);
++					}
++					printf("\n");
+ 				} else {
+ 					/* not supporting computed rows in this unit test */
+ 					failed = 1;
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 6c6b985..606f3fc 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.182 2008/02/20 08:04:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.183 2008/06/12 01:00:48 jklowden Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -2842,12 +2842,12 @@ tds_willconvert(int srctype, int desttype)
+ 	unsigned int i;
+ 	const ANSWER *p = NULL;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_willconvert()\n");
++	tdsdump_log(TDS_DBG_FUNC, "tds_willconvert(%d, %d)\n", srctype, desttype);
+ 
+ 	for (i = 0; i < sizeof(answers) / sizeof(ANSWER); i++) {
+ 		if (srctype == answers[i].srctype && desttype == answers[i].desttype) {
+-			tdsdump_log(TDS_DBG_FUNC, "tds_willconvert() %d %d %d\n", answers[i].srctype, answers[i].desttype,
+-				    answers[i].yn);
++			tdsdump_log(TDS_DBG_FUNC, "tds_willconvert(%d, %d) returns %s\n", answers[i].srctype, answers[i].desttype,
++				    answers[i].yn? "yes":"no");
+ 			p =  &answers[i];
+ 			break;
+ 		}
+
+commit 019f357fbd2df0594ad5c4fc70b5a66d2cfc4652
+Author: jklowden <jklowden>
+Date:   Thu Jun 12 03:10:16 2008 +0000
+
+    Applied patch from Suren A. Chilingaryan cf.  ML on 10 June 2008
+
+diff --git a/ChangeLog b/ChangeLog
+index bfe1a42..7f6c7bb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Jun 11 23:07:29 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/odbc/odbc.c src/odbc/unittests/getdata.c
++	- Applied patch from Suren A. Chilingaryan cf. 
++	- ML on 10 June 2008
++	
+ Sat Jun  7 17:52:24 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c src/dblib/rpc.c src/dblib/unittests/rpc.c
+ 	* src/tds/convert.c
+@@ -338,4 +343,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2533 2008/06/12 01:00:48 jklowden Exp $
++$Id: ChangeLog,v 1.2534 2008/06/12 03:10:16 jklowden Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a69da4f..07ab1ff 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.481 2008/06/05 16:21:54 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.482 2008/06/12 03:10:16 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3707,29 +3707,32 @@ SQLRETURN ODBC_API
+ SQLFetch(SQLHSTMT hstmt)
+ {
+ 	SQLRETURN ret;
+-	SQLULEN  save_sql_desc_array_size;
+-	SQLULEN *save_sql_desc_rows_processed_ptr;
+-	SQLUSMALLINT *save_sql_desc_array_status_ptr;
+-
++	struct {
++		SQLULEN  array_size;
++		SQLULEN *rows_processed_ptr;
++		SQLUSMALLINT *array_status_ptr;
++	} keep;
++	
+ 	INIT_HSTMT;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLFetch(%p)\n", hstmt);
+ 
++	keep.array_size = stmt->ard->header.sql_desc_array_size;
++	keep.rows_processed_ptr = stmt->ird->header.sql_desc_rows_processed_ptr;
++	keep.array_status_ptr = stmt->ird->header.sql_desc_array_status_ptr;
++	
+ 	if (stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3) {
+-		save_sql_desc_array_size = stmt->ard->header.sql_desc_array_size;
+ 		stmt->ard->header.sql_desc_array_size = 1;
+-		save_sql_desc_rows_processed_ptr = stmt->ird->header.sql_desc_rows_processed_ptr;
+ 		stmt->ird->header.sql_desc_rows_processed_ptr = NULL;
+-		save_sql_desc_array_status_ptr = stmt->ird->header.sql_desc_array_status_ptr;
+ 		stmt->ird->header.sql_desc_array_status_ptr = NULL;
+ 	}
+ 
+ 	ret = _SQLFetch(stmt, SQL_FETCH_NEXT, 0);
+ 
+ 	if (stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3) {
+-		stmt->ard->header.sql_desc_array_size = save_sql_desc_array_size;
+-		stmt->ird->header.sql_desc_rows_processed_ptr = save_sql_desc_rows_processed_ptr;
+-		stmt->ird->header.sql_desc_array_status_ptr = save_sql_desc_array_status_ptr;
++		stmt->ard->header.sql_desc_array_size = keep.array_size;
++		stmt->ird->header.sql_desc_rows_processed_ptr = keep.rows_processed_ptr;
++		stmt->ird->header.sql_desc_array_status_ptr = keep.array_status_ptr;
+ 	}
+ 
+ 	ODBC_RETURN(stmt, ret);
+@@ -4636,7 +4639,6 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ {
+ 	/* TODO cursors fetch row if needed ?? */
+ 	TDSCOLUMN *colinfo;
+-	TDSRESULTINFO *resinfo;
+ 	TDSSOCKET *tds;
+ 	TDS_CHAR *src;
+ 	int srclen;
+@@ -4644,6 +4646,8 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	SQLLEN dummy_cb;
+ 	int nSybType;
+ 
++	int extra_bytes = 0;
++
+ 	INIT_HSTMT;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n", 
+@@ -4684,42 +4688,140 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	if (colinfo->column_cur_size < 0) {
+ 		*pcbValue = SQL_NULL_DATA;
+ 	} else {
++		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++		if (fCType == SQL_C_DEFAULT)
++			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++		if (fCType == SQL_ARD_TYPE) {
++			if (icol > stmt->ard->header.sql_desc_count) {
++				odbc_errs_add(&stmt->errs, "07009", NULL);
++				ODBC_RETURN(stmt, SQL_ERROR);
++			}
++			fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++		}
++		assert(fCType);
++
+ 		src = (TDS_CHAR *) colinfo->column_data;
+ 		if (is_variable_type(colinfo->column_type)) {
+-			if (colinfo->column_text_sqlgetdatapos > 0
+-			    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-				ODBC_RETURN(stmt, SQL_NO_DATA);
+-
++			int nread = 0;
++			
+ 			/* 2003-8-29 check for an old bug -- freddy77 */
+ 			assert(colinfo->column_text_sqlgetdatapos >= 0);
+ 			if (is_blob_type(colinfo->column_type))
+ 				src = ((TDSBLOB *) src)->textvalue;
+-			src += colinfo->column_text_sqlgetdatapos;
+-			srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++			if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
++				TDS_CHAR buf[3];
++				SQLLEN len;
++
++				switch (nSybType) {
++				case SYBLONGBINARY:
++				case SYBBINARY:
++				case SYBVARBINARY:
++				case SYBIMAGE:
++				case XSYBBINARY:
++				case XSYBVARBINARY:
++				case TDS_CONVERT_BINARY:
++					if (colinfo->column_text_sqlgetdatapos % 2) {
++						nread = (colinfo->column_text_sqlgetdatapos - 1) / 2;
++						if (nread >= colinfo->column_cur_size)
++							ODBC_RETURN(stmt, SQL_NO_DATA);
++						
++						if (cbValueMax > 2) {
++							len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
++							if (len < 2) {
++								if (len < 0) 
++									odbc_convert_err_set(&stmt->errs, len);
++								ODBC_RETURN(stmt, SQL_ERROR);
++							}
++							*(TDS_CHAR *) rgbValue = buf[1];
++							*((TDS_CHAR *) rgbValue + 1) = 0;
++						
++							rgbValue++;
++							cbValueMax--;
++						
++							extra_bytes = 1;
++							nread++;
++
++							if (nread >= colinfo->column_cur_size)
++								ODBC_RETURN_(stmt);
++						} else {
++							if (cbValueMax) 
++								*(TDS_CHAR *) rgbValue = 0;
++							odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
++							ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
++						}
++					} else {
++						nread = colinfo->column_text_sqlgetdatapos / 2;
++						if (nread >= colinfo->column_cur_size)
++							ODBC_RETURN(stmt, SQL_NO_DATA);
++					}
++					
++					src += nread;
++					srclen = colinfo->column_cur_size - nread;
++					break;
++				default:
++					if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++						ODBC_RETURN(stmt, SQL_NO_DATA);
++						
++					src += colinfo->column_text_sqlgetdatapos;
++					srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++
++				}
++			} else if (fCType == SQL_C_BINARY) {
++				switch (nSybType) {
++				case SYBCHAR:
++				case SYBVARCHAR:
++				case SYBTEXT:
++				case XSYBCHAR:
++				case XSYBVARCHAR:
++					nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
++						
++					while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0')) 
++						nread++;
++
++					nread += colinfo->column_text_sqlgetdatapos * 2;
++					
++					if (nread && nread >= colinfo->column_cur_size)
++						ODBC_RETURN(stmt, SQL_NO_DATA);
++
++					src += nread;
++					srclen = colinfo->column_cur_size - nread;
++					break;
++				default:
++					if (colinfo->column_text_sqlgetdatapos > 0
++					&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++						ODBC_RETURN(stmt, SQL_NO_DATA);
++						
++					src += colinfo->column_text_sqlgetdatapos;
++					srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++				}
++			} else {
++				if (colinfo->column_text_sqlgetdatapos > 0
++				&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++					ODBC_RETURN(stmt, SQL_NO_DATA);
++
++				src += colinfo->column_text_sqlgetdatapos;
++				srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
++			}
+ 		} else {
+ 			if (colinfo->column_text_sqlgetdatapos > 0
+-			    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++			&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+ 				ODBC_RETURN(stmt, SQL_NO_DATA);
+ 
+ 			srclen = colinfo->column_cur_size;
+ 		}
+-		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+-		if (fCType == SQL_C_DEFAULT)
+-			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+-		if (fCType == SQL_ARD_TYPE) {
+-			if (icol > stmt->ard->header.sql_desc_count) {
+-				odbc_errs_add(&stmt->errs, "07009", NULL);
+-				ODBC_RETURN(stmt, SQL_ERROR);
+-			}
+-			fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+-		}
+-		assert(fCType);
++
+ 		*pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ 		if (*pcbValue < 0) {
+ 			odbc_convert_err_set(&stmt->errs, *pcbValue);
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 		}
+-
++		
++		if (extra_bytes) {
++			colinfo->column_text_sqlgetdatapos += extra_bytes;
++			*pcbValue += extra_bytes;
++		}
++		
+ 		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+ 			/* calculate how many bytes were read */
+ 			int remaining = cbValueMax;
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 8520ca1..f772605 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.6 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.7 2008/06/12 03:10:16 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -11,7 +11,14 @@ ReadError(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
++	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT
++					, Statement
++					, 1
++					, (SQLCHAR *) odbc_sqlstate
++					, NULL
++					, (SQLCHAR *) odbc_err
++					, sizeof(odbc_err)
++					, NULL))) {
+ 		printf("SQLGetDiagRec should not fail\n");
+ 		exit(1);
+ 	}
+
+commit abcc570a7126ed6aecf0985e751e5b7c1b594fe6
+Author: jklowden <jklowden>
+Date:   Thu Jun 12 03:52:04 2008 +0000
+
+    (added)
+
+diff --git a/ChangeLog b/ChangeLog
+index 7f6c7bb..cde84f2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Jun 11 23:26:34 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/odbc/unittests/Makefile.am
++	* src/odbc/unittests/cursor7.c (added)
++	- test for fetching overlapping batches
++
+ Wed Jun 11 23:07:29 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/odbc/odbc.c src/odbc/unittests/getdata.c
+ 	- Applied patch from Suren A. Chilingaryan cf. 
+@@ -343,4 +348,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2534 2008/06/12 03:10:16 jklowden Exp $
++$Id: ChangeLog,v 1.2535 2008/06/12 03:52:04 jklowden Exp $
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index ad4ee0f..3496168 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.75 2008/06/05 16:12:19 freddy77 Exp $
++# $Id: Makefile.am,v 1.76 2008/06/12 03:52:05 jklowden Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -22,7 +22,7 @@ TESTS		=	\
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+ 			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT) \
+-			cursor6$(EXEEXT)
++			cursor6$(EXEEXT) cursor7$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -86,6 +86,7 @@ cancel_SOURCES = cancel.c common.c common.h
+ wchar_SOURCES = wchar.c common.c common.h
+ transaction2_SOURCES = transaction2.c common.c common.h
+ cursor6_SOURCES	= cursor6.c common.c common.h
++cursor7_SOURCES	= cursor7.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+new file mode 100644
+index 0000000..f36a464
+--- /dev/null
++++ b/src/odbc/unittests/cursor7.c
+@@ -0,0 +1,99 @@
++#include "common.h"
++
++/* Test SQLFetchScroll with no bound columns */
++
++static char software_version[] = "$Id: cursor7.c,v 1.1 2008/06/12 03:52:05 jklowden Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static void
++Test(void)
++{
++	enum { ROWS=5 };
++	struct data_t {
++		SQLINTEGER i;
++		SQLLEN ind_i;
++		char c[20];
++		SQLLEN ind_c;
++	} data[ROWS];
++	SQLUSMALLINT statuses[ROWS];
++	SQLULEN num_row;
++
++	int i;
++	SQLRETURN ErrCode;
++
++	ResetStatement();
++
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0));
++
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT c, i FROM #cursor7_test", SQL_NTS));
++	CHK(SQLExecute, (Statement));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, statuses, 0));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
++
++	CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c));
++	CHK(SQLBindCol, (Statement, 2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i));
++
++	/* Read records from last to first */
++	printf("\n\nReading records from last to first:\n");
++	ErrCode = SQLFetchScroll(Statement, SQL_FETCH_LAST, -ROWS);
++	while ((ErrCode == SQL_SUCCESS) || (ErrCode == SQL_SUCCESS_WITH_INFO)) {
++		/* Print this set of rows */
++		for (i = ROWS - 1; i >= 0; i--) {
++			if (statuses[i] != SQL_ROW_NOROW)
++				printf("\t %d, %s\n", (int) data[i].i, data[i].c);
++		}
++
++		/* Read next rowset */
++		ErrCode = SQLFetchScroll(Statement, SQL_FETCH_RELATIVE, -ROWS);
++	}
++	printf("\nRecords 5, 4 and 3 are returned twice!!\n\n");
++}
++
++static void
++Init(void)
++{
++	int i;
++	char sql[128];
++
++	printf("\n\nCreating table #cursor7_test with 12 records.\n");
++
++	Command(Statement, "\tCREATE TABLE #cursor7_test (i INT, c VARCHAR(20))");
++	for (i = 1; i <= 12; ++i) {
++		sprintf(sql, "\tINSERT INTO #cursor7_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
++		Command(Statement, sql);
++	}
++
++}
++
++int
++main(int argc, char *argv[])
++{
++	unsigned char sqlstate[6], msg[256];
++	SQLRETURN retcode;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
++	if (retcode != SQL_SUCCESS) {
++		CHK(SQLGetDiagRec, (SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL));
++		sqlstate[5] = 0;
++		if (strcmp((const char *) sqlstate, "S1092") == 0) {
++			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
++			Disconnect();
++			exit(0);
++		}
++		ODBC_REPORT_ERROR("SQLSetConnectAttr");
++	}
++
++	Init();
++
++	Test();
++
++	Disconnect();
++
++	return 0;
++}
+
+commit 6fea469567817619f6382b3988fff41af9ec3188
+Author: freddy77 <freddy77>
+Date:   Wed Jun 18 09:06:26 2008 +0000
+
+    applied patch for SQL_ATTR_ROW_NUMBER
+
+diff --git a/ChangeLog b/ChangeLog
+index cde84f2..c2d900f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Jun 18 11:05:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/odbc.c src/odbc/unittests/cursor7.c:
++	* src/tds/query.c:
++	- applied Daniel A. Veiga patch for SQL_ATTR_ROW_NUMBER
++	  (sligtly modified)
++
+ Wed Jun 11 23:26:34 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/odbc/unittests/Makefile.am
+ 	* src/odbc/unittests/cursor7.c (added)
+@@ -7,7 +13,7 @@ Wed Jun 11 23:07:29 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/odbc/odbc.c src/odbc/unittests/getdata.c
+ 	- Applied patch from Suren A. Chilingaryan cf. 
+ 	- ML on 10 June 2008
+-	
++
+ Sat Jun  7 17:52:24 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c src/dblib/rpc.c src/dblib/unittests/rpc.c
+ 	* src/tds/convert.c
+@@ -348,4 +354,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2535 2008/06/12 03:52:04 jklowden Exp $
++$Id: ChangeLog,v 1.2536 2008/06/18 09:06:26 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index ec2cecd..e2dae20 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.288 2008/05/27 22:24:49 jklowden Exp $ */
++/* $Id: tds.h,v 1.289 2008/06/18 09:06:26 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1484,6 +1484,7 @@ int tds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params
+ int tds_cursor_setrows(TDSSOCKET * tds, TDSCURSOR * cursor, int *send);
+ int tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *send);
+ int tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_type, TDS_INT i_row);
++int tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_number, TDS_UINT * row_count);
+ int tds_cursor_close(TDSSOCKET * tds, TDSCURSOR * cursor);
+ int tds_cursor_dealloc(TDSSOCKET * tds, TDSCURSOR * cursor);
+ int tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op, TDS_INT i_row, TDSPARAMINFO * params);
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 07ab1ff..92c1284 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.482 2008/06/12 03:10:16 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.483 2008/06/18 09:06:26 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4094,7 +4094,13 @@ _SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEG
+ 		src = &stmt->ard->header.sql_desc_bind_type;
+ 		break;
+ 	case SQL_ATTR_ROW_NUMBER:
+-		/* TODO update this value */
++		/* TODO do not get info every time, cache somewhere */
++		if (stmt->cursor && odbc_lock_statement(stmt)) {
++			TDS_UINT row_number, row_count;
++
++			tds_cursor_get_cursor_info(stmt->dbc->tds_socket, stmt->cursor, &row_number, &row_count);
++			stmt->attr.row_number = row_number;
++		}
+ 		size = sizeof(stmt->attr.row_number);
+ 		src = &stmt->attr.row_number;
+ 		break;
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index f36a464..e739a2b 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -1,8 +1,8 @@
+ #include "common.h"
+ 
+-/* Test SQLFetchScroll with no bound columns */
++/* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.1 2008/06/12 03:52:05 jklowden Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.2 2008/06/18 09:06:27 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -17,6 +17,7 @@ Test(void)
+ 	} data[ROWS];
+ 	SQLUSMALLINT statuses[ROWS];
+ 	SQLULEN num_row;
++	SQLULEN RowNumber;
+ 
+ 	int i;
+ 	SQLRETURN ErrCode;
+@@ -40,16 +41,26 @@ Test(void)
+ 	printf("\n\nReading records from last to first:\n");
+ 	ErrCode = SQLFetchScroll(Statement, SQL_FETCH_LAST, -ROWS);
+ 	while ((ErrCode == SQL_SUCCESS) || (ErrCode == SQL_SUCCESS_WITH_INFO)) {
++		SQLULEN RowNumber;
++
+ 		/* Print this set of rows */
+ 		for (i = ROWS - 1; i >= 0; i--) {
+ 			if (statuses[i] != SQL_ROW_NOROW)
+ 				printf("\t %d, %s\n", (int) data[i].i, data[i].c);
+ 		}
+ 
++		CHK(SQLGetStmtAttr, (Statement, SQL_ROW_NUMBER, (SQLPOINTER)(&RowNumber), sizeof(RowNumber), NULL));
++		printf("---> We are in record No: %u\n", (unsigned int) RowNumber);
++
+ 		/* Read next rowset */
+-		ErrCode = SQLFetchScroll(Statement, SQL_FETCH_RELATIVE, -ROWS);
++		if ( (RowNumber>1) && (RowNumber<ROWS) ) {
++			ErrCode=SQLFetchScroll(Statement, SQL_FETCH_RELATIVE, 1-RowNumber); 
++			for (i=RowNumber-1; i<ROWS; ++i)
++				statuses[i] = SQL_ROW_NOROW;
++		} else {
++			ErrCode=SQLFetchScroll(Statement, SQL_FETCH_RELATIVE, -ROWS);
++		}
+ 	}
+-	printf("\nRecords 5, 4 and 3 are returned twice!!\n\n");
+ }
+ 
+ static void
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 3cd8c5f..2686517 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.219 2008/02/13 08:52:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.220 2008/06/18 09:06:27 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -2419,6 +2419,119 @@ tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_typ
+ }
+ 
+ int
++tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_number, TDS_UINT * row_count)
++{
++	int done_flags;
++	int retcode;
++	TDS_INT result_type;
++
++	CHECK_TDS_EXTRA(tds);
++
++	if (!cursor)
++		return TDS_FAIL;
++
++	tdsdump_log(TDS_DBG_INFO1, "tds_cursor_get_cursor_info() cursor id = %d\n", cursor->cursor_id);
++
++	/* Assume not known */
++	*row_number = 0;
++	*row_count = 0;
++
++	if (IS_TDS7_PLUS(tds)) {
++		/* Change state to quering */
++		if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
++			return TDS_FAIL;
++
++		/* Remember the server has been sent a command for this cursor */
++		tds_set_cur_cursor(tds, cursor);
++
++		/* General initialization of server command */
++		tds->out_flag = TDS_RPC;
++		START_QUERY;
++
++		/* Create and send query to server */
++		if (IS_TDS8_PLUS(tds)) {
++			tds_put_smallint(tds, -1);
++			tds_put_smallint(tds, TDS_SP_CURSORFETCH);
++		} else {
++			tds_put_smallint(tds, 14);
++			TDS_PUT_N_AS_UCS2(tds, "sp_cursorfetch");
++		}
++
++		/* This flag tells the SP only to */
++		/* output a dummy metadata token  */
++
++		tds_put_smallint(tds, 2);
++
++		/* input cursor handle (int) */
++
++		tds_put_byte(tds, 0);	/* no parameter name */
++		tds_put_byte(tds, 0);	/* input parameter  */
++		tds_put_byte(tds, SYBINTN);
++		tds_put_byte(tds, 4);
++		tds_put_byte(tds, 4);
++		tds_put_int(tds, cursor->cursor_id);
++
++		tds_put_byte(tds, 0);	/* no parameter name */
++		tds_put_byte(tds, 0);	/* input parameter  */
++		tds_put_byte(tds, SYBINTN);
++		tds_put_byte(tds, 4);
++		tds_put_byte(tds, 4);
++		tds_put_int(tds, 0x100);	/* FETCH_INFO */
++
++		/* row number */
++		tds_put_byte(tds, 0);	/* no parameter name */
++		tds_put_byte(tds, 1);	/* output parameter  */
++		tds_put_byte(tds, SYBINTN);
++		tds_put_byte(tds, 4);
++		tds_put_byte(tds, 0);
++
++		/* number of rows fetched */
++		tds_put_byte(tds, 0);	/* no parameter name */
++		tds_put_byte(tds, 1);	/* output parameter  */
++		tds_put_byte(tds, SYBINTN);
++		tds_put_byte(tds, 4);
++		tds_put_byte(tds, 0);
++
++		/* Adjust current state */
++		tds->internal_sp_called = 0;
++		if ( (retcode=tds_query_flush_packet(tds)) != TDS_SUCCEED )
++			return retcode;
++
++		/* Process answer from server */
++		for (;;) {
++			retcode = tds_process_tokens(tds, &result_type, &done_flags, TDS_RETURN_PROC);
++			tdsdump_log(TDS_DBG_FUNC, "tds_cursor_get_cursor_info: tds_process_tokens returned %d\n", retcode);
++			tdsdump_log(TDS_DBG_FUNC, "    result_type=%d, TDS_DONE_COUNT=%x, TDS_DONE_ERROR=%x\n", result_type, (done_flags & TDS_DONE_COUNT), (done_flags & TDS_DONE_ERROR));
++			switch (retcode) {
++			case TDS_NO_MORE_RESULTS:
++				return TDS_SUCCEED;
++			case TDS_CANCELLED:
++			case TDS_FAIL:
++				return TDS_FAIL;
++
++			case TDS_SUCCEED:
++				if (result_type==TDS_PARAM_RESULT) {
++					/* Status is updated when TDS_STATUS_RESULT token arrives, before the params are processed */
++					if (tds->has_status && tds->ret_status==0) {
++						TDSPARAMINFO *pinfo = tds->current_results;
++
++						/* Make sure the params retuned have the correct tipe and size */
++						if (pinfo && pinfo->num_cols==2 && pinfo->columns[0]->column_type==SYBINTN && pinfo->columns[1]->column_type==SYBINTN && pinfo->columns[0]->column_size==4 && pinfo->columns[1]->column_size==4) {
++							/* Take the values */
++							*row_number = (TDS_UINT)(*(TDS_INT *) pinfo->columns[0]->column_data);
++							*row_count  = (TDS_UINT)(*(TDS_INT *) pinfo->columns[1]->column_data);
++							tdsdump_log(TDS_DBG_FUNC, "----------------> row_number=%u, row_count=%u\n", row_count, row_number);
++						}
++					}
++				}
++			}
++		}
++	}
++
++	return TDS_SUCCEED;
++}
++
++int
+ tds_cursor_close(TDSSOCKET * tds, TDSCURSOR * cursor)
+ {
+ 	CHECK_TDS_EXTRA(tds);
+
+commit 3ba728ad46586dd9db469f351cb79ed52ff9887a
+Author: freddy77 <freddy77>
+Date:   Wed Jun 25 11:54:35 2008 +0000
+
+    cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index c2d900f..bdea5ce 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jun 25 13:54:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor7.c: cleanup
++
+ Wed Jun 18 11:05:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/odbc.c src/odbc/unittests/cursor7.c:
+ 	* src/tds/query.c:
+@@ -354,4 +357,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2536 2008/06/18 09:06:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2537 2008/06/25 11:54:35 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index e739a2b..9d5c096 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.2 2008/06/18 09:06:27 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.3 2008/06/25 11:54:37 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -17,7 +17,6 @@ Test(void)
+ 	} data[ROWS];
+ 	SQLUSMALLINT statuses[ROWS];
+ 	SQLULEN num_row;
+-	SQLULEN RowNumber;
+ 
+ 	int i;
+ 	SQLRETURN ErrCode;
+@@ -48,6 +47,7 @@ Test(void)
+ 			if (statuses[i] != SQL_ROW_NOROW)
+ 				printf("\t %d, %s\n", (int) data[i].i, data[i].c);
+ 		}
++		printf("\n");
+ 
+ 		CHK(SQLGetStmtAttr, (Statement, SQL_ROW_NUMBER, (SQLPOINTER)(&RowNumber), sizeof(RowNumber), NULL));
+ 		printf("---> We are in record No: %u\n", (unsigned int) RowNumber);
+
+commit 0f270f21f5dcef6d7f406bc83f5f59d32a9400b8
+Author: freddy77 <freddy77>
+Date:   Wed Jun 25 11:58:45 2008 +0000
+
+    *** empty log message ***
+
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index c1a686e..6a3f662 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -62,6 +62,7 @@ cursor3
+ cursor4
+ cursor5
+ cursor6
++cursor7
+ attributes
+ hidden
+ blob1
+
+commit 2090aea9a7a7ca185817a5b04da7c822f3c6d464
+Author: jklowden <jklowden>
+Date:   Fri Jul 4 21:08:38 2008 +0000
+
+    src/odbc/prepare_query.c src/odbc/unittests/blob1.c Applied patch from ML Suren A. Chiling 3 July 2008
+
+diff --git a/ChangeLog b/ChangeLog
+index bdea5ce..eeed084 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Fri Jul  4 16:59:48 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/odbc/odbc.c
++	- src/odbc/prepare_query.c src/odbc/unittests/blob1.c
++	- Applied patch from ML Suren A. Chiling 3 July 2008
++	* src/tds/query.c fixed warning and formatting
++	* TODO added NetBSD note
++	* src/dblib/dblib.c NTBSTRINGBIND attempt
++
+ Tue Jun 25 13:54:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor7.c: cleanup
+ 
+@@ -357,4 +365,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2537 2008/06/25 11:54:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2538 2008/07/04 21:08:38 jklowden Exp $
+diff --git a/include/tds.h b/include/tds.h
+index e2dae20..e90a226 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.289 2008/06/18 09:06:26 freddy77 Exp $ */
++/* $Id: tds.h,v 1.290 2008/07/04 21:08:39 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1009,6 +1009,7 @@ typedef struct tds_column
+ 	TDS_INT *column_lenbind;
+ 	TDS_INT column_textpos;
+ 	TDS_INT column_text_sqlgetdatapos;
++	TDS_CHAR column_text_sqlputdatainfo;
+ 
+ 	BCPCOLDATA *bcp_column_data;
+ 	/**
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 92c1284..75645f2 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.483 2008/06/18 09:06:26 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.484 2008/07/04 21:08:39 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4652,6 +4652,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	SQLLEN dummy_cb;
+ 	int nSybType;
+ 
++	TDS_INT converted_column_cur_size;
+ 	int extra_bytes = 0;
+ 
+ 	INIT_HSTMT;
+@@ -4690,6 +4691,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 	colinfo = tds->current_results->columns[icol - 1];
++	converted_column_cur_size = colinfo->column_cur_size;
+ 
+ 	if (colinfo->column_cur_size < 0) {
+ 		*pcbValue = SQL_NULL_DATA;
+@@ -4715,7 +4717,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			if (is_blob_type(colinfo->column_type))
+ 				src = ((TDSBLOB *) src)->textvalue;
+ 
+-			if (fCType == SQL_C_CHAR && colinfo->column_text_sqlgetdatapos) {
++			if (fCType == SQL_C_CHAR) {
+ 				TDS_CHAR buf[3];
+ 				SQLLEN len;
+ 
+@@ -4758,40 +4760,15 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 						}
+ 					} else {
+ 						nread = colinfo->column_text_sqlgetdatapos / 2;
+-						if (nread >= colinfo->column_cur_size)
++						
++						if (colinfo->column_text_sqlgetdatapos > 0
++						    && nread >= colinfo->column_cur_size)
+ 							ODBC_RETURN(stmt, SQL_NO_DATA);
+ 					}
+ 					
+ 					src += nread;
+ 					srclen = colinfo->column_cur_size - nread;
+-					break;
+-				default:
+-					if (colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-						ODBC_RETURN(stmt, SQL_NO_DATA);
+-						
+-					src += colinfo->column_text_sqlgetdatapos;
+-					srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+-
+-				}
+-			} else if (fCType == SQL_C_BINARY) {
+-				switch (nSybType) {
+-				case SYBCHAR:
+-				case SYBVARCHAR:
+-				case SYBTEXT:
+-				case XSYBCHAR:
+-				case XSYBVARCHAR:
+-					nread = (src[0] == '0' && toupper(src[1]) == 'X')? 2 : 0;
+-						
+-					while ((nread < colinfo->column_cur_size) && (src[nread] == ' ' || src[nread] == '\0')) 
+-						nread++;
+-
+-					nread += colinfo->column_text_sqlgetdatapos * 2;
+-					
+-					if (nread && nread >= colinfo->column_cur_size)
+-						ODBC_RETURN(stmt, SQL_NO_DATA);
+-
+-					src += nread;
+-					srclen = colinfo->column_cur_size - nread;
++					converted_column_cur_size *= 2;
+ 					break;
+ 				default:
+ 					if (colinfo->column_text_sqlgetdatapos > 0
+@@ -4842,7 +4819,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ 				++colinfo->column_text_sqlgetdatapos;
+ 			
+-			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {	/* not all read ?? */
++			if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) {	/* not all read ?? */
+ 				odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ 				ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ 			}
+
+commit 5f16d9850166c0f9ac1b44067d4e1b7f6a55128d
+Author: jklowden <jklowden>
+Date:   Fri Jul 4 21:08:49 2008 +0000
+
+    fixed warning and formatting
+
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 2686517..0d54f27 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.220 2008/06/18 09:06:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.221 2008/07/04 21:08:49 jklowden Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -2419,10 +2419,9 @@ tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_typ
+ }
+ 
+ int
+-tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_number, TDS_UINT * row_count)
++tds_cursor_get_cursor_info(TDSSOCKET *tds, TDSCURSOR *cursor, TDS_UINT *prow_number, TDS_UINT *prow_count)
+ {
+-	int done_flags;
+-	int retcode;
++	int done_flags, retcode;
+ 	TDS_INT result_type;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+@@ -2433,11 +2432,12 @@ tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_n
+ 	tdsdump_log(TDS_DBG_INFO1, "tds_cursor_get_cursor_info() cursor id = %d\n", cursor->cursor_id);
+ 
+ 	/* Assume not known */
+-	*row_number = 0;
+-	*row_count = 0;
++	assert(prow_number && prow_count);
++	*prow_number = 0;
++	*prow_count = 0;
+ 
+ 	if (IS_TDS7_PLUS(tds)) {
+-		/* Change state to quering */
++		/* Change state to querying */
+ 		if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
+ 			return TDS_FAIL;
+ 
+@@ -2501,7 +2501,8 @@ tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_n
+ 		for (;;) {
+ 			retcode = tds_process_tokens(tds, &result_type, &done_flags, TDS_RETURN_PROC);
+ 			tdsdump_log(TDS_DBG_FUNC, "tds_cursor_get_cursor_info: tds_process_tokens returned %d\n", retcode);
+-			tdsdump_log(TDS_DBG_FUNC, "    result_type=%d, TDS_DONE_COUNT=%x, TDS_DONE_ERROR=%x\n", result_type, (done_flags & TDS_DONE_COUNT), (done_flags & TDS_DONE_ERROR));
++			tdsdump_log(TDS_DBG_FUNC, "    result_type=%d, TDS_DONE_COUNT=%x, TDS_DONE_ERROR=%x\n", 
++						  result_type, (done_flags & TDS_DONE_COUNT), (done_flags & TDS_DONE_ERROR));
+ 			switch (retcode) {
+ 			case TDS_NO_MORE_RESULTS:
+ 				return TDS_SUCCEED;
+@@ -2515,12 +2516,17 @@ tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_n
+ 					if (tds->has_status && tds->ret_status==0) {
+ 						TDSPARAMINFO *pinfo = tds->current_results;
+ 
+-						/* Make sure the params retuned have the correct tipe and size */
+-						if (pinfo && pinfo->num_cols==2 && pinfo->columns[0]->column_type==SYBINTN && pinfo->columns[1]->column_type==SYBINTN && pinfo->columns[0]->column_size==4 && pinfo->columns[1]->column_size==4) {
++						/* Make sure the params retuned have the correct type and size */
++						if (pinfo && pinfo->num_cols==2 
++							  && pinfo->columns[0]->column_type==SYBINTN 
++							  && pinfo->columns[1]->column_type==SYBINTN 
++							  && pinfo->columns[0]->column_size==4 
++							  && pinfo->columns[1]->column_size==4) {
+ 							/* Take the values */
+-							*row_number = (TDS_UINT)(*(TDS_INT *) pinfo->columns[0]->column_data);
+-							*row_count  = (TDS_UINT)(*(TDS_INT *) pinfo->columns[1]->column_data);
+-							tdsdump_log(TDS_DBG_FUNC, "----------------> row_number=%u, row_count=%u\n", row_count, row_number);
++							*prow_number = (TDS_UINT)(*(TDS_INT *) pinfo->columns[0]->column_data);
++							*prow_count  = (TDS_UINT)(*(TDS_INT *) pinfo->columns[1]->column_data);
++							tdsdump_log(TDS_DBG_FUNC, "----------------> prow_number=%u, prow_count=%u\n", 
++										  *prow_count, *prow_number);
+ 						}
+ 					}
+ 				}
+
+commit 982a35dbed80aa30b955912a04b42100f9544b7e
+Author: jklowden <jklowden>
+Date:   Fri Jul 4 21:08:57 2008 +0000
+
+    added NetBSD note
+
+diff --git a/TODO b/TODO
+index 5517ce6..92f7d8a 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.168 2008/05/22 01:32:30 jklowden Exp $
++To Do List	$Id: TODO,v 1.169 2008/07/04 21:08:57 jklowden Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -26,6 +26,8 @@ Must be fixed:
+          (actually a ct_cancel() error)" 
+ 
+ Broken:
++. HAVE_FUNC_GETSERVBYNAME_R_6 is defined by configure as 1 on 
++  NetBSD 2.0 even though it's not defined by the OS.  
+ . Passing invalid character set names to server with tsql?
+   tsql (and so libTDS) can pass invalid charset names to Sybase
+   libTDS assume Sybase can handle this charset but it's false
+
+commit ccffbfe2de595902ad798cd134ddf2360526326e
+Author: jklowden <jklowden>
+Date:   Fri Jul 4 21:09:12 2008 +0000
+
+    NTBSTRINGBIND attempt
+
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 96d7de4..76785be 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.325 2008/06/12 01:00:48 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.326 2008/07/04 21:09:12 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -606,6 +606,7 @@ dbgetnull(DBPROCESS *dbproc, int bindtype, int varlen, BYTE* varaddr)
+ 	/*
+ 	 * CHARBIND		Empty string (padded with blanks)
+ 	 * STRINGBIND		Empty string (padded with blanks, null-terminated)
++	 * NTBSTRINGBIND	Empty string (unpadded, null-terminated)
+ 	 * BINARYBIND		Empty array (padded with zeros)
+ 	 */
+ 	varaddr += pnullrep->len;
+@@ -619,6 +620,9 @@ dbgetnull(DBPROCESS *dbproc, int bindtype, int varlen, BYTE* varaddr)
+ 			memset(varaddr, ' ', varlen);
+ 			varaddr[varlen-1] = '\0';
+ 			break;
++		case NTBSTRINGBIND:
++			varaddr[0] = '\0';
++			break;
+ 		case BINARYBIND:
+ 			memset(varaddr, 0, varlen);
+ 			break;
+
+commit 6282100445643ff4fe5f6d300d0bf04b41b0e0ab
+Author: jklowden <jklowden>
+Date:   Sat Jul 5 22:57:53 2008 +0000
+
+    src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c src/ctlib/unittests/datafmt.c cs_convert sets output resultlen even when dest is too small.
+
+diff --git a/ChangeLog b/ChangeLog
+index eeed084..8b08bed 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Sat Jul  5 18:52:45 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/cspublic.h src/ctlib/cs.c src/ctlib/ct.c
++	- src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c
++	- src/ctlib/unittests/datafmt.c
++	- cs_convert sets output resultlen even when dest is too small. 
++	* src/odbc/prepare_query.c src/odbc/unittests/blob1.c
++	- make it compile....
++	
+ Fri Jul  4 16:59:48 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h src/odbc/odbc.c
+ 	- src/odbc/prepare_query.c src/odbc/unittests/blob1.c
+@@ -365,4 +373,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2538 2008/07/04 21:08:38 jklowden Exp $
++$Id: ChangeLog,v 1.2539 2008/07/05 22:57:53 jklowden Exp $
+diff --git a/include/cspublic.h b/include/cspublic.h
+index 954b24f..eb90d3d 100644
+--- a/include/cspublic.h
++++ b/include/cspublic.h
+@@ -34,7 +34,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.59 2008/06/02 14:18:44 jklowden Exp $";
++static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.60 2008/07/05 22:57:54 jklowden Exp $";
+ static const void *const no_unused_cspublic_h_warn[] = { rcsid_cspublic_h, no_unused_cspublic_h_warn };
+ 
+ #define CS_PUBLIC
+@@ -749,6 +749,8 @@ CS_RETCODE cs_strcmp(CS_CONTEXT * ctx, CS_LOCALE * locale, CS_INT type, CS_CHAR
+ CS_RETCODE cs_time(CS_CONTEXT * ctx, CS_LOCALE * locale, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen, CS_DATEREC * daterec);
+ CS_RETCODE cs_will_convert(CS_CONTEXT * ctx, CS_INT srctype, CS_INT desttype, CS_BOOL * result);
+ 
++const char * cs_prretcode(int retcode);
++
+ #ifdef __cplusplus
+ #if 0
+ {
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index 4cf70f8..036aab2 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -35,6 +35,7 @@
+ #endif
+ 
+ #include <stdio.h>
++#include <assert.h>
+ 
+ #if HAVE_STDLIB_H
+ #include <stdlib.h>
+@@ -49,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.65 2007/12/23 21:12:02 jklowden Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.66 2008/07/05 22:57:54 jklowden Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -57,6 +58,39 @@ static CS_INT cs_diag_clearmsg(CS_CONTEXT *context, CS_INT type);
+ static CS_INT cs_diag_getmsg(CS_CONTEXT *context, CS_INT idx, CS_CLIENTMSG *message);
+ static CS_INT cs_diag_countmsg(CS_CONTEXT *context, CS_INT *count);
+ 
++const char *
++cs_prretcode(int retcode)
++{
++	static char unknown[12]="oops: ";
++	
++	switch(retcode) {
++	case CS_SUCCEED:	return "CS_SUCCEED";
++	case CS_FAIL:		return "CS_FAIL";
++	case CS_MEM_ERROR:	return "CS_MEM_ERROR";
++	case CS_PENDING:	return "CS_PENDING";
++	case CS_QUIET:		return "CS_QUIET";
++	case CS_BUSY:		return "CS_BUSY";
++	case CS_INTERRUPT:	return "CS_INTERRUPT";
++	case CS_BLK_HAS_TEXT:	return "CS_BLK_HAS_TEXT";
++	case CS_CONTINUE:	return "CS_CONTINUE";
++	case CS_FATAL:		return "CS_FATAL";
++	case CS_RET_HAFAILOVER:	return "CS_RET_HAFAILOVER";
++	case CS_UNSUPPORTED:	return "CS_UNSUPPORTED";
++
++	case CS_CANCELED:	return "CS_CANCELED";
++	case CS_ROW_FAIL:	return "CS_ROW_FAIL";
++	case CS_END_DATA:	return "CS_END_DATA";
++	case CS_END_RESULTS:	return "CS_END_RESULTS";
++	case CS_END_ITEM:	return "CS_END_ITEM";
++	case CS_NOMSG:		return "CS_NOMSG";
++	case CS_TIMED_OUT:	return "CS_TIMED_OUT";
++
++	default:
++		sprintf(unknown + 6, "%u ??", retcode);
++	}
++	return unknown;
++}
++
+ /**
+  * returns the fixed length of the specified data type, or 0 if not a 
+  * fixed length data type
+@@ -452,22 +486,49 @@ CS_RETCODE
+ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT * destfmt, CS_VOID * destdata, CS_INT * resultlen)
+ {
+ 
+-int src_type, src_len, desttype, destlen, len, i = 0;
++	int src_type, src_len, desttype, destlen, len, i = 0;
++	CONV_RESULT cres;
++	unsigned char *dest;
++	CS_RETCODE ret;
++	CS_INT dummy;
+ 
+-CONV_RESULT cres;
++	tdsdump_log(TDS_DBG_FUNC, "cs_convert(%p, %p, %p, %p, %p, %p)\n", ctx, srcfmt, srcdata, destfmt, destdata, resultlen);
++
++	/* If destination is NULL we have a problem */
++	if (destdata == NULL) {
++		/* TODO: add error message */
++		tdsdump_log(TDS_DBG_FUNC, "error: destdata is null\n");
++		return CS_FAIL;
++
++	}
++
++	/* If destfmt is NULL we have a problem */
++	if (destfmt == NULL) {
++		/* TODO: add error message */
++		tdsdump_log(TDS_DBG_FUNC, "error: destfmt is null\n");
++		return CS_FAIL;
+ 
+-unsigned char *dest;
++	}
++	
++	if (resultlen == NULL) 
++		resultlen = &dummy;
+ 
+-CS_RETCODE ret;
++	/* If source is indicated to be NULL, set dest to low values */
++	if (srcdata == NULL) {
++		/* TODO: implement cs_setnull */
++		tdsdump_log(TDS_DBG_FUNC, "srcdata is null\n");
++		memset(destdata, '\0', destfmt->maxlength);
++		*resultlen = 0;
++		return CS_SUCCEED;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "cs_convert()\n");
++	}
+ 
+ 	src_type = _ct_get_server_type(srcfmt->datatype);
+-	src_len = srcfmt ? srcfmt->maxlength : 0;
++	src_len = srcfmt->maxlength;
+ 	desttype = _ct_get_server_type(destfmt->datatype);
+-	destlen = destfmt ? destfmt->maxlength : 0;
++	destlen = destfmt->maxlength;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "cs_convert() srctype = %d (%d) desttype = %d (%d)\n",
++	tdsdump_log(TDS_DBG_FUNC, "converting type %d (%d bytes) to type = %d (%d bytes)\n",
+ 		    src_type, src_len, desttype, destlen);
+ 
+ 	if (!is_fixed_type(desttype) && (destlen <= 0)) {
+@@ -476,51 +537,36 @@ CS_RETCODE ret;
+ 
+ 	dest = (unsigned char *) destdata;
+ 
+-	/* If source is indicated to be NULL, set dest to low values */
+-
+-	if (srcdata == NULL) {
+-
+-		tdsdump_log(TDS_DBG_FUNC, "cs_convert() srcdata is null\n");
+-		memset(dest, '\0', destlen);
+-		if (resultlen != NULL)
+-			*resultlen = 0;
+-		return CS_SUCCEED;
+-
+-	}
+-
+ 	/* many times we are asked to convert a data type to itself */
+ 
+ 	if (src_type == desttype) {
++		int minlen = src_len < destlen? src_len : destlen;
+ 
+-		tdsdump_log(TDS_DBG_FUNC, "cs_convert() srctype = desttype\n");
++		tdsdump_log(TDS_DBG_FUNC, "cs_convert() srctype == desttype\n");
+ 		switch (desttype) {
+ 
+ 		case SYBLONGBINARY:
+ 		case SYBBINARY:
+ 		case SYBVARBINARY:
+ 		case SYBIMAGE:
++			memcpy(dest, srcdata, src_len);
++			*resultlen = src_len;
++
+ 			if (src_len > destlen) {
++				tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n");
+ 				ret = CS_FAIL;
+ 			} else {
+ 				switch (destfmt->format) {
+ 				case CS_FMT_PADNULL:
+-					memcpy(dest, srcdata, src_len);
+-					for (i = src_len; i < destlen; i++)
+-						dest[i] = '\0';
+-					if (resultlen != NULL)
+-						*resultlen = destlen;
+-					ret = CS_SUCCEED;
+-					break;
++					memset(dest + src_len, '\0', destlen - src_len);
++					*resultlen = destlen;
++					/* fall through */
+ 				case CS_FMT_UNUSED:
+-					memcpy(dest, srcdata, src_len);
+-					if (resultlen != NULL)
+-						*resultlen = src_len;
+ 					ret = CS_SUCCEED;
+ 					break;
+ 				default:
+ 					ret = CS_FAIL;
+ 					break;
+-
+ 				}
+ 			}
+ 			break;
+@@ -529,45 +575,38 @@ CS_RETCODE ret;
+ 		case SYBVARCHAR:
+ 		case SYBTEXT:
+ 			tdsdump_log(TDS_DBG_FUNC, "cs_convert() desttype = character\n");
++
++			memcpy(dest, srcdata, minlen);
++			*resultlen = minlen;
++
+ 			if (src_len > destlen) {
+-				tdsdump_log(TDS_DBG_FUNC, "src_len > destlen\n");
++				tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n");
+ 				ret = CS_FAIL;
+ 			} else {
+ 				switch (destfmt->format) {
+-
+ 				case CS_FMT_NULLTERM:
+ 					if (src_len == destlen) {
+-						ret = CS_FAIL;	/* not enough room for data + a null terminator - error */
++						*resultlen = src_len;
++						tdsdump_log(TDS_DBG_FUNC, "error: no room for null terminator\n");
++						ret = CS_FAIL;
+ 					} else {
+-						memcpy(dest, srcdata, src_len);
+ 						dest[src_len] = '\0';
+-						if (resultlen != NULL)
+-							*resultlen = src_len + 1;
++						*resultlen = src_len + 1;
+ 						ret = CS_SUCCEED;
+ 					}
+ 					break;
+ 
+ 				case CS_FMT_PADBLANK:
+-					memcpy(dest, srcdata, src_len);
+-					for (i = src_len; i < destlen; i++)
+-						dest[i] = ' ';
+-					if (resultlen != NULL)
+-						*resultlen = destlen;
++					memset(dest + src_len, ' ', destlen - src_len);
++					*resultlen = destlen;
+ 					ret = CS_SUCCEED;
+ 					break;
+-
+ 				case CS_FMT_PADNULL:
+-					memcpy(dest, srcdata, src_len);
+-					for (i = src_len; i < destlen; i++)
+-						dest[i] = '\0';
+-					if (resultlen != NULL)
+-						*resultlen = destlen;
++					memset(dest + src_len, '\0', destlen - src_len);
++					*resultlen = destlen;
+ 					ret = CS_SUCCEED;
+ 					break;
+ 				case CS_FMT_UNUSED:
+-					memcpy(dest, srcdata, src_len);
+-					if (resultlen != NULL)
+-						*resultlen = src_len;
+ 					ret = CS_SUCCEED;
+ 					break;
+ 				default:
+@@ -588,9 +627,8 @@ CS_RETCODE ret;
+ 		case SYBMONEY4:
+ 		case SYBDATETIME:
+ 		case SYBDATETIME4:
+-			memcpy(dest, srcdata, _cs_datatype_length(src_type));
+-			if (resultlen != NULL)
+-				*resultlen = _cs_datatype_length(src_type);
++			*resultlen = _cs_datatype_length(src_type);
++			memcpy(dest, srcdata, *resultlen);
+ 			ret = CS_SUCCEED;
+ 			break;
+ 
+@@ -598,27 +636,30 @@ CS_RETCODE ret;
+ 		case SYBDECIMAL:
+ 			src_len = tds_numeric_bytes_per_prec[((TDS_NUMERIC *) srcdata)->precision] + 2;
+ 		case SYBBITN:
++			memcpy(dest, srcdata, minlen);
++			*resultlen = minlen;
++
+ 			if (src_len > destlen) {
++				tdsdump_log(TDS_DBG_FUNC, "error: src_len > destlen\n");
+ 				ret = CS_FAIL;
+ 			} else {
+-				memcpy(dest, srcdata, src_len);
+-				if (resultlen != NULL)
+-					*resultlen = src_len;
+ 				ret = CS_SUCCEED;
+ 			}
+ 			break;
+ 
+ 		default:
++			tdsdump_log(TDS_DBG_FUNC, "error: unrecognized type\n");
+ 			ret = CS_FAIL;
+ 			break;
+ 		}
+ 
++		tdsdump_log(TDS_DBG_FUNC, "cs_convert() returning  %s\n", cs_prretcode(ret));
+ 		return ret;
+ 
+ 	}
+ 
+-
+-	/* src type != dest type */
++	assert(src_type != desttype);
++	
+ 	/* set the output precision/scale for conversions to numeric type */
+ 	if (is_numeric_type(desttype)) {
+ 		cres.n.precision = destfmt->precision;
+@@ -675,8 +716,7 @@ CS_RETCODE ret;
+ 			free(cres.ib);
+ 			for (i = len; i < destlen; i++)
+ 				dest[i] = '\0';
+-			if (resultlen != NULL)
+-				*resultlen = destlen;
++			*resultlen = destlen;
+ 			ret = CS_SUCCEED;
+ 		}
+ 		break;
+@@ -685,72 +725,61 @@ CS_RETCODE ret;
+ 		/* fall trough, act same way of TINYINT */
+ 	case SYBINT1:
+ 		memcpy(dest, &(cres.ti), 1);
+-		if (resultlen != NULL)
+-			*resultlen = 1;
++		*resultlen = 1;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBINT2:
+ 		memcpy(dest, &(cres.si), 2);
+-		if (resultlen != NULL)
+-			*resultlen = 2;
++		*resultlen = 2;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBINT4:
+ 		memcpy(dest, &(cres.i), 4);
+-		if (resultlen != NULL)
+-			*resultlen = 4;
++		*resultlen = 4;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBINT8:
+ 		memcpy(dest, &(cres.bi), 8);
+-		if (resultlen != NULL)
+-			*resultlen = 8;
++		*resultlen = 8;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBFLT8:
+ 		memcpy(dest, &(cres.f), 8);
+-		if (resultlen != NULL)
+-			*resultlen = 8;
++		*resultlen = 8;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBREAL:
+ 		memcpy(dest, &(cres.r), 4);
+-		if (resultlen != NULL)
+-			*resultlen = 4;
++		*resultlen = 4;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBMONEY:
+ 
+ 		tdsdump_log(TDS_DBG_FUNC, "cs_convert() copying %d bytes to src\n", (int) sizeof(TDS_MONEY));
+ 		memcpy(dest, &(cres.m), sizeof(TDS_MONEY));
+-		if (resultlen != NULL)
+-			*resultlen = sizeof(TDS_MONEY);
++		*resultlen = sizeof(TDS_MONEY);
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBMONEY4:
+ 		memcpy(dest, &(cres.m4), sizeof(TDS_MONEY4));
+-		if (resultlen != NULL)
+-			*resultlen = sizeof(TDS_MONEY4);
++		*resultlen = sizeof(TDS_MONEY4);
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBDATETIME:
+ 		memcpy(dest, &(cres.dt), sizeof(TDS_DATETIME));
+-		if (resultlen != NULL)
+-			*resultlen = sizeof(TDS_DATETIME);
++		*resultlen = sizeof(TDS_DATETIME);
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBDATETIME4:
+ 		memcpy(dest, &(cres.dt4), sizeof(TDS_DATETIME4));
+-		if (resultlen != NULL)
+-			*resultlen = sizeof(TDS_DATETIME4);
++		*resultlen = sizeof(TDS_DATETIME4);
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBNUMERIC:
+ 	case SYBDECIMAL:
+ 		src_len = tds_numeric_bytes_per_prec[cres.n.precision] + 2;
+ 		memcpy(dest, &(cres.n), src_len);
+-		if (resultlen != NULL)
+-			*resultlen = src_len;
++		*resultlen = src_len;
+ 		ret = CS_SUCCEED;
+ 		break;
+ 	case SYBCHAR:
+@@ -770,8 +799,7 @@ CS_RETCODE ret;
+ 				} else {
+ 					memcpy(dest, cres.c, len);
+ 					dest[len] = 0;
+-					if (resultlen != NULL)
+-						*resultlen = len + 1;
++					*resultlen = len + 1;
+ 					ret = CS_SUCCEED;
+ 				}
+ 				break;
+@@ -782,8 +810,7 @@ CS_RETCODE ret;
+ 				memcpy(dest, cres.c, len);
+ 				for (i = len; i < destlen; i++)
+ 					dest[i] = ' ';
+-				if (resultlen != NULL)
+-					*resultlen = destlen;
++				*resultlen = destlen;
+ 				ret = CS_SUCCEED;
+ 				break;
+ 
+@@ -793,15 +820,13 @@ CS_RETCODE ret;
+ 				memcpy(dest, cres.c, len);
+ 				for (i = len; i < destlen; i++)
+ 					dest[i] = '\0';
+-				if (resultlen != NULL)
+-					*resultlen = destlen;
++				*resultlen = destlen;
+ 				ret = CS_SUCCEED;
+ 				break;
+ 			case CS_FMT_UNUSED:
+ 				tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_UNUSED\n");
+ 				memcpy(dest, cres.c, len);
+-				if (resultlen != NULL)
+-					*resultlen = len;
++				*resultlen = len;
+ 				ret = CS_SUCCEED;
+ 				break;
+ 			default:
+@@ -815,7 +840,7 @@ CS_RETCODE ret;
+ 		ret = CS_FAIL;
+ 		break;
+ 	}
+-	tdsdump_log(TDS_DBG_FUNC, "cs_convert() returning  %d\n", ret);
++	tdsdump_log(TDS_DBG_FUNC, "cs_convert() returning  %s\n", cs_prretcode(ret));
+ 	return (ret);
+ }
+ 
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 9dabd00..2362777 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.179 2008/05/22 01:32:32 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.180 2008/07/05 22:57:54 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -135,7 +135,8 @@ _ct_get_user_api_layer_error(int error)
+ {
+ 	switch (error) {
+ 	case 137:
+-		return "A bind count of %1! is not consistent with the count supplied for existing binds. The current bind count is %2!.";
++		return  "A bind count of %1! is not consistent with the count supplied for existing binds. "
++			"The current bind count is %2!.";
+ 		break;
+ 	case 138:
+ 		return "Use direction CS_BLK_IN or CS_BLK_OUT for a bulk copy operation.";
+@@ -1222,7 +1223,8 @@ ct_results(CS_COMMAND * cmd, CS_INT * result_type)
+ 					return CS_SUCCEED;
+ 				}
+ 
+-				tdsret = tds_process_tokens(tds, &res_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);
++				tdsret = tds_process_tokens(tds, &res_type, NULL,
++							 TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);
+ 
+ 				/* set results state to show that the result set has rows... */
+ 
+@@ -1445,8 +1447,10 @@ ct_bind(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buffer, C
+ 
+ 	colinfo = resinfo->columns[item - 1];
+ 
+-	/* check whether the request is for array binding and ensure that user */
+-	/* supplies the same datafmt->count to the subsequent ct_bind calls    */
++	/* 
++	 * Check whether the request is for array binding, and ensure that the user
++	 * supplies the same datafmt->count to the subsequent ct_bind calls    
++	 */
+ 
+ 	bind_count = (datafmt->count == 0) ? 1 : datafmt->count;
+ 
+@@ -1479,15 +1483,16 @@ ct_bind(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buffer, C
+ }
+ 
+ CS_RETCODE
+-ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * rows_read)
++ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * prows_read)
+ {
+ 	TDS_INT ret_type;
+ 	TDS_INT ret;
+ 	TDS_INT marker;
+ 	TDS_INT temp_count;
+ 	TDSSOCKET *tds;
++	CS_INT rows_read_dummy;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_fetch()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_fetch(%p, %d, %d, %d, %p)\n", cmd, type, offset, option, prows_read);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+@@ -1501,21 +1506,21 @@ ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * r
+ 		_ct_cancel_cleanup(cmd);
+ 		return CS_CANCELED;
+ 	}
++	
++	if( prows_read == NULL )
++		prows_read = &rows_read_dummy;
+ 
+ 	tds = cmd->con->tds_socket;
+ 
+-	/* We'll call a special function for fetches from a cursor            */
+-	/* the processing is too incompatible to patch into a single function */
+-
++	/* 
++	 * Call a special function for fetches from a cursor because 
++	 * the processing is too incompatible to patch into a single function 
++	 */
+ 	if (cmd->command_type == CS_CUR_CMD) {
+-		return _ct_fetch_cursor(cmd, type, offset, option, rows_read);
++		return _ct_fetch_cursor(cmd, type, offset, option, prows_read);
+ 	}
+ 
+-	if (rows_read)
+-		*rows_read = 0;
+-
+-	/* taking a copy of the cmd->bind_count value. */
+-	temp_count = cmd->bind_count;
++	*prows_read = 0;
+ 
+ 	if ( cmd->bind_count == CS_UNUSED )
+ 		cmd->bind_count = 1;
+@@ -1528,8 +1533,7 @@ ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * r
+ 		cmd->get_data_bytes_returned = 0;
+ 		if (_ct_bind_data(cmd->con->ctx, tds->current_results, tds->current_results, 0))
+ 			return CS_ROW_FAIL;
+-		if (rows_read)
+-			*rows_read = 1;
++		*prows_read = 1;
+ 		return CS_SUCCEED;
+ 	}
+ 
+@@ -1542,17 +1546,18 @@ ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * r
+ 
+ 
+ 	marker = tds_peek(tds);
+-	if ((cmd->curr_result_type == CS_ROW_RESULT && marker != TDS_ROW_TOKEN) ||
+-		(cmd->curr_result_type == CS_STATUS_RESULT && marker != TDS_RETURNSTATUS_TOKEN) )
++	if ((cmd->curr_result_type == CS_ROW_RESULT    && marker != TDS_ROW_TOKEN)
++	||  (cmd->curr_result_type == CS_STATUS_RESULT && marker != TDS_RETURNSTATUS_TOKEN) )
+ 		return CS_END_DATA;
+ 
+ 	/* Array Binding Code changes start here */
+ 
+ 	for (temp_count = 0; temp_count < cmd->bind_count; temp_count++) {
+ 
+-		ret = tds_process_tokens(tds, &ret_type, NULL, TDS_STOPAT_ROWFMT|TDS_STOPAT_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);
++		ret = tds_process_tokens(tds, &ret_type, NULL, 
++					 TDS_STOPAT_ROWFMT|TDS_STOPAT_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);
+ 
+-		tdsdump_log(TDS_DBG_FUNC, "inside ct_fetch()process_row_tokens returned %d\n", ret);
++		tdsdump_log(TDS_DBG_FUNC, "inside ct_fetch() process_row_tokens returned %d\n", ret);
+ 
+ 		switch (ret) {
+ 			case TDS_SUCCEED:
+@@ -1561,8 +1566,7 @@ ct_fetch(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * r
+ 					cmd->get_data_bytes_returned = 0;
+ 					if (_ct_bind_data(cmd->con->ctx, tds->current_results, tds->current_results, temp_count))
+ 						return CS_ROW_FAIL;
+-					if (rows_read)
+-						*rows_read = *rows_read + 1;
++					(*prows_read)++;
+ 					break;
+ 				}
+ 			case TDS_NO_MORE_RESULTS:
+@@ -1650,7 +1654,8 @@ _ct_fetch_cursor(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS
+ 			case CS_ROW_RESULT:
+ 				for (temp_count = 0; temp_count < cmd->bind_count; temp_count++) {
+ 
+-					ret = tds_process_tokens(tds, &restype, NULL, TDS_STOPAT_ROWFMT|TDS_STOPAT_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);
++					ret = tds_process_tokens(tds, &restype, NULL,
++							 TDS_STOPAT_ROWFMT|TDS_STOPAT_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE);
+ 
+ 					tdsdump_log(TDS_DBG_FUNC, "_ct_fetch_cursor() tds_process_tokens returned %d\n", ret);
+ 
+@@ -1658,7 +1663,8 @@ _ct_fetch_cursor(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS
+ 						cmd->get_data_item = 0;
+ 						cmd->get_data_bytes_returned = 0;
+ 						if (restype == TDS_ROW_RESULT) {
+-							if (_ct_bind_data(cmd->con->ctx, tds->current_results, tds->current_results, temp_count))
++							if (_ct_bind_data(cmd->con->ctx, tds->current_results,
++									  tds->current_results, temp_count))
+ 								return CS_ROW_FAIL;
+ 							if (rows_read)
+ 								*rows_read = *rows_read + 1;
+@@ -1696,10 +1702,10 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo,
+ 	unsigned char *src;
+ 	unsigned char *dest, *temp_add;
+ 	int result = 0;
+-	TDS_INT srctype, srclen, desttype, len;
++	TDS_INT srctype, srclen, desttype;
+ 	CS_DATAFMT srcfmt, destfmt;
+-	TDS_INT *datalen = NULL;
+-	TDS_SMALLINT *nullind = NULL;
++	TDS_INT datalen_dummy, *pdatalen = &datalen_dummy;
++	TDS_SMALLINT nullind_dummy, *nullind = &nullind_dummy;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_ct_bind_data()\n");
+ 
+@@ -1708,10 +1714,8 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo,
+ 		curcol = resinfo->columns[i];
+ 		bindcol = bindinfo->columns[i];
+ 
+-		tdsdump_log(TDS_DBG_FUNC, "_ct_bind_data(): column_type: %d column_len: %d\n",
+-			curcol->column_type,
+-			curcol->column_cur_size
+-		);
++		tdsdump_log(TDS_DBG_FUNC, "_ct_bind_data(): column %d is type %d and has length %d\n",
++						i, curcol->column_type, curcol->column_cur_size);
+ 
+ 		if (curcol->column_hidden)
+ 			continue;
+@@ -1720,28 +1724,28 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo,
+ 		srctype = curcol->column_type;
+ 		desttype = _ct_get_server_type(bindcol->column_bindtype);
+ 
+-		/* retrieve the initial bound column_varaddress */
+-		/* and increment it if offset specified         */
++		/* 
++		 * Retrieve the initial bound column_varaddress and increment it if offset specified         
++		 */
+ 
+ 		temp_add = (unsigned char *) bindcol->column_varaddr;
+ 		dest = temp_add + (offset * bindcol->column_bindlen);
+ 
+ 		if (bindcol->column_nullbind) {
+ 			nullind = bindcol->column_nullbind;
++			assert(nullind);
+ 			nullind += offset;
+ 		}
+ 		if (bindcol->column_lenbind) {
+-			datalen = bindcol->column_lenbind;
+-			datalen += offset;
++			pdatalen = bindcol->column_lenbind;
++			assert(pdatalen);
++			pdatalen += offset;
+ 		}
+ 
+ 		if (dest) {
+-
+ 			if (curcol->column_cur_size < 0) {
+-				if (nullind)
+-					*nullind = -1;
+-				if (datalen)
+-					*datalen = 0;
++				*nullind = -1;
++				*pdatalen = 0;
+ 			} else {
+ 
+ 				srctype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
+@@ -1759,22 +1763,17 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo,
+ 				destfmt.format = bindcol->column_bindfmt;
+ 
+ 				/* if convert return FAIL mark error but process other columns */
+-				if ((result= cs_convert(ctx, &srcfmt, (CS_VOID *) src, &destfmt, (CS_VOID *) dest, &len) != CS_SUCCEED)) {
++				if ((result= cs_convert(ctx, &srcfmt, src, &destfmt, dest, pdatalen) != CS_SUCCEED)) {
+ 					tdsdump_log(TDS_DBG_FUNC, "cs_convert-result = %d\n", result);
+ 					result = 1;
+-					len = 0;
+-					tdsdump_log(TDS_DBG_INFO1, "\n  convert failed for %d \n", srcfmt.datatype);
++					tdsdump_log(TDS_DBG_INFO1, "error: converted only %d bytes for type %d \n", 
++									*pdatalen, srcfmt.datatype);
+ 				}
+ 
+-				if (nullind)
+-					*nullind = 0;
+-				if (datalen) {
+-					*datalen = len;
+-				}
++				*nullind = 0;
+ 			}
+ 		} else {
+-			if (datalen)
+-				*datalen = 0;
++			*pdatalen = 0;
+ 		}
+ 	}
+ 	return result;
+@@ -2001,70 +2000,31 @@ int
+ _ct_get_server_type(int datatype)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "_ct_get_server_type(%d)\n", datatype);
++	
+ 	switch (datatype) {
+-	case CS_IMAGE_TYPE:
+-		return SYBIMAGE;
+-		break;
+-	case CS_BINARY_TYPE:
+-		return SYBBINARY;
+-		break;
+-	case CS_BIT_TYPE:
+-		return SYBBIT;
+-		break;
+-	case CS_CHAR_TYPE:
+-		return SYBCHAR;
+-		break;
++	case CS_IMAGE_TYPE:		return SYBIMAGE;
++	case CS_BINARY_TYPE:		return SYBBINARY;
++	case CS_BIT_TYPE:		return SYBBIT;	
++	case CS_CHAR_TYPE:		return SYBCHAR;	
+ 	case CS_LONG_TYPE:
+-	case CS_BIGINT_TYPE:
+-		return SYBINT8;
+-		break;
+-	case CS_INT_TYPE:
+-		return SYBINT4;
+-		break;
+-	case CS_SMALLINT_TYPE:
+-		return SYBINT2;
+-		break;
+-	case CS_TINYINT_TYPE:
+-		return SYBINT1;
+-		break;
+-	case CS_REAL_TYPE:
+-		return SYBREAL;
+-		break;
+-	case CS_FLOAT_TYPE:
+-		return SYBFLT8;
+-		break;
+-	case CS_MONEY_TYPE:
+-		return SYBMONEY;
+-		break;
+-	case CS_MONEY4_TYPE:
+-		return SYBMONEY4;
+-		break;
+-	case CS_DATETIME_TYPE:
+-		return SYBDATETIME;
+-		break;
+-	case CS_DATETIME4_TYPE:
+-		return SYBDATETIME4;
+-		break;
+-	case CS_NUMERIC_TYPE:
+-		return SYBNUMERIC;
+-		break;
+-	case CS_DECIMAL_TYPE:
+-		return SYBDECIMAL;
+-		break;
+-	case CS_VARBINARY_TYPE:
+-		return SYBVARBINARY;
+-		break;
+-	case CS_TEXT_TYPE:
+-		return SYBTEXT;
+-		break;
+-	case CS_UNIQUE_TYPE:
+-		return SYBUNIQUE;
+-		break;
+-	case CS_LONGBINARY_TYPE:	/* vicm */
+-		return SYBLONGBINARY;
+-		break;
+-	case CS_UNICHAR_TYPE:
+-		return SYBVARCHAR;
++	case CS_BIGINT_TYPE:		return SYBINT8;	
++	case CS_INT_TYPE:		return SYBINT4;	
++	case CS_SMALLINT_TYPE:		return SYBINT2;	
++	case CS_TINYINT_TYPE:		return SYBINT1;	
++	case CS_REAL_TYPE:		return SYBREAL;	
++	case CS_FLOAT_TYPE:		return SYBFLT8;	
++	case CS_MONEY_TYPE:		return SYBMONEY;
++	case CS_MONEY4_TYPE:		return SYBMONEY4;
++	case CS_DATETIME_TYPE:		return SYBDATETIME;
++	case CS_DATETIME4_TYPE:		return SYBDATETIME4;
++	case CS_NUMERIC_TYPE:		return SYBNUMERIC;
++	case CS_DECIMAL_TYPE:		return SYBDECIMAL;
++	case CS_VARBINARY_TYPE:		return SYBVARBINARY;
++	case CS_TEXT_TYPE:		return SYBTEXT;	
++	case CS_UNIQUE_TYPE:		return SYBUNIQUE;
++	case CS_LONGBINARY_TYPE:	return SYBLONGBINARY;
++	case CS_UNICHAR_TYPE:		return SYBVARCHAR;
++
+ 	default:
+ 		return -1;
+ 		break;
+@@ -2159,7 +2119,8 @@ ct_cancel(CS_CONNECTION * conn, CS_COMMAND * cmd, CS_INT type)
+ 					tdsdump_log(TDS_DBG_FUNC, "ct_cancel() command state READY/IDLE\n");
+ 					break;
+ 				case _CS_COMMAND_SENT:
+-					tdsdump_log(TDS_DBG_FUNC, "ct_cancel() command state SENT results_state %d\n", cmd->results_state);
++					tdsdump_log(TDS_DBG_FUNC, "ct_cancel() command state SENT results_state %d\n",
++								   cmd->results_state);
+ 					if (cmd->results_state != _CS_RES_NONE) {
+ 						tdsdump_log(TDS_DBG_FUNC, "ct_cancel() sending a cancel \n");
+ 						tds_send_cancel(cmd_conn->tds_socket);
+@@ -2929,150 +2890,50 @@ ct_capability(CS_CONNECTION * con, CS_INT action, CS_INT type, CS_INT capability
+ 
+ 	if (type == CS_CAP_RESPONSE) {
+ 		switch (capability) {
+-		case CS_DATA_NOBOUNDARY:
+-			idx = 13;
+-			bitmask = 0x01;
+-			break;
+-		case CS_RES_NOTDSDEBUG:
+-			idx = 13;
+-			bitmask = 0x02;
+-			break;
+-		case CS_RES_NOSTRIPBLANKS:
+-			idx = 13;
+-			bitmask = 0x04;
+-			break;
+-		case CS_DATA_NOINT8:
+-			idx = 13;
+-			bitmask = 0x08;
+-			break;
+-		case CS_DATA_NOINTN:
+-			idx = 14;
+-			bitmask = 0x01;
+-			break;
+-		case CS_DATA_NODATETIMEN:
+-			idx = 14;
+-			bitmask = 0x02;
+-			break;
+-		case CS_DATA_NOMONEYN:
+-			idx = 14;
+-			bitmask = 0x04;
+-			break;
+-		case CS_CON_NOOOB:
+-			idx = 14;
+-			bitmask = 0x08;
+-			break;
+-		case CS_CON_NOINBAND:
+-			idx = 14;
+-			bitmask = 0x10;
+-			break;
+-		case CS_PROTO_NOTEXT:
+-			idx = 14;
+-			bitmask = 0x20;
+-			break;
+-		case CS_PROTO_NOBULK:
+-			idx = 14;
+-			bitmask = 0x40;
+-			break;
+-		case CS_DATA_NOSENSITIVITY:
+-			idx = 14;
+-			bitmask = 0x80;
+-			break;
+-		case CS_DATA_NOFLT4:
+-			idx = 15;
+-			bitmask = 0x01;
+-			break;
+-		case CS_DATA_NOFLT8:
+-			idx = 15;
+-			bitmask = 0x02;
+-			break;
+-		case CS_DATA_NONUM:
+-			idx = 15;
+-			bitmask = 0x04;
+-			break;
+-		case CS_DATA_NOTEXT:
+-			idx = 15;
+-			bitmask = 0x08;
+-			break;
+-		case CS_DATA_NOIMAGE:
+-			idx = 15;
+-			bitmask = 0x10;
+-			break;
+-		case CS_DATA_NODEC:
+-			idx = 15;
+-			bitmask = 0x20;
+-			break;
+-		case CS_DATA_NOLCHAR:
+-			idx = 15;
+-			bitmask = 0x40;
+-			break;
+-		case CS_DATA_NOLBIN:
+-			idx = 15;
+-			bitmask = 0x80;
+-			break;
+-		case CS_DATA_NOCHAR:
+-			idx = 16;
+-			bitmask = 0x01;
+-			break;
+-		case CS_DATA_NOVCHAR:
+-			idx = 16;
+-			bitmask = 0x02;
+-			break;
+-		case CS_DATA_NOBIN:
+-			idx = 16;
+-			bitmask = 0x04;
+-			break;
+-		case CS_DATA_NOVBIN:
+-			idx = 16;
+-			bitmask = 0x08;
+-			break;
+-		case CS_DATA_NOMNY8:
+-			idx = 16;
+-			bitmask = 0x10;
+-			break;
+-		case CS_DATA_NOMNY4:
+-			idx = 16;
+-			bitmask = 0x20;
+-			break;
+-		case CS_DATA_NODATE8:
+-			idx = 16;
+-			bitmask = 0x40;
+-			break;
+-		case CS_DATA_NODATE4:
+-			idx = 16;
+-			bitmask = 0x80;
+-			break;
+-		case CS_RES_NOMSG:
+-			idx = 17;
+-			bitmask = 0x02;
+-			break;
+-		case CS_RES_NOEED:
+-			idx = 17;
+-			bitmask = 0x04;
+-			break;
+-		case CS_RES_NOPARAM:
+-			idx = 17;
+-			bitmask = 0x08;
+-			break;
+-		case CS_DATA_NOINT1:
+-			idx = 17;
+-			bitmask = 0x10;
+-			break;
+-		case CS_DATA_NOINT2:
+-			idx = 17;
+-			bitmask = 0x20;
+-			break;
+-		case CS_DATA_NOINT4:
+-			idx = 17;
+-			bitmask = 0x40;
+-			break;
+-		case CS_DATA_NOBIT:
+-			idx = 17;
+-			bitmask = 0x80;
+-			break;
++		case CS_DATA_NOBOUNDARY:	idx = 13; bitmask = 0x01;	break;
++		case CS_RES_NOTDSDEBUG:		idx = 13; bitmask = 0x02;	break;
++		case CS_RES_NOSTRIPBLANKS:	idx = 13; bitmask = 0x04;	break;
++		case CS_DATA_NOINT8:		idx = 13; bitmask = 0x08;	break;
++
++		case CS_DATA_NOINTN:		idx = 14; bitmask = 0x01;	break;
++		case CS_DATA_NODATETIMEN:	idx = 14; bitmask = 0x02;	break;
++		case CS_DATA_NOMONEYN:		idx = 14; bitmask = 0x04;	break;
++		case CS_CON_NOOOB:		idx = 14; bitmask = 0x08;	break;
++		case CS_CON_NOINBAND:		idx = 14; bitmask = 0x10;	break;
++		case CS_PROTO_NOTEXT:		idx = 14; bitmask = 0x20;	break;
++		case CS_PROTO_NOBULK:		idx = 14; bitmask = 0x40;	break;
++		case CS_DATA_NOSENSITIVITY:	idx = 14; bitmask = 0x80;	break;
++
++		case CS_DATA_NOFLT4:		idx = 15; bitmask = 0x01;	break;
++		case CS_DATA_NOFLT8:		idx = 15; bitmask = 0x02;	break;
++		case CS_DATA_NONUM:		idx = 15; bitmask = 0x04;	break;
++		case CS_DATA_NOTEXT:		idx = 15; bitmask = 0x08;	break;
++		case CS_DATA_NOIMAGE:		idx = 15; bitmask = 0x10;	break;
++		case CS_DATA_NODEC:		idx = 15; bitmask = 0x20;	break;
++		case CS_DATA_NOLCHAR:		idx = 15; bitmask = 0x40;	break;
++		case CS_DATA_NOLBIN:		idx = 15; bitmask = 0x80;	break;
++
++		case CS_DATA_NOCHAR:		idx = 16; bitmask = 0x01;	break;
++		case CS_DATA_NOVCHAR:		idx = 16; bitmask = 0x02;	break;
++		case CS_DATA_NOBIN:		idx = 16; bitmask = 0x04;	break;
++		case CS_DATA_NOVBIN:		idx = 16; bitmask = 0x08;	break;
++		case CS_DATA_NOMNY8:		idx = 16; bitmask = 0x10;	break;
++		case CS_DATA_NOMNY4:		idx = 16; bitmask = 0x20;	break;
++		case CS_DATA_NODATE8:		idx = 16; bitmask = 0x40;	break;
++		case CS_DATA_NODATE4:		idx = 16; bitmask = 0x80;	break;
++
++		case CS_RES_NOMSG:		idx = 17; bitmask = 0x02;	break;
++		case CS_RES_NOEED:		idx = 17; bitmask = 0x04;	break;
++		case CS_RES_NOPARAM:		idx = 17; bitmask = 0x08;	break;
++		case CS_DATA_NOINT1:		idx = 17; bitmask = 0x10;	break;
++		case CS_DATA_NOINT2:		idx = 17; bitmask = 0x20;	break;
++		case CS_DATA_NOINT4:		idx = 17; bitmask = 0x40;	break;
++		case CS_DATA_NOBIT:		idx = 17; bitmask = 0x80;	break;
++
+ 		default:
+ 			tdsdump_log(TDS_DBG_SEVERE, "ct_capability -- attempt to set/get a non-existant capability\n");
+ 			return CS_FAIL;
+-		}			/* end capability */
++		} /* end capability */
+ 
+ 		assert(13 <= idx && idx <= 17);
+ 		assert(bitmask);
+@@ -3107,165 +2968,68 @@ ct_capability(CS_CONNECTION * con, CS_INT action, CS_INT type, CS_INT capability
+ 	 * These capabilities describe the types of requests that a server can support.
+ 	 */
+ 	switch (capability) {
+-	case CS_PROTO_DYNPROC:
+-		*(CS_BOOL *) value = mask[2] & 0x01 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_FLTN:
+-		*(CS_BOOL *) value = mask[2] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_BITN:
+-		*(CS_BOOL *) value = mask[2] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_INT8:
+-		*(CS_BOOL *) value = mask[2] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_VOID:
+-		*(CS_BOOL *) value = mask[2] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CON_INBAND:
+-		*(CS_BOOL *) value = mask[3] & 0x01 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CON_LOGICAL:
+-		*(CS_BOOL *) value = mask[3] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_PROTO_TEXT:
+-		*(CS_BOOL *) value = mask[3] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_PROTO_BULK:
+-		*(CS_BOOL *) value = mask[3] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_URGNOTIF:
+-		*(CS_BOOL *) value = mask[3] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_SENSITIVITY:
+-		*(CS_BOOL *) value = mask[3] & 0x20 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_BOUNDARY:
+-		*(CS_BOOL *) value = mask[3] & 0x40 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_PROTO_DYNAMIC:
+-		*(CS_BOOL *) value = mask[3] & 0x80 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_MONEYN:
+-		*(CS_BOOL *) value = mask[4] & 0x01 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CSR_PREV:
+-		*(CS_BOOL *) value = mask[4] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CSR_FIRST:
+-		*(CS_BOOL *) value = mask[4] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CSR_LAST:
+-		*(CS_BOOL *) value = mask[4] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CSR_ABS:
+-		*(CS_BOOL *) value = mask[4] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CSR_REL:
+-		*(CS_BOOL *) value = mask[4] & 0x20 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CSR_MULTI:
+-		*(CS_BOOL *) value = mask[4] & 0x40 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_CON_OOB:
+-		*(CS_BOOL *) value = mask[4] & 0x80 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_NUM:
+-		*(CS_BOOL *) value = mask[5] & 0x01 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_TEXT:
+-		*(CS_BOOL *) value = mask[5] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_IMAGE:
+-		*(CS_BOOL *) value = mask[5] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_DEC:
+-		*(CS_BOOL *) value = mask[5] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_LCHAR:
+-		*(CS_BOOL *) value = mask[5] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_LBIN:
+-		*(CS_BOOL *) value = mask[5] & 0x20 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_INTN:
+-		*(CS_BOOL *) value = mask[5] & 0x40 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_DATETIMEN:
+-		*(CS_BOOL *) value = mask[5] & 0x80 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_BIN:
+-		*(CS_BOOL *) value = mask[6] & 0x01 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_VBIN:
+-		*(CS_BOOL *) value = mask[6] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_MNY8:
+-		*(CS_BOOL *) value = mask[6] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_MNY4:
+-		*(CS_BOOL *) value = mask[6] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_DATE8:
+-		*(CS_BOOL *) value = mask[6] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_DATE4:
+-		*(CS_BOOL *) value = mask[6] & 0x20 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_FLT4:
+-		*(CS_BOOL *) value = mask[6] & 0x40 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_FLT8:
+-		*(CS_BOOL *) value = mask[6] & 0x80 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_MSG:
+-		*(CS_BOOL *) value = mask[7] & 0x01 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_PARAM:
+-		*(CS_BOOL *) value = mask[7] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_INT1:
+-		*(CS_BOOL *) value = mask[7] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_INT2:
+-		*(CS_BOOL *) value = mask[7] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_INT4:
+-		*(CS_BOOL *) value = mask[7] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_BIT:
+-		*(CS_BOOL *) value = mask[7] & 0x20 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_CHAR:
+-		*(CS_BOOL *) value = mask[7] & 0x40 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_DATA_VCHAR:
+-		*(CS_BOOL *) value = mask[7] & 0x80 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_LANG:
+-		*(CS_BOOL *) value = mask[8] & 0x02 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_RPC:
+-		*(CS_BOOL *) value = mask[8] & 0x04 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_NOTIF:
+-		*(CS_BOOL *) value = mask[8] & 0x08 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_MSTMT:
+-		*(CS_BOOL *) value = mask[8] & 0x10 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_BCP:
+-		*(CS_BOOL *) value = mask[8] & 0x20 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_CURSOR:
+-		*(CS_BOOL *) value = mask[8] & 0x40 ? CS_TRUE : CS_FALSE;
+-		break;
+-	case CS_REQ_DYN:
+-		*(CS_BOOL *) value = mask[8] & 0x80 ? CS_TRUE : CS_FALSE;
+-		break;
++	case CS_PROTO_DYNPROC:		*(CS_BOOL *) value = mask[2] & 0x01 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_FLTN:		*(CS_BOOL *) value = mask[2] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_BITN:		*(CS_BOOL *) value = mask[2] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_INT8:		*(CS_BOOL *) value = mask[2] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_VOID:		*(CS_BOOL *) value = mask[2] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++
++	case CS_CON_INBAND:		*(CS_BOOL *) value = mask[3] & 0x01 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CON_LOGICAL:		*(CS_BOOL *) value = mask[3] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_PROTO_TEXT:		*(CS_BOOL *) value = mask[3] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_PROTO_BULK:		*(CS_BOOL *) value = mask[3] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_URGNOTIF:		*(CS_BOOL *) value = mask[3] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_SENSITIVITY:	*(CS_BOOL *) value = mask[3] & 0x20 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_BOUNDARY:		*(CS_BOOL *) value = mask[3] & 0x40 ? CS_TRUE : CS_FALSE;	break;
++	case CS_PROTO_DYNAMIC:		*(CS_BOOL *) value = mask[3] & 0x80 ? CS_TRUE : CS_FALSE;	break;
++
++	case CS_DATA_MONEYN:		*(CS_BOOL *) value = mask[4] & 0x01 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CSR_PREV:		*(CS_BOOL *) value = mask[4] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CSR_FIRST:		*(CS_BOOL *) value = mask[4] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CSR_LAST:		*(CS_BOOL *) value = mask[4] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CSR_ABS:		*(CS_BOOL *) value = mask[4] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CSR_REL:		*(CS_BOOL *) value = mask[4] & 0x20 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CSR_MULTI:		*(CS_BOOL *) value = mask[4] & 0x40 ? CS_TRUE : CS_FALSE;	break;
++	case CS_CON_OOB:		*(CS_BOOL *) value = mask[4] & 0x80 ? CS_TRUE : CS_FALSE;	break;
++
++	case CS_DATA_NUM:		*(CS_BOOL *) value = mask[5] & 0x01 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_TEXT:		*(CS_BOOL *) value = mask[5] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_IMAGE:		*(CS_BOOL *) value = mask[5] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_DEC:		*(CS_BOOL *) value = mask[5] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_LCHAR:		*(CS_BOOL *) value = mask[5] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_LBIN:		*(CS_BOOL *) value = mask[5] & 0x20 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_INTN:		*(CS_BOOL *) value = mask[5] & 0x40 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_DATETIMEN:		*(CS_BOOL *) value = mask[5] & 0x80 ? CS_TRUE : CS_FALSE;	break;
++
++	case CS_DATA_BIN:		*(CS_BOOL *) value = mask[6] & 0x01 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_VBIN:		*(CS_BOOL *) value = mask[6] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_MNY8:		*(CS_BOOL *) value = mask[6] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_MNY4:		*(CS_BOOL *) value = mask[6] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_DATE8:		*(CS_BOOL *) value = mask[6] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_DATE4:		*(CS_BOOL *) value = mask[6] & 0x20 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_FLT4:		*(CS_BOOL *) value = mask[6] & 0x40 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_FLT8:		*(CS_BOOL *) value = mask[6] & 0x80 ? CS_TRUE : CS_FALSE;	break;
++
++	case CS_REQ_MSG:		*(CS_BOOL *) value = mask[7] & 0x01 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_PARAM:		*(CS_BOOL *) value = mask[7] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_INT1:		*(CS_BOOL *) value = mask[7] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_INT2:		*(CS_BOOL *) value = mask[7] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_INT4:		*(CS_BOOL *) value = mask[7] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_BIT:		*(CS_BOOL *) value = mask[7] & 0x20 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_CHAR:		*(CS_BOOL *) value = mask[7] & 0x40 ? CS_TRUE : CS_FALSE;	break;
++	case CS_DATA_VCHAR:		*(CS_BOOL *) value = mask[7] & 0x80 ? CS_TRUE : CS_FALSE;	break;
++
++	case CS_REQ_LANG:		*(CS_BOOL *) value = mask[8] & 0x02 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_RPC:		*(CS_BOOL *) value = mask[8] & 0x04 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_NOTIF:		*(CS_BOOL *) value = mask[8] & 0x08 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_MSTMT:		*(CS_BOOL *) value = mask[8] & 0x10 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_BCP:		*(CS_BOOL *) value = mask[8] & 0x20 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_CURSOR:		*(CS_BOOL *) value = mask[8] & 0x40 ? CS_TRUE : CS_FALSE;	break;
++	case CS_REQ_DYN:		*(CS_BOOL *) value = mask[8] & 0x80 ? CS_TRUE : CS_FALSE;	break;
++
+ 	default:
+ 		tdsdump_log(TDS_DBG_SEVERE, "ct_capability -- attempt to get a non-existant capability\n");
+-		return CS_FAIL;
++		return CS_FAIL;	
+ 		break;
+ 	}			/* end capability */
+ 
+@@ -3281,7 +3045,7 @@ ct_capability(CS_CONNECTION * con, CS_INT action, CS_INT type, CS_INT capability
+ 	tdsdump_log(TDS_DBG_SEVERE, "ct_capability -- attempt to set a read-only capability (type %d, action %d)\n",
+ 		type, action);
+ 	return CS_FAIL;
+-}				/* end ct_capability( */
++} /* end ct_capability */
+ 
+ 
+ CS_RETCODE
+@@ -3828,7 +3592,8 @@ ct_options(CS_CONNECTION * con, CS_INT action, CS_INT option, CS_VOID * param, C
+ SEND_OPTION:
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "\ttds_submit_optioncmd will be action(%s) option(%d) arg(%x) arglen(%d)\n",
+-				action_string, tds_option, tds_argsize == 1 ? tds_argument.ti : (tds_argsize == 4 ? tds_argument.i : 0), tds_argsize);
++				action_string, tds_option, 
++				tds_argsize == 1 ? tds_argument.ti : (tds_argsize == 4 ? tds_argument.i : 0), tds_argsize);
+ 
+ 	if (tds_submit_optioncmd(tds, tds_command, tds_option, &tds_argument, tds_argsize) == TDS_FAIL) {
+ 		return CS_FAIL;
+@@ -4240,7 +4005,8 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ 		/* actual data */
+ 		tdsdump_log(TDS_DBG_FUNC, "paraminfoalloc: status = %d, maxlen %d \n", p->status, p->maxlen);
+ 		tdsdump_log(TDS_DBG_FUNC,
+-			    "paraminfoalloc: name = %*.*s, varint size %d column_type %d size %d, %d column_cur_size %d column_output = %d\n",
++			    "paraminfoalloc: name = %*.*s, varint size %d "
++			    "column_type %d size %d, %d column_cur_size %d column_output = %d\n",
+ 			    pcol->column_namelen, pcol->column_namelen, pcol->column_name,
+ 			    pcol->column_varint_size, pcol->column_type,
+ 			    pcol->on_server.column_size, pcol->column_size,
+@@ -4300,7 +4066,8 @@ param_clear(CS_PARAM * pparam)
+ 
+ 
+ static int
+-_ct_fill_param(CS_INT cmd_type, CS_PARAM * param, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT * datalen, CS_SMALLINT * indicator, CS_BYTE byvalue)
++_ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *data, CS_INT *datalen, 
++	       CS_SMALLINT *indicator, CS_BYTE byvalue)
+ {
+ 	int param_is_null = 0;
+ 
+@@ -4379,7 +4146,8 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM * param, CS_DATAFMT * datafmt, CS_VOID
+ 
+ 				if (*(param->datalen) && data) {
+ 					if (*(param->datalen) == CS_NULLTERM) {
+-						tdsdump_log(TDS_DBG_INFO1, " _ct_fill_param() about to strdup string %u bytes long\n",
++						tdsdump_log(TDS_DBG_INFO1, 
++							    " _ct_fill_param() about to strdup string %u bytes long\n",
+ 							    (unsigned int) strlen(data));
+ 						*(param->datalen) = strlen(data);
+ 					} else if (*(param->datalen) < 0) {
+
+commit 3e75d66e9f7bbe6cbb906df1d3eceff53eefdd73
+Author: jklowden <jklowden>
+Date:   Sat Jul 5 22:58:01 2008 +0000
+
+    make it compile....
+
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 280ed9f..0ff289b 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.64 2007/04/18 14:29:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.65 2008/07/05 22:58:01 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -246,8 +246,10 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	TDSCOLUMN *curcol;
+ 	TDSBLOB *blob;
+ 
+-	if (!stmt->params)
++	if (!stmt->params) {
++		tdsdump_log(TDS_DBG_FUNC, "error? continue_parse_prepared_query: no parameters provided");
+ 		return SQL_ERROR;
++	}
+ 
+ 	if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count)
+ 		return SQL_ERROR;
+@@ -261,13 +263,41 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	assert(curcol->column_cur_size <= curcol->column_size);
+ 	need_bytes = curcol->column_size - curcol->column_cur_size;
+ 
+-	if (SQL_NTS == StrLen_or_Ind)
++	if (DataPtr == NULL) {
++		switch(StrLen_or_Ind) {
++		case SQL_NULL_DATA:
++		case SQL_DEFAULT_PARAM:
++			break;	/* OK */
++		default:
++			odbc_errs_add(&stmt->dbc->errs, "HY009", NULL); /* Invalid use of null pointer */
++			return SQL_ERROR;
++		}
++	}		
++
++	switch(StrLen_or_Ind) {
++	case SQL_NTS:
+ 		len = strlen((char *) DataPtr);
+-	else if (SQL_DEFAULT_PARAM == StrLen_or_Ind || StrLen_or_Ind < 0)
+-		/* FIXME: I don't know what to do */
++		break;
++	case SQL_NULL_DATA:
++		len = 0;
++		break;
++	case SQL_DEFAULT_PARAM:
++		/* FIXME: use the default if the parameter has one. */
++		odbc_errs_add(&stmt->dbc->errs, "07S01", NULL); /* Invalid use of default parameter */
+ 		return SQL_ERROR;
+-	else
++	default:
++		if (DataPtr && StrLen_or_Ind < 0) {
++			/*
++			 * "The argument DataPtr was not a null pointer, and 
++			 * the argument StrLen_or_Ind was less than 0 
++			 * but not equal to SQL_NTS or SQL_NULL_DATA."
++			 */
++			odbc_errs_add(&stmt->dbc->errs, "HY090", NULL);
++			return SQL_ERROR;
++		}
+ 		len = StrLen_or_Ind;
++		break;
++	}
+ 
+ 	if (!blob && len > need_bytes)
+ 		len = need_bytes;
+@@ -275,21 +305,132 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	/* copy to destination */
+ 	if (blob) {
+ 		TDS_CHAR *p;
++		int dest_type, src_type, sql_src_type, res;
++		CONV_RESULT ores;
++		TDS_DBC * dbc = stmt->dbc;
++		void *free_ptr = NULL;
++		int start = 0;
++		SQLPOINTER extradata = NULL;
++		SQLLEN extralen = 0;
++		
++
++		if (0 == (dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type))) {
++			odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
++			return SQL_ERROR;
++		}
++			
++		/* get C type */
++		sql_src_type = drec_apd->sql_desc_concise_type;
++		if (sql_src_type == SQL_C_DEFAULT)
++			sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
++
++		/* test source type */
++		/* TODO test intervals */
++		src_type = odbc_c_to_server_type(sql_src_type);
++		if (src_type == TDS_FAIL) {
++			odbc_errs_add(&stmt->dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
++			return SQL_ERROR;
++		}
++		
++		if (sql_src_type == SQL_C_CHAR) {
++			switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
++			case SYBBINARY:
++			case SYBVARBINARY:
++			case XSYBBINARY:
++			case XSYBVARBINARY:
++			case SYBLONGBINARY:
++			case SYBIMAGE:
++				if (!*((char*)DataPtr+len-1))
++					--len;
++					
++				if (!len)
++					return SQL_SUCCESS;
++					
++				if (curcol->column_cur_size > 0
++				&&  curcol->column_text_sqlputdatainfo) {
++					TDS_CHAR data[2];
++					data[0] = curcol->column_text_sqlputdatainfo;
++					data[1] = *(char*)DataPtr;
++				    
++					res = tds_convert(dbc->env->tds_ctx, src_type, data, 2, dest_type, &ores);
++					switch(res) {
++					case TDS_CONVERT_FAIL:
++					case TDS_CONVERT_NOAVAIL:
++					case TDS_CONVERT_SYNTAX:
++						odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
++						return SQL_ERROR;
++					case TDS_CONVERT_NOMEM:
++						odbc_errs_add(&dbc->errs, "HY001", NULL); /* Memory allocation error */
++						return SQL_ERROR;
++					case TDS_CONVERT_OVERFLOW:
++						odbc_errs_add(&dbc->errs, "22003", NULL); /* Numeric value out of range */
++						return SQL_ERROR;
++					}
++				    
++					extradata = ores.ib;
++					extralen = res;
++					
++					start = 1;
++					--len;
++				}
++				
++			        if (len&1) {
++					--len;
++					curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
++				}
++
++				res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr+start, len, dest_type, &ores);
++				if (res < 0) {
++					switch(res) {
++					case TDS_CONVERT_FAIL:
++					case TDS_CONVERT_NOAVAIL:
++					case TDS_CONVERT_SYNTAX:
++						odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
++						break;
++					case TDS_CONVERT_NOMEM:
++						odbc_errs_add(&dbc->errs, "HY001", NULL); /* Memory allocation error */
++						break;
++					case TDS_CONVERT_OVERFLOW:
++						odbc_errs_add(&dbc->errs, "22003", NULL); /* Numeric value out of range */
++						break;
++					}
++					free(extradata);
++					return SQL_ERROR;
++				}
++			    
++				DataPtr = free_ptr = ores.ib;
++				len = res;
++				break;
++			}
++		}
+ 
+ 		if (blob->textvalue)
+-			p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size);
++			p = (TDS_CHAR *) realloc(blob->textvalue, len + extralen + curcol->column_cur_size);
+ 		else {
+ 			assert(curcol->column_cur_size == 0);
+-			p = (TDS_CHAR *) malloc(len);
++			p = (TDS_CHAR *) malloc(len + extralen);
+ 		}
+-		if (!p)
++		if (!p) {
++			free(free_ptr);
++			free(extradata);
++			odbc_errs_add(&dbc->errs, "HY001", NULL); /* Memory allocation error */
+ 			return SQL_ERROR;
++		}
+ 		blob->textvalue = p;
++		if (extralen) {
++			memcpy(blob->textvalue + curcol->column_cur_size, extradata, extralen);
++			curcol->column_cur_size += extralen;
++		}
+ 		memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len);
++		
++		free(extradata);
++		free(free_ptr);
+ 	} else {
+ 		memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len);
+ 	}
++	
+ 	curcol->column_cur_size += len;
++	
+ 	if (blob && curcol->column_cur_size > curcol->column_size)
+ 		curcol->column_size = curcol->column_cur_size;
+ 
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 379930d..c03bf87 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.4 2008/01/12 00:14:11 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.5 2008/07/05 22:58:01 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -47,6 +47,16 @@ fill_chars(char *buf, size_t len, unsigned int start, unsigned int step)
+ 		buf[n] = 'a' + ((start+n) * step % ('z' - 'a' + 1));
+ }
+ 
++static void
++fill_hex(char *buf, size_t len, unsigned int start, unsigned int step)
++{
++	size_t n;
++
++	for (n = 0; n < len; ++n)
++		sprintf(buf + 2*n, "%2x", (unsigned int)('a' + ((start+n) * step % ('z' - 'a' + 1))));
++}
++
++
+ static int
+ check_chars(const char *buf, size_t len, unsigned int start, unsigned int step)
+ {
+@@ -60,6 +70,21 @@ check_chars(const char *buf, size_t len, unsigned int start, unsigned int step)
+ }
+ 
+ static int
++check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
++{
++	size_t n;
++	char symbol[3];
++
++	for (n = 0; n < len; ++n) {
++		sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
++		if (buf[n] != symbol[(start+n) % 2])
++			return 0;
++	}
++
++	return 1;
++}
++
++static int
+ readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+ {
+ 	SQLRETURN rcode;
+@@ -93,6 +118,43 @@ readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+ 	return rcode;
+ }
+ 
++static int
++readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
++{
++	SQLRETURN rcode = SQL_SUCCESS_WITH_INFO;
++	char buf[8192];
++	SQLLEN len, total = 0;
++	int i = 0;
++	int check;
++	int bufsize;
++	
++	if (step%2) bufsize = sizeof(buf) - 1;
++	else bufsize = sizeof(buf);
++
++	printf(">> readBlobAsChar field %d\n", pos);
++	while (rcode == SQL_SUCCESS_WITH_INFO) {
++		i++;
++		rcode = SQLGetData(stmth, pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len);
++		if (!SQL_SUCCEEDED(rcode) || len <= 0)
++			break;
++		if (len > (SQLLEN) bufsize)
++			len = (SQLLEN) bufsize - 1;
++		printf(">>     step %d: %d bytes readed\n", i, (int) len);
++		
++		check =	check_hex(buf, len, 2*987 + total, 25);
++		if (!check) {
++			fprintf(stderr, "Wrong buffer content\n");
++			failed = 1;
++		}
++		total += len;
++	}
++	printf(">>   total bytes read = %d \n", (int) total);
++	if (total != 20000)
++		failed = 1;
++	return rcode;
++}
++
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -106,12 +168,14 @@ main(int argc, char **argv)
+ 	SQLLEN vind1;
+ 	char buf2[NBYTES];
+ 	SQLLEN vind2;
++	char buf3[NBYTES*2 + 1];
++	SQLLEN vind3;
+ 	int cnt = 2;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b IMAGE, v INT )");
++	Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )");
+ 
+ 	/* Insert rows ... */
+ 
+@@ -121,7 +185,7 @@ main(int argc, char **argv)
+ 		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+ 		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ? )", SQL_NTS);
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+ 
+ 		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+@@ -133,9 +197,12 @@ main(int argc, char **argv)
+ 		SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3");
+ 
+-		SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++		SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4");
+ 
++		SQLBindParameter(m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 5");
++
+ 		key = i;
+ 		vind0 = 0;
+ 
+@@ -144,6 +211,10 @@ main(int argc, char **argv)
+ 
+ 		fill_chars(buf2, NBYTES, 987, 25);
+ 		vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES);
++		
++		memset(buf3, 0, sizeof(buf3));
++		vind3 = SQL_LEN_DATA_AT_EXEC(2*NBYTES+1);
++		
+ 
+ 		printf(">> insert... %d\n", i);
+ 		rcode = SQLExecute(m_hstmt);
+@@ -155,10 +226,25 @@ main(int argc, char **argv)
+ 			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
+ 			printf(">> SQLParamData: ptr = %p  rcode = %d\n", (void *) p, rcode);
+ 			if (rcode == SQL_NEED_DATA) {
+-				SQLRETURN rcode = SQLPutData(m_hstmt, p, NBYTES);
+-
+-				CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+-				printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++				SQLRETURN rcode;
++				if (p == buf3) {
++					fill_hex(buf3, NBYTES, 987, 25);
++					
++					rcode = SQLPutData(m_hstmt, p, NBYTES - (i&1));
++
++					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
++					
++					rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1));
++
++					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
++				} else {
++					rcode = SQLPutData(m_hstmt, p, NBYTES);
++
++					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
++					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
++				}
+ 			}
+ 		}
+ 
+@@ -182,7 +268,7 @@ main(int argc, char **argv)
+ 			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
+ 		}
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b, v FROM #tt WHERE k = ?", SQL_NTS);
++		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
+ 
+ 		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+@@ -192,7 +278,9 @@ main(int argc, char **argv)
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2");
+ 		SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3");
+-		SQLBindCol(m_hstmt, 3, SQL_C_LONG, &key, 0, &vind0);
++		SQLBindCol(m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 4");
++		SQLBindCol(m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1");
+ 
+ 		vind0 = 0;
+@@ -210,6 +298,8 @@ main(int argc, char **argv)
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
+ 		rcode = readBlob(m_hstmt, 2);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
++		rcode = readBlobAsChar(m_hstmt, 3, i);
++		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR");
+ 
+ 		rcode = SQLCloseCursor(m_hstmt);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH");
+
+commit 9308a52b17b06e7c7309024f5119152771134875
+Author: jklowden <jklowden>
+Date:   Sun Jul 6 13:17:34 2008 +0000
+
+    add AIX note
+
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index 3c3ece5..1c7baf5 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.17 2008/06/12 00:00:25 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.18 2008/07/06 13:17:34 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -33,6 +33,27 @@ News&nbsp;&nbsp;|&nbsp;
+ <table summary="layout" width="80%" align="center">
+ 
+ <!--  item  -->
++<tr bgcolor="#c9c9ff"><td>Building 0.82 on AIX</td></tr>
++<tr>
++<td>
++<br />
++
++To build FreeTDS 0.82 on AIX, you may find you need GNU libiconv.  The following intructions were provided Denis Putnam on 3 July 2008:
++<ol>
++<li>	Download and install the latest version of <tt>libtool</tt>.
++<li>	Download and install the latest version of the <tt>GNU libiconv</tt>.
++<li>	Download and install <tt>unixODBC</tt>.
++<li>	Download and configure FreeTDS.
++<li>	Run <tt>make</tt>.
++<li>	Copy the latest <tt>libtool</tt> into the <tt>freetds-<i>ver</i></tt> directory.
++<li>	Run <tt><b>make clean &&  make && make install</b></tt>.
++<li>	<tt>cd</tt> to <tt>PREFIX/lib</tt> and run <tt><b>ar -vx</b></tt> on all the <tt>*.a</tt> files to extract the <tt>.so</tt> files. 
++</ol>
++
++</td>
++</tr>
++
++<!--  item  -->
+ <tr bgcolor="#c9c9ff"><td>PHP msdblib niggle encountered</td></tr>
+ <tr>
+ <td>
+
+commit 85589f0a3cd76cd935baf93a6dd6fbfba003f673
+Author: jklowden <jklowden>
+Date:   Sun Jul 6 16:38:26 2008 +0000
+
+    added
+
+diff --git a/src/ctlib/unittests/datafmt.c b/src/ctlib/unittests/datafmt.c
+new file mode 100644
+index 0000000..4ae38b3
+--- /dev/null
++++ b/src/ctlib/unittests/datafmt.c
+@@ -0,0 +1,164 @@
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif /* HAVE_CONFIG_H */
++
++#if HAVE_STRING_H
++#include <string.h>
++#endif /* HAVE_STRING_H */
++
++#include <stdio.h>
++#include <stdlib.h>
++#include <ctpublic.h>
++#include "common.h"
++
++static char software_version[] = "$Id: datafmt.c,v 1.1 2008/07/06 16:38:26 jklowden Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++/* Testing: array binding of result set */
++int
++main(int argc, char *argv[])
++{
++	CS_CONTEXT *ctx;
++	CS_CONNECTION *conn;
++	CS_COMMAND *cmd;
++	int verbose = 0;
++
++	CS_RETCODE ret;
++	CS_RETCODE results_ret;
++	CS_INT result_type;
++	CS_INT num_cols;
++
++	CS_DATAFMT datafmt;
++	CS_INT copied = 0;
++	CS_SMALLINT ind = 0;
++	CS_INT count, row_count = 0;
++
++	CS_CHAR select[1024];
++
++	char *addr = NULL;
++
++	fprintf(stdout, "%s: test data truncation behavior of ct_fetch \n", __FILE__);
++	if (verbose) {
++		fprintf(stdout, "Trying login\n");
++	}
++	ret = try_ctlogin_with_options(argc, argv, &ctx, &conn, &cmd, verbose);
++	if (ret != CS_SUCCEED) {
++		fprintf(stderr, "Login failed\n");
++		return 1;
++	}
++
++	strcpy(select, "select name from systypes where datalength(name) > 2*9 order by datalength(name)");
++	printf("%s\n", select);
++
++	ret = ct_command(cmd, CS_LANG_CMD, select, CS_NULLTERM, CS_UNUSED);
++
++	if (ret != CS_SUCCEED) {
++		fprintf(stderr, "ct_command(%s) failed\n", select);
++		return 1;
++	}
++
++	ret = ct_send(cmd);
++	if (ret != CS_SUCCEED) {
++		fprintf(stderr, "ct_send() failed\n");
++		return 1;
++	}
++
++	while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED) {
++		switch ((int) result_type) {
++		case CS_CMD_SUCCEED:
++			break;
++		case CS_CMD_DONE:
++			break;
++		case CS_CMD_FAIL:
++			fprintf(stderr, "ct_results() result_type CS_CMD_FAIL.\n");
++			return 1;
++		case CS_ROW_RESULT:
++
++			ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
++			if (ret != CS_SUCCEED) {
++				fprintf(stderr, "ct_res_info() failed");
++				return 1;
++			}
++			fprintf(stderr, "%d column%s\n", num_cols, num_cols==1? "":"s");
++
++			ret = ct_describe(cmd, 1, &datafmt);
++			if (ret != CS_SUCCEED) {
++				fprintf(stderr, "ct_describe() failed\n");
++				return 1;
++			}
++
++			fprintf(stderr, "type = %d\n", datafmt.datatype);
++			fprintf(stderr, "maxlength = %d\n", datafmt.maxlength);
++			if (datafmt.datatype == CS_CHAR_TYPE) {
++				fprintf(stderr, "CS_CHAR_TYPE\n");
++				datafmt.format = CS_FMT_NULLTERM;
++				addr = malloc(datafmt.maxlength);
++			}
++
++			fprintf(stderr, "binding column 1 (%s)\n", datafmt.name);
++
++			/* set maxlength to something short to test truncation behavior */
++			if (common_pwd.maxlength) 
++				datafmt.maxlength = common_pwd.maxlength;
++
++			ret = ct_bind(cmd, 1, &datafmt, addr, &copied, &ind);
++			if (ret != CS_SUCCEED) {
++				fprintf(stderr, "ct_bind() failed\n");
++				return 1;
++			}
++
++			fprintf(stderr, "fetching rows with datafmt.maxlength = %d\n", datafmt.maxlength);
++
++			while ((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) != CS_END_DATA) {
++
++				fprintf(stderr, "ct_fetch() row %d returned %s.\n", row_count, cs_prretcode(ret));
++				addr[copied] = '\0';
++				fprintf(stderr, "copied %d bytes: [%s]\n", copied, addr);
++				row_count += count;
++
++				switch (ret) {
++				case CS_SUCCEED:
++					fprintf(stdout, "ct_fetch returned %d row%s\n", count, count==1? "":"s");
++					break;
++				case CS_ROW_FAIL:
++					fprintf(stderr, "error: ct_fetch() returned CS_ROW_FAIL on row %d.\n", row_count);
++					return 1;
++				case CS_CANCELED:
++					fprintf(stderr, "error: ct_fetch() returned CS_CANCELED??\n");
++					return 1;
++				case CS_FAIL:
++					fprintf(stderr, "error: ct_fetch() returned CS_FAIL.\n");
++					return 1;
++				default:
++					fprintf(stderr, "error: ct_fetch() unexpected return.\n");
++					return 1;
++				}
++			}
++			
++			break;
++		}
++	}
++	
++	switch ((int) results_ret) {
++	case CS_END_RESULTS:
++		break;
++	case CS_FAIL:
++		fprintf(stderr, "ct_results() failed.\n");
++		return 1;
++		break;
++	default:
++		fprintf(stderr, "ct_results() unexpected return.\n");
++		return 1;
++	}
++
++	if (verbose) {
++		fprintf(stdout, "Trying logout\n");
++	}
++	ret = try_ctlogout(ctx, conn, cmd, verbose);
++	if (ret != CS_SUCCEED) {
++		fprintf(stderr, "Logout failed\n");
++		return 1;
++	}
++
++	return 0;
++}
+
+commit 84e2ff4c7fbb6566f0030c0ff43a02b966bf786a
+Author: jklowden <jklowden>
+Date:   Sun Jul 6 16:44:24 2008 +0000
+
+    unit tests accept command-line options
+
+diff --git a/ChangeLog b/ChangeLog
+index 8b08bed..478b039 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,7 +1,13 @@
++Sun Jul  6 12:25:38 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c
++	* src/ctlib/unittests/common.h
++	- unit tests accept command-line options
++	* src/ctlib/unittests/datafmt.c added
++	
+ Sat Jul  5 18:52:45 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cspublic.h src/ctlib/cs.c src/ctlib/ct.c
+-	- src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c
+-	- src/ctlib/unittests/datafmt.c
++	* src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c
++	* src/ctlib/unittests/datafmt.c
+ 	- cs_convert sets output resultlen even when dest is too small. 
+ 	* src/odbc/prepare_query.c src/odbc/unittests/blob1.c
+ 	- make it compile....
+@@ -373,4 +379,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2539 2008/07/05 22:57:53 jklowden Exp $
++$Id: ChangeLog,v 1.2540 2008/07/06 16:44:24 jklowden Exp $
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index 795cccd..e7044c7 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,10 +1,11 @@
+-# $Id: Makefile.am,v 1.25 2007/08/16 08:10:09 freddy77 Exp $
++# $Id: Makefile.am,v 1.26 2008/07/06 16:44:24 jklowden Exp $
+ TESTS		=	t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 \
+ 			connect_fail ct_options lang_ct_param array_bind cs_diag \
+ 			get_send_data rpc_ct_param rpc_ct_setparam ct_diagclient \
+ 			ct_diagserver ct_diagall cs_config cancel \
+ 			blk_in blk_out ct_cursor ct_cursors \
+-			ct_dynamic blk_in2
++			ct_dynamic blk_in2 datafmt
++
+ check_PROGRAMS	=	$(TESTS)
+ 
+ t0001_SOURCES		= t0001.c common.c common.h
+@@ -35,6 +36,7 @@ ct_cursor_SOURCES	= ct_cursor.c common.c common.h
+ ct_cursors_SOURCES	= ct_cursors.c common.c common.h
+ ct_dynamic_SOURCES	= ct_dynamic.c common.c common.h
+ blk_in2_SOURCES		= blk_in2.c common.c common.h
++datafmt_SOURCES		= datafmt.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include
+ if MINGW32
+@@ -42,5 +44,6 @@ AM_LDFLAGS	=	-no-fast-install
+ else
+ AM_LDFLAGS	=	-no-install
+ endif
+-LIBS		=	../libct.la @NETWORK_LIBS@
++#IBS		=	../libct.la @NETWORK_LIBS@
++LIBS		=	../.libs/libct.a @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index b992b75..993e2f4 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -12,11 +12,19 @@
+ #include <string.h>
+ #endif /* HAVE_STRING_H */
+ 
++#if HAVE_UNISTD_H
++#include <unistd.h>
++#endif
++
++#ifndef DBNTWIN32
++#include "replacements.h"
++#endif
++
+ #include <ctpublic.h>
+ #include "common.h"
+ #include "ctlib.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.16 2007/12/26 18:45:17 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.17 2008/07/06 16:44:24 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -26,10 +34,19 @@ char DATABASE[512];
+ 
+ COMMON_PWD common_pwd = {0};
+ 
++static char *DIRNAME = NULL;
++static const char *BASENAME = NULL;
++
++static const char *PWD = "../../../PWD";
++
++
+ int cslibmsg_cb_invoked = 0;
+ int clientmsg_cb_invoked = 0;
+ int servermsg_cb_invoked = 0;
+ 
++static CS_RETCODE continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose);
++
++
+ CS_RETCODE
+ read_login_info(void)
+ {
+@@ -39,15 +56,15 @@ read_login_info(void)
+ 	
+ 	if (common_pwd.initialized) {
+ 		strcpy(USER, common_pwd.USER);
+-		strcpy(SERVER, common_pwd.SERVER);
+ 		strcpy(PASSWORD, common_pwd.PASSWORD);
++		strcpy(SERVER, common_pwd.SERVER);
+ 		strcpy(DATABASE, common_pwd.DATABASE);
+ 		return CS_SUCCEED;
+ 	}
+ 
+-	in = fopen("../../../PWD", "r");
++	in = fopen(PWD, "r");
+ 	if (!in) {
+-		fprintf(stderr, "Can not open PWD file\n\n");
++		fprintf(stderr, "Can not open PWD file \"%s\"\n\n", PWD);
+ 		return CS_FAIL;
+ 	}
+ 
+@@ -71,21 +88,107 @@ read_login_info(void)
+ 	return CS_SUCCEED;
+ }
+ 
++static CS_RETCODE
++establish_login(int argc, char **argv)
++{
++	extern char *optarg;
++	extern int optind;
++	COMMON_PWD options = {0};
++#if !defined(__MINGW32__) && !defined(_MSC_VER)
++	int ch;
++#endif
++
++	BASENAME = tds_basename((char *)argv[0]);
++	DIRNAME = dirname((char *)argv[0]);
++	
++#if !defined(__MINGW32__) && !defined(_MSC_VER)
++	/* process command line options (handy for manual testing) */
++	while ((ch = getopt(argc, argv, "U:P:S:D:f:m:v")) != -1) {
++		switch (ch) {
++		case 'U':
++			strcpy(options.USER, optarg);
++			break;
++		case 'P':
++			strcpy(options.PASSWORD, optarg);
++			break;
++		case 'S':
++			strcpy(options.SERVER, optarg);
++			break;
++		case 'D':
++			strcpy(options.DATABASE, optarg);
++			break;
++		case 'f': /* override default PWD file */
++			PWD = strdup(optarg);
++			break;
++		case 'm':
++			common_pwd.maxlength = strtol(optarg, NULL, 10);
++		case 'v':
++			common_pwd.fverbose = 1;
++			break;
++		case '?':
++		default:
++			fprintf(stderr, "usage:  %s [-v] [-f PWD]\n"
++					"        [-U username] [-P password]\n"
++					"        [-S servername] [-D database]\n"
++					, BASENAME);
++			exit(1);
++		}
++	}
++#endif
++	read_login_info();
++	
++	/* override PWD file with command-line options */
++	
++	if (*options.USER)
++		strcpy(USER, options.USER);
++	if (*options.PASSWORD)
++		strcpy(PASSWORD, options.PASSWORD);
++	if (*options.SERVER)
++		strcpy(SERVER, options.SERVER);
++	if (*options.DATABASE)
++		strcpy(DATABASE, options.DATABASE);
++	
++	return (*USER && *PASSWORD && *SERVER && *DATABASE)? CS_SUCCEED : CS_FAIL;
++}
++
++extern const char STD_DATETIME_FMT[];
++
++CS_RETCODE
++try_ctlogin_with_options(int argc, char **argv, CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
++{
++	CS_RETCODE ret;
++
++	if ((ret = establish_login(argc, argv)) != CS_SUCCEED) {
++		if (verbose) {
++			fprintf(stderr, "read_login_info() failed!\n");
++		}
++		return ret;
++	}
++	return continue_logging_in(ctx, conn, cmd, verbose);
++}
++
++/* old way: because I'm too lazy to change every unit test */
+ CS_RETCODE
+ try_ctlogin(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
+ {
+-CS_RETCODE ret;
+-char query[30];
+-TDSCONTEXT *tds_ctx;
++	CS_RETCODE ret;
+ 
+-	/* read login information from PWD file */
+-	ret = read_login_info();
+-	if (ret != CS_SUCCEED) {
++	if ((ret = read_login_info()) != CS_SUCCEED) {
+ 		if (verbose) {
+ 			fprintf(stderr, "read_login_info() failed!\n");
+ 		}
+ 		return ret;
+ 	}
++	return continue_logging_in(ctx, conn, cmd, verbose);
++}
++
++CS_RETCODE
++continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
++{
++	CS_RETCODE ret;
++	char query[30];
++	TDSCONTEXT *tds_ctx;
++
+ 	ret = cs_ctx_alloc(CS_VERSION_100, ctx);
+ 	if (ret != CS_SUCCEED) {
+ 		if (verbose) {
+@@ -108,6 +211,15 @@ TDSCONTEXT *tds_ctx;
+ 		}
+ 		return ret;
+ 	}
++	if ((ret = ct_callback(*ctx, NULL, CS_SET, CS_CLIENTMSG_CB, 
++			       (CS_VOID*) clientmsg_cb)) != CS_SUCCEED) {
++		fprintf(stderr, "ct_callback() failed\n");
++		return ret;
++	}
++	if ((ret = ct_callback(*ctx, NULL, CS_SET, CS_SERVERMSG_CB, servermsg_cb)) != CS_SUCCEED) {
++		fprintf(stderr, "ct_callback() failed\n");
++		return ret;
++	}
+ 	ret = ct_con_alloc(*ctx, conn);
+ 	if (ret != CS_SUCCEED) {
+ 		if (verbose) {
+@@ -263,13 +375,18 @@ CS_RETCODE
+ servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * srvmsg)
+ {
+ 	servermsg_cb_invoked++;
+-	fprintf(stderr, "\nServer Message:\n");
+-	fprintf(stderr, "number %d severity %d state %d line %d\n",
++
++	if (srvmsg->msgnumber == 5701 || srvmsg->msgnumber == 5703) {
++		fprintf(stderr, "%s\n", srvmsg->text);
++		return CS_SUCCEED;
++	}
++		
++	fprintf(stderr, "%s Message %d severity %d state %d line %d:\n",
++		srvmsg->svrnlen > 0? srvmsg->svrname : "Server", 
+ 		srvmsg->msgnumber, srvmsg->severity, srvmsg->state, srvmsg->line);
+-	fprintf(stderr, "server: %s\n", (srvmsg->svrnlen > 0)
+-		? srvmsg->svrname : "(null)");
+-	fprintf(stderr, "proc: %s\n", (srvmsg->proclen > 0)
+-		? srvmsg->proc : "(null)");
+-	fprintf(stderr, "text: %s\n", srvmsg->text);
++	if (srvmsg->proclen > 0) 
++		fprintf(stderr, "proc %s: ", srvmsg->proc);
++	fprintf(stderr, "\t\"%s\"\n", srvmsg->text);
++
+ 	return CS_SUCCEED;
+ }
+diff --git a/src/ctlib/unittests/common.h b/src/ctlib/unittests/common.h
+index 37a0185..1b0a52c 100644
+--- a/src/ctlib/unittests/common.h
++++ b/src/ctlib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.10 2004/07/21 19:28:01 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.11 2008/07/06 16:44:24 jklowden Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ extern char SERVER[512];
+@@ -17,6 +17,8 @@ typedef struct
+ 	char DATABASE[512];
+ 	char USER[512];
+ 	char PASSWORD[512];
++	char fverbose;
++	int maxlength; 
+ } COMMON_PWD;
+ extern COMMON_PWD common_pwd;
+ 
+@@ -27,7 +29,11 @@ extern int clientmsg_cb_invoked;
+ extern int servermsg_cb_invoked;
+ 
+ CS_RETCODE try_ctlogin(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose);
++CS_RETCODE try_ctlogin_with_options(int argc, char **argv, CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, 
++				    int verbose);
++
+ CS_RETCODE try_ctlogout(CS_CONTEXT * ctx, CS_CONNECTION * conn, CS_COMMAND * cmd, int verbose);
++
+ CS_RETCODE run_command(CS_COMMAND * cmd, const char *sql);
+ CS_RETCODE cslibmsg_cb(CS_CONTEXT * connection, CS_CLIENTMSG * errmsg);
+ CS_RETCODE clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
+
+commit f7b0050f2869a839641bcfc1d8d3f9c869d5b476
+Author: jklowden <jklowden>
+Date:   Sun Jul 6 17:00:32 2008 +0000
+
+    small cleanup
+
+diff --git a/src/ctlib/unittests/datafmt.c b/src/ctlib/unittests/datafmt.c
+index 4ae38b3..1dcf934 100644
+--- a/src/ctlib/unittests/datafmt.c
++++ b/src/ctlib/unittests/datafmt.c
+@@ -11,10 +11,10 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: datafmt.c,v 1.1 2008/07/06 16:38:26 jklowden Exp $";
++static char software_version[] = "$Id: datafmt.c,v 1.2 2008/07/06 17:00:32 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-/* Testing: array binding of result set */
++/* Testing: data truncation behavior of ct_fetch */
+ int
+ main(int argc, char *argv[])
+ {
+@@ -46,6 +46,7 @@ main(int argc, char *argv[])
+ 		fprintf(stderr, "Login failed\n");
+ 		return 1;
+ 	}
++	verbose += common_pwd.fverbose;
+ 
+ 	strcpy(select, "select name from systypes where datalength(name) > 2*9 order by datalength(name)");
+ 	printf("%s\n", select);
+
+commit f94d58c3751e80efe471d3fa8b8bba48db0e489a
+Author: freddy77 <freddy77>
+Date:   Mon Jul 7 11:09:40 2008 +0000
+
+    fix portability problem in ctlib
+
+diff --git a/ChangeLog b/ChangeLog
+index 478b039..d6051be 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,9 +1,13 @@
++Mon Jul 07 13:09:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/common.c: make portable to win32
++	* src/odbc/prepare_query.c: add small comment
++
+ Sun Jul  6 12:25:38 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c
+ 	* src/ctlib/unittests/common.h
+ 	- unit tests accept command-line options
+ 	* src/ctlib/unittests/datafmt.c added
+-	
++
+ Sat Jul  5 18:52:45 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cspublic.h src/ctlib/cs.c src/ctlib/ct.c
+ 	* src/ctlib/unittests/Makefile.am src/ctlib/unittests/common.c
+@@ -11,7 +15,7 @@ Sat Jul  5 18:52:45 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	- cs_convert sets output resultlen even when dest is too small. 
+ 	* src/odbc/prepare_query.c src/odbc/unittests/blob1.c
+ 	- make it compile....
+-	
++
+ Fri Jul  4 16:59:48 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h src/odbc/odbc.c
+ 	- src/odbc/prepare_query.c src/odbc/unittests/blob1.c
+@@ -379,4 +383,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2540 2008/07/06 16:44:24 jklowden Exp $
++$Id: ChangeLog,v 1.2541 2008/07/07 11:09:40 freddy77 Exp $
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index 993e2f4..20e5e21 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -24,7 +24,7 @@
+ #include "common.h"
+ #include "ctlib.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.17 2008/07/06 16:44:24 jklowden Exp $";
++static char software_version[] = "$Id: common.c,v 1.18 2008/07/07 11:09:42 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -46,6 +46,27 @@ int servermsg_cb_invoked = 0;
+ 
+ static CS_RETCODE continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose);
+ 
++#if defined(__MINGW32__) || defined(_MSC_VER)
++static char *
++tds_dirname(char* path)
++{
++	char *p, *p2;
++
++	for (p = path + strlen(path); --p > path && (*p == '/' || *p == '\\');)
++		*p = '\0';
++
++	p = strrchr(path, '/');
++	if (!p)
++		p = path;
++	p2 = strrchr(p, '\\');
++	if (p2)
++		p = p2;
++	*p = 0;
++	return path;
++}
++#define dirname tds_dirname
++
++#endif
+ 
+ CS_RETCODE
+ read_login_info(void)
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 0ff289b..2904569 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.65 2008/07/05 22:58:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.66 2008/07/07 11:09:43 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -276,6 +276,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 
+ 	switch(StrLen_or_Ind) {
+ 	case SQL_NTS:
++		/* TODO WCHAR */
+ 		len = strlen((char *) DataPtr);
+ 		break;
+ 	case SQL_NULL_DATA:
+
+commit d3f2f039b29027ea89c7d29279d122d675d29780
+Author: freddy77 <freddy77>
+Date:   Mon Jul 7 11:27:11 2008 +0000
+
+    start sqlwchar support
+
+diff --git a/ChangeLog b/ChangeLog
+index d6051be..030561a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jul 07 13:23:52 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/Makefile.am src/odbc/sql2tds.c:
++	- start wchar support
++
+ Mon Jul 07 13:09:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/common.c: make portable to win32
+ 	* src/odbc/prepare_query.c: add small comment
+@@ -383,4 +387,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2541 2008/07/07 11:09:40 freddy77 Exp $
++$Id: ChangeLog,v 1.2542 2008/07/07 11:27:11 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 5efd600..e52c366 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.105 2008/03/13 13:23:31 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.106 2008/07/07 11:27:12 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -521,6 +521,15 @@ const char *parse_const_param(const char * s, TDS_SERVER_TYPE *type);
+  */
+ SQLRETURN sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _drecord *drec_axd, TDSCOLUMN *curcol, int compute_row, const TDS_DESC* axd, unsigned int n_row);
+ 
++/*
++ * sqlwchar.c
++ */
++#if SIZEOF_SQLWCHAR != SIZEOF_WCHAR_T
++size_t sqlwcslen(const SQLWCHAR * s);
++#else
++#define sqlwcslen wcslen
++#endif
++
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility pop
+ #endif
+diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am
+index f8799da..56cecf5 100644
+--- a/src/odbc/Makefile.am
++++ b/src/odbc/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.45 2007/12/03 18:55:09 freddy77 Exp $
++# $Id: Makefile.am,v 1.46 2008/07/07 11:27:12 freddy77 Exp $
+ SUBDIRS		= unittests
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC)
+ 
+@@ -11,7 +11,7 @@ MINGW_SOURCES	=
+ endif
+ libtdsodbc_la_SOURCES=	odbc.c connectparams.c convert_tds2sql.c \
+ 	descriptor.c prepare_query.c odbc_util.c \
+-	native.c sql2tds.c error.c odbc_checks.c $(MINGW_SOURCES)
++	native.c sql2tds.c error.c odbc_checks.c sqlwchar.c $(MINGW_SOURCES)
+ if MINGW32
+ libtdsodbc_la_LIBADD=	../../win32/setup.res ../tds/libtds.la ../replacements/libreplacements.la $(ODBCINSTLIB) \
+ 	$(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 507a996..449850d 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.65 2008/01/07 21:00:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.66 2008/07/07 11:27:12 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -241,7 +241,10 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			odbc_errs_add(&stmt->errs, "HY090", NULL);
+ 			return SQL_ERROR;
+ 		}
+-		len = strlen(src);
++		if (sql_src_type == SQL_C_WCHAR)
++			len = sqlwcslen(src);
++		else
++			len = strlen(src);
+ 		break;
+ 	case SQL_DEFAULT_PARAM:
+ 	case SQL_DATA_AT_EXEC:
+@@ -254,6 +257,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			/* test for SQL_C_CHAR/SQL_C_BINARY */
+ 			switch (sql_src_type) {
+ 			case SQL_C_CHAR:
++			case SQL_C_WCHAR:
+ 			case SQL_C_BINARY:
+ 				break;
+ 			default:
+@@ -265,6 +269,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			/* dynamic length allowed only for BLOB fields */
+ 			switch (drec_ipd->sql_desc_concise_type) {
+ 			case SQL_LONGVARCHAR:
++			case SQL_WLONGVARCHAR:
+ 			case SQL_LONGVARBINARY:
+ 				break;
+ 			default:
+
+commit afa9114c3c8105f11b88deea585a964118d4b752
+Author: freddy77 <freddy77>
+Date:   Mon Jul 7 13:17:51 2008 +0000
+
+    make it works with ms odbvc
+
+diff --git a/ChangeLog b/ChangeLog
+index 030561a..0153ac1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul 07 15:16:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: make it works with MS ODBC
++
+ Mon Jul 07 13:23:52 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/Makefile.am src/odbc/sql2tds.c:
+ 	- start wchar support
+@@ -387,4 +390,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2542 2008/07/07 11:27:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2543 2008/07/07 13:17:51 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index c03bf87..6536aaf 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.5 2008/07/05 22:58:01 jklowden Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.6 2008/07/07 13:17:51 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -76,7 +76,7 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ 	char symbol[3];
+ 
+ 	for (n = 0; n < len; ++n) {
+-		sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
++		sprintf(symbol, "%2X", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
+ 		if (buf[n] != symbol[(start+n) % 2])
+ 			return 0;
+ 	}
+@@ -139,6 +139,7 @@ readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
+ 			break;
+ 		if (len > (SQLLEN) bufsize)
+ 			len = (SQLLEN) bufsize - 1;
++		len -= len % 2;
+ 		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+ 		
+ 		check =	check_hex(buf, len, 2*987 + total, 25);
+@@ -235,7 +236,7 @@ main(int argc, char **argv)
+ 					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
+ 					
+-					rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1));
++					rcode = SQLPutData(m_hstmt, p + NBYTES - 2 * (i&1), NBYTES + 2 * (i&1));
+ 
+ 					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
+
+commit 27ea737f51c619dc70378b881666996d3aaa0025
+Author: jklowden <jklowden>
+Date:   Mon Jul 7 18:28:25 2008 +0000
+
+    added -v to print instance information
+
+diff --git a/ChangeLog b/ChangeLog
+index 0153ac1..1447ca8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul  7 14:27:28 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c added -v to print instance information
++
+ Mon Jul 07 15:16:09 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: make it works with MS ODBC
+ 
+@@ -390,4 +393,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2543 2008/07/07 13:17:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2544 2008/07/07 18:28:25 jklowden Exp $
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 7a668cd..bdf86d9 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.118 2008/05/31 08:54:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.119 2008/07/07 18:28:27 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -95,12 +95,14 @@ enum
+ 	OPT_TIMER =    0x02,
+ 	OPT_NOFOOTER = 0x04,
+ 	OPT_NOHEADER = 0x08,
+-	OPT_QUIET =    0x10
++	OPT_QUIET =    0x10,
++	OPT_VERBOSE =  0x20
+ };
+ 
+ static int istty = 0;
+ static int global_opt_flags = 0;
+ #define QUIET (global_opt_flags & OPT_QUIET)
++#define VERBOSE (global_opt_flags & OPT_VERBOSE)
+ 
+ static char *opt_col_term = "\t";
+ static char *opt_row_term = "\n";
+@@ -392,7 +394,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ #endif
+ 
+ 
+-	while ((opt = getopt(argc, argv, "H:S:I:P:U:p:Co:t:r:D:")) != -1) {
++	while ((opt = getopt(argc, argv, "H:S:I:P:U:p:Co:t:r:D:v")) != -1) {
+ 		switch (opt) {
+ 		case 't':
+ 			opt_col_term = strdup(optarg);
+@@ -429,6 +431,9 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		case 'p':
+ 			port = atoi(optarg);
+ 			break;
++		case 'v':
++			global_opt_flags |= OPT_VERBOSE;
++			break;
+ 		case 'C':
+ 			settings = tds_get_compiletime_settings();
+ 			printf("%s\n%35s: %s\n%35s: %s\n%35s: %s\n%35s: %s\n%35s: %s\n%35s: %s\n%35s: %s\n%35s: %s\n%35s: %s\n",
+@@ -587,6 +592,16 @@ slurp_input_file(char *fname, char **mybuf, int *bufsz, size_t *buflen, int *lin
+ 	fclose(fp);
+ }
+ 
++static void
++print_instance_data(TDSCONNECTION *connection) 
++{
++	if (!connection)
++		return;
++	
++	if (!tds_dstr_isempty(&connection->instance_name))
++		printf("connecting to instance %s on port %d\n", tds_dstr_cstr(&connection->instance_name), connection->port);
++}
++
+ extern const char STD_DATETIME_FMT[];
+ 
+ int
+@@ -682,13 +697,17 @@ main(int argc, char **argv)
+ 	}
+ #endif
+ 	if (!connection || tds_connect(tds, connection) == TDS_FAIL) {
+-		tds_free_connection(connection);
++		if( VERBOSE ) 
++			print_instance_data(connection);
++		print_instance_data(connection);
+ 		tds_free_socket(tds);
+ 		tds_free_login(login);
+ 		tds_free_context(context);
+ 		fprintf(stderr, "There was a problem connecting to the server\n");
+ 		exit(1);
+ 	}
++	if( VERBOSE ) 
++		print_instance_data(connection);
+ 	tds_free_connection(connection);
+ 	/* give the buffer an initial size */
+ 	bufsz = 4096;
+
+commit feae33623c045bacadb0edd70b45794529c0a305
+Author: jklowden <jklowden>
+Date:   Mon Jul 7 18:40:44 2008 +0000
+
+    print instance just once
+
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index bdf86d9..874fa4f 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.119 2008/07/07 18:28:27 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.120 2008/07/07 18:40:44 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -699,7 +699,6 @@ main(int argc, char **argv)
+ 	if (!connection || tds_connect(tds, connection) == TDS_FAIL) {
+ 		if( VERBOSE ) 
+ 			print_instance_data(connection);
+-		print_instance_data(connection);
+ 		tds_free_socket(tds);
+ 		tds_free_login(login);
+ 		tds_free_context(context);
+
+commit 12b505cf075df29132819e4722262a95f2669fbd
+Author: jklowden <jklowden>
+Date:   Mon Jul 7 21:43:23 2008 +0000
+
+    link statically
+
+diff --git a/ChangeLog b/ChangeLog
+index 1447ca8..10ea178 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul  7 17:42:00 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/unittests/Makefile.am link statically
++
+ Mon Jul  7 14:27:28 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/tsql.c added -v to print instance information
+ 
+@@ -393,4 +396,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2544 2008/07/07 18:28:25 jklowden Exp $
++$Id: ChangeLog,v 1.2545 2008/07/07 21:43:23 jklowden Exp $
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index e7044c7..f9ab31f 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,4 +1,5 @@
+-# $Id: Makefile.am,v 1.26 2008/07/06 16:44:24 jklowden Exp $
++# $Id: Makefile.am,v 1.27 2008/07/07 21:43:24 jklowden Exp $
++
+ TESTS		=	t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 \
+ 			connect_fail ct_options lang_ct_param array_bind cs_diag \
+ 			get_send_data rpc_ct_param rpc_ct_setparam ct_diagclient \
+@@ -44,6 +45,5 @@ AM_LDFLAGS	=	-no-fast-install
+ else
+ AM_LDFLAGS	=	-no-install
+ endif
+-#IBS		=	../libct.la @NETWORK_LIBS@
+-LIBS		=	../.libs/libct.a @NETWORK_LIBS@
++LIBS		=	../libct.la -static @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+
+commit c07eec5a4a82e67042b54ff5376b110212f226c9
+Author: freddy77 <freddy77>
+Date:   Tue Jul 8 08:41:05 2008 +0000
+
+    make win32 compile
+
+diff --git a/ChangeLog b/ChangeLog
+index 10ea178..b310136 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 08 10:39:12 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/Makefile.am: make win32 happy
++
+ Mon Jul  7 17:42:00 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/ctlib/unittests/Makefile.am link statically
+ 
+@@ -396,4 +399,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2545 2008/07/07 21:43:23 jklowden Exp $
++$Id: ChangeLog,v 1.2546 2008/07/08 08:41:05 freddy77 Exp $
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index f9ab31f..4d177cd 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,11 +1,14 @@
+-# $Id: Makefile.am,v 1.27 2008/07/07 21:43:24 jklowden Exp $
++# $Id: Makefile.am,v 1.28 2008/07/08 08:41:06 freddy77 Exp $
+ 
+-TESTS		=	t0001 t0002 t0003 t0004 t0005 t0006 t0007 t0008 t0009 \
+-			connect_fail ct_options lang_ct_param array_bind cs_diag \
+-			get_send_data rpc_ct_param rpc_ct_setparam ct_diagclient \
+-			ct_diagserver ct_diagall cs_config cancel \
+-			blk_in blk_out ct_cursor ct_cursors \
+-			ct_dynamic blk_in2 datafmt
++TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT) t0004$(EXEEXT) \
++			t0005$(EXEEXT) t0006$(EXEEXT) t0007$(EXEEXT) t0008$(EXEEXT) \
++			t0009$(EXEEXT) connect_fail$(EXEEXT) ct_options$(EXEEXT) \
++			lang_ct_param$(EXEEXT) array_bind$(EXEEXT) cs_diag$(EXEEXT) \
++			get_send_data$(EXEEXT) rpc_ct_param$(EXEEXT) rpc_ct_setparam$(EXEEXT) \
++			ct_diagclient$(EXEEXT) ct_diagserver$(EXEEXT) ct_diagall$(EXEEXT) \
++			cs_config$(EXEEXT) cancel$(EXEEXT) blk_in$(EXEEXT) \
++			blk_out$(EXEEXT) ct_cursor$(EXEEXT) ct_cursors$(EXEEXT) \
++			ct_dynamic$(EXEEXT) blk_in2$(EXEEXT) datafmt$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+
+commit b8de0d4eaec6c9d756d7cd5a8f7c184c05ab8f5b
+Author: freddy77 <freddy77>
+Date:   Tue Jul 8 08:45:09 2008 +0000
+
+    new constants for mssql2005
+
+diff --git a/ChangeLog b/ChangeLog
+index b310136..ca2836b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 08 10:4:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: add new constants for mssql2005
++
+ Tue Jul 08 10:39:12 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/Makefile.am: make win32 happy
+ 
+@@ -399,4 +402,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2546 2008/07/08 08:41:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2547 2008/07/08 08:45:09 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index e90a226..8ac7a09 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.290 2008/07/04 21:08:39 jklowden Exp $ */
++/* $Id: tds.h,v 1.291 2008/07/08 08:45:09 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -498,6 +498,10 @@ typedef enum
+ #define SYBUNIQUE	SYBUNIQUE
+ 	SYBVARIANT = 98, 	/* 0x62 */
+ #define SYBVARIANT	SYBVARIANT
++	SYBMSUDT = 240,		/* 0xF0 */
++#define SYBMSUDT SYBMSUDT
++	SYBMSXML = 241,		/* 0xF1 */
++#define SYBMSXML SYBMSXML
+ 
+ /*
+  * Sybase only types
+
+commit aa43eeed07aca04ccb5d4fc038f9bd7002dad67e
+Author: freddy77 <freddy77>
+Date:   Tue Jul 8 08:47:08 2008 +0000
+
+    remove memory leak
+
+diff --git a/ChangeLog b/ChangeLog
+index ca2836b..0f99c29 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,4 +1,7 @@
+-Tue Jul 08 10:4:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Tue Jul 08 10:46:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/pool/stream.c: remove memory leak
++
++Tue Jul 08 10:44:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h: add new constants for mssql2005
+ 
+ Tue Jul 08 10:39:12 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+@@ -402,4 +405,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2547 2008/07/08 08:45:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2548 2008/07/08 08:47:08 freddy77 Exp $
+diff --git a/src/pool/stream.c b/src/pool/stream.c
+index 8823cd9..b9a3deb 100644
+--- a/src/pool/stream.c
++++ b/src/pool/stream.c
+@@ -40,7 +40,7 @@
+ #include "pool.h"
+ #include "tds.h"
+ 
+-TDS_RCSID(var, "$Id: stream.c,v 1.25 2007/06/19 13:31:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: stream.c,v 1.26 2008/07/08 08:47:08 freddy77 Exp $");
+ 
+ int pool_find_end_token(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int len);
+ 
+@@ -158,12 +158,23 @@ read_row(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *byte
+ 	return 1;
+ }
+ 
++static void
++free_col_struct(struct tmp_col_struct *head)
++{
++	while (head) {
++		struct tmp_col_struct *prev = head;
++		head = prev->next;
++		free(prev->column_name);
++		free(prev);
++	}
++}
++
+ static int
+ read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int *bytes_read)
+ {
+ 	TDS_SMALLINT hdrsize;
+ 	int pos = 0;
+-	int stop = 0, num_cols = 0;
++	int num_cols = 0;
+ 	int namelen;
+ 	struct tmp_col_struct *head = NULL, *cur = NULL, *prev;
+ 	int col;
+@@ -175,14 +186,17 @@ read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int
+ 		*bytes_read = maxlen;
+ 		return 0;
+ 	}
+-	/* FIX ME -- endian */
++	/* FIXME -- endian */
+ 	hdrsize = buf[1] + buf[2] * 256;
+ 	pos += 3;
+ 
+-	while (!stop) {
++	for (;;) {
+ 		prev = cur;
+ 		cur = (struct tmp_col_struct *)
+ 			malloc(sizeof(struct tmp_col_struct));
++		cur->next = NULL;
++		cur->column_name = NULL;
++
+ 		if (prev)
+ 			prev->next = cur;
+ 		if (!head)
+@@ -190,6 +204,7 @@ read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int
+ 
+ 		if (bytes_left(pmbr, buf, pos, maxlen, 1)) {
+ 			*bytes_read = maxlen;
++			free_col_struct(head);
+ 			return 0;
+ 		}
+ 		namelen = buf[pos++];
+@@ -197,19 +212,19 @@ read_col_name(TDS_POOL_MEMBER * pmbr, const unsigned char *buf, int maxlen, int
+ 
+ 		if (bytes_left(pmbr, buf, pos, maxlen, namelen)) {
+ 			*bytes_read = maxlen;
++			free_col_struct(head);
+ 			return 0;
+ 		}
+ 		cur->column_name = (char *) malloc(namelen + 1);
+ 		strncpy(cur->column_name, (char *) &buf[pos], namelen);
+ 		cur->column_name[namelen] = '\0';
+-		cur->next = NULL;
+ 
+ 		pos += namelen;
+ 
+ 		num_cols++;
+ 
+ 		if (pos >= hdrsize)
+-			stop = 1;
++			break;
+ 	}
+ 
+ 	tds_free_all_results(pmbr->tds);
+
+commit 2100ae55406b85c0b0e21d11f25bad9a1a07471e
+Author: freddy77 <freddy77>
+Date:   Tue Jul 8 08:48:38 2008 +0000
+
+    *** empty log message ***
+
+diff --git a/src/ctlib/unittests/.cvsignore b/src/ctlib/unittests/.cvsignore
+index 4682152..632b3b8 100644
+--- a/src/ctlib/unittests/.cvsignore
++++ b/src/ctlib/unittests/.cvsignore
+@@ -31,4 +31,5 @@ ct_cursor
+ ct_cursors
+ ct_dynamic
+ blk_in2
++datafmt
+ 
+
+commit 791a42722a559ea6fcd6f62de4f2d1247fee813f
+Author: jklowden <jklowden>
+Date:   Tue Jul 8 17:16:54 2008 +0000
+
+    use locally provided server name if the error message packet doesn't include one.
+
+diff --git a/ChangeLog b/ChangeLog
+index 0f99c29..128f41c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jul  8 13:02:14 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/tds/token.c
++	- use locally provided server name if the error message
++	- packet doesn't include one. 
++
+ Tue Jul 08 10:46:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/pool/stream.c: remove memory leak
+ 
+@@ -405,4 +410,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2548 2008/07/08 08:47:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2549 2008/07/08 17:16:54 jklowden Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 8ac7a09..42d9978 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.291 2008/07/08 08:45:09 freddy77 Exp $ */
++/* $Id: tds.h,v 1.292 2008/07/08 17:16:55 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -165,7 +165,7 @@ typedef struct tdsunique
+ 	TDS_UCHAR Data4[8];
+ } TDS_UNIQUE;
+ 
+-/** information on data, used by tds_datecrack */
++/** Used by tds_datecrack */
+ typedef struct tdsdaterec
+ {
+ 	TDS_INT year;	       /**< year */
+@@ -258,7 +258,7 @@ enum tds_end
+ 	, TDS_DONE_PROC 	= 0x08	/**< results are from a stored procedure */
+ 	, TDS_DONE_COUNT 	= 0x10	/**< count field in packet is valid */
+ 	, TDS_DONE_CANCELLED 	= 0x20	/**< acknowledging an attention command (usually a cancel) */
+-	, TDS_DONE_EVENT 	= 0x40	/* part of an event notification. */
++	, TDS_DONE_EVENT 	= 0x40	/*   part of an event notification. */
+ 	, TDS_DONE_SRVERROR 	= 0x100	/**< SQL server server error */
+ 	
+ 	/* after the above flags, a TDS_DONE packet has a field describing the state of the transaction */
+@@ -834,8 +834,8 @@ typedef struct tds_login
+ 	TDS_TINYINT major_version;	/* TDS version */
+ 	TDS_TINYINT minor_version;	/* TDS version */
+ 	int block_size;
+-	DSTR language;		/* ie us-english */
+-	DSTR server_charset;	/*  ie iso_1 */
++	DSTR language;			/* e.g. us-english */
++	DSTR server_charset;		/* e.g. iso_1 */
+ 	TDS_INT connect_timeout;
+ 	DSTR client_host_name;
+ 	DSTR app_name;
+@@ -866,8 +866,8 @@ typedef struct tds_connection
+ 	DSTR client_host_name;
+ 	DSTR server_host_name;
+ 	DSTR app_name;
+-	DSTR user_name;	    /**< account for login */
+-	DSTR password;	    /**< password of account login */
++	DSTR user_name;	    	/**< account for login */
++	DSTR password;	    	/**< password of account login */
+ 	DSTR library;
+ 	TDS_TINYINT bulk_copy;
+ 	TDS_TINYINT suppress_language;
+@@ -877,7 +877,7 @@ typedef struct tds_connection
+ 	unsigned char capabilities[TDS_MAX_CAPABILITY];
+ 	DSTR client_charset;
+ 
+-	DSTR ip_addr;	  /**< ip of server */
++	DSTR ip_addr;	  	/**< ip of server */
+ 	DSTR instance_name;
+ 	DSTR database;
+ 	DSTR dump_file;
+@@ -1021,7 +1021,7 @@ typedef struct tds_column
+ 	 * For example, strings in some non-C programming languages are
+ 	 * made up of a one-byte length prefix, followed by the string
+ 	 * data itself.
+-	 * If the data does not have a length prefix, set prefixlen to 0.
++	 * If the data do not have a length prefix, set prefixlen to 0.
+ 	 * Currently not very used in code, however do not remove.
+ 	 */
+ 	TDS_INT bcp_prefix_len;
+@@ -1131,7 +1131,7 @@ typedef struct tds_upd_col
+ } TDSUPDCOL;
+ 
+ typedef enum {
+-	  TDS_CURSOR_STATE_UNACTIONED = 0   /* initial value */
++	  TDS_CURSOR_STATE_UNACTIONED = 0   	/* initial value */
+ 	, TDS_CURSOR_STATE_REQUESTED = 1	/* called by ct_cursor */ 
+ 	, TDS_CURSOR_STATE_SENT = 2		/* sent to server */
+ 	, TDS_CURSOR_STATE_ACTIONED = 3		/* acknowledged by server */
+@@ -1279,45 +1279,34 @@ struct tds_authentication
+ typedef struct tds_authentication TDSAUTHENTICATION;
+ 
+ /**
+- * Hold information for a server connection
++ * Information for a server connection
+  */
+ struct tds_socket
+ {
+-	/* fixed and connect time */
+-	/** tcp socket, INVALID_SOCKET if not connected */
+-	TDS_SYS_SOCKET s;
++	TDS_SYS_SOCKET s;		/**< tcp socket, INVALID_SOCKET if not connected */
+ 	TDS_SMALLINT major_version;
+ 	TDS_SMALLINT minor_version;
+-	/** version of product (Sybase/MS and full version) */
+-	TDS_UINT product_version;
++	TDS_UINT product_version;	/**< version of product (Sybase/MS and full version) */
+ 	char *product_name;
++
+ 	unsigned char capabilities[TDS_MAX_CAPABILITY];
+ 	unsigned char broken_dates;
+ 	unsigned char option_flag2;
+-	/* in/out buffers */
+-	/** input buffer */
+-	unsigned char *in_buf;
+-	/** output buffer */
+-	unsigned char *out_buf;
+-	/** allocated input buffer */
+-	unsigned int in_buf_max;
+-	/** current position in in_buf */
+-	unsigned in_pos;
+-	/** current position in out_buf */
+-	unsigned out_pos;
+-	/** input buffer length */
+-	unsigned in_len;
+-	/* TODO remove blocksize from env and use out_len ?? */
+-/*	unsigned out_len; */
+-	/** input buffer type */
+-	unsigned char in_flag;
+-	/** output buffer type */
+-	unsigned char out_flag;
+-	/** true if current input buffer is the last one */
+-	unsigned char last_packet;
++
++	unsigned char *in_buf;		/**< input buffer */
++	unsigned char *out_buf;		/**< output buffer */
++	unsigned int in_buf_max;	/**< allocated input buffer */
++	unsigned in_pos;		/**< current position in in_buf */
++	unsigned out_pos;		/**< current position in out_buf */
++	unsigned in_len;		/**< input buffer length */
++
++	unsigned char in_flag;		/**< input buffer type */
++	unsigned char out_flag;		/**< output buffer type */
++	unsigned char last_packet;	/**< true if current input buffer is the last one */
+ 	void *parent;
++
+ 	/**
+-	 * info about current query. 
++	 * Current query information. 
+ 	 * Contains information in process, both normal and compute results.
+ 	 * This pointer shouldn't be freed; it's just an alias to another structure.
+ 	 */
+@@ -1326,22 +1315,21 @@ struct tds_socket
+ 	TDS_INT num_comp_info;
+ 	TDSCOMPUTEINFO **comp_info;
+ 	TDSPARAMINFO *param_info;
+-	TDSCURSOR *cur_cursor;	/**< cursor in use */
+-	TDSCURSOR *cursors;	/**< linked list of cursors allocated for this connection */
+-	TDS_TINYINT has_status; /**< true is ret_status is valid */
+-	TDS_INT ret_status;     /**< return status from store procedure */
++	TDSCURSOR *cur_cursor;		/**< cursor in use */
++	TDSCURSOR *cursors;		/**< linked list of cursors allocated for this connection */
++	TDS_TINYINT has_status; 	/**< true is ret_status is valid */
++	TDS_INT ret_status;     	/**< return status from store procedure */
+ 	TDS_STATE state;
+-	/** indicate we are waiting a cancel reply so discard tokens till acknowledge */
+-	volatile unsigned char in_cancel;
+-	/** rows updated/deleted/inserted/selected, TDS_NO_COUNT if not valid */
+-	TDS_INT8 rows_affected;
+-	/* timeout stuff from Jeff */
++
++	volatile 
++	unsigned char in_cancel; 	/**< indicate we are waiting a cancel reply; discard tokens till acknowledge */
++	
++	TDS_INT8 rows_affected;		/**< rows updated/deleted/inserted/selected, TDS_NO_COUNT if not valid */
+ 	TDS_INT query_timeout;
+ 	TDSENV env;
+ 
+-	/* dynamic placeholder stuff */
+-	/*@dependent@*/ TDSDYNAMIC *cur_dyn;	/**< dynamic structure in use */
+-	TDSDYNAMIC *dyns;	/**< list of dynamic allocate for this connection */
++	TDSDYNAMIC *cur_dyn;		/**< dynamic structure in use */
++	TDSDYNAMIC *dyns;		/**< list of dynamic allocate for this connection */
+ 
+ 	int emul_little_endian;
+ 	char *date_fmt;
+@@ -1349,8 +1337,7 @@ struct tds_socket
+ 	int char_conv_count;
+ 	TDSICONV **char_convs;
+ 
+-	/** config for login stuff. After login this field is NULL */
+-	TDSCONNECTION *connection;
++	TDSCONNECTION *connection;	/**< config for login stuff. After login this field is NULL */
+ 
+ 	int spid;
+ 	TDS_UCHAR collation[5];
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 445c4b1..ca99868 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.345 2008/04/23 21:36:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.346 2008/07/08 17:16:55 jklowden Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2501,6 +2501,10 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 	/* server name */
+ 	rc += tds_alloc_get_string(tds, &msg.server, tds_get_byte(tds));
+ 
++	if (!msg.server[0] && tds->connection) {
++		sprintf(msg.server, "[%s]", tds_dstr_cstr(&tds->connection->server_name));
++	}
++
+ 	/* stored proc name if available */
+ 	rc += tds_alloc_get_string(tds, &msg.proc_name, tds_get_byte(tds));
+ 
+
+commit 38e5bb5bfcc719796a8390fb87c8bd37cec716ca
+Author: jklowden <jklowden>
+Date:   Tue Jul 8 19:41:24 2008 +0000
+
+    don't dereference a NULL dbproc.
+
+diff --git a/ChangeLog b/ChangeLog
+index 128f41c..b7d7f42 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul  8 15:38:37 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c don't dereference a NULL dbproc. 
++
+ Tue Jul  8 13:02:14 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h src/tds/token.c
+ 	- use locally provided server name if the error message
+@@ -410,4 +413,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2549 2008/07/08 17:16:54 jklowden Exp $
++$Id: ChangeLog,v 1.2550 2008/07/08 19:41:24 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 76785be..0686e7c 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.326 2008/07/04 21:09:12 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.327 2008/07/08 19:41:25 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4748,7 +4748,7 @@ dbbylist(DBPROCESS * dbproc, int computeid, int *size)
+ DBBOOL
+ dbdead(DBPROCESS * dbproc)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "dbdead(%p) [%s]\n", dbproc, IS_TDSDEAD(dbproc->tds_socket)? "dead":"alive");
++	tdsdump_log(TDS_DBG_FUNC, "dbdead(%p) [%s]\n", dbproc, dbproc? IS_TDSDEAD(dbproc->tds_socket)? "dead":"alive" : "quite dead");
+ 	CHECK_PARAMETER(dbproc, SYBENULL, TRUE);
+ 
+ 	if (IS_TDSDEAD(dbproc->tds_socket))
+
+commit 8dc1142ed81ac3fe481884cc06e8bd463bc6ffd7
+Author: jklowden <jklowden>
+Date:   Wed Jul 9 09:41:07 2008 +0000
+
+    use locally provided server name correctly
+
+diff --git a/ChangeLog b/ChangeLog
+index b7d7f42..8adfbef 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jul  9 05:34:20 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/tds/token.c use locally provided server name correctly
++
+ Tue Jul  8 15:38:37 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c don't dereference a NULL dbproc. 
+ 
+@@ -413,4 +416,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2550 2008/07/08 19:41:24 jklowden Exp $
++$Id: ChangeLog,v 1.2551 2008/07/09 09:41:07 jklowden Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index ca99868..6f8e13f 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.346 2008/07/08 17:16:55 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.347 2008/07/09 09:41:10 jklowden Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2501,8 +2501,12 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 	/* server name */
+ 	rc += tds_alloc_get_string(tds, &msg.server, tds_get_byte(tds));
+ 
+-	if (!msg.server[0] && tds->connection) {
+-		sprintf(msg.server, "[%s]", tds_dstr_cstr(&tds->connection->server_name));
++	if ((!msg.server || !msg.server[0]) && tds->connection) {
++		free(msg.server);
++		if (-1 == asprintf(&msg.server, "[%s]", tds_dstr_cstr(&tds->connection->server_name))) {
++			tdsdump_log(TDS_DBG_ERROR, "out of memory (%d), %s\n", errno, strerror(errno));
++			return TDS_FAIL;
++		}
+ 	}
+ 
+ 	/* stored proc name if available */
+
+commit cd9ca33b0456f9e01feabb7281e5f674d0c2056a
+Author: jklowden <jklowden>
+Date:   Wed Jul 9 10:01:04 2008 +0000
+
+    zero freed memory
+
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 6f8e13f..e4ffcc8 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.347 2008/07/09 09:41:10 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.348 2008/07/09 10:01:04 jklowden Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2502,7 +2502,7 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 	rc += tds_alloc_get_string(tds, &msg.server, tds_get_byte(tds));
+ 
+ 	if ((!msg.server || !msg.server[0]) && tds->connection) {
+-		free(msg.server);
++		TDS_ZERO_FREE(msg.server);
+ 		if (-1 == asprintf(&msg.server, "[%s]", tds_dstr_cstr(&tds->connection->server_name))) {
+ 			tdsdump_log(TDS_DBG_ERROR, "out of memory (%d), %s\n", errno, strerror(errno));
+ 			return TDS_FAIL;
+
+commit b6dceabdfb779d3c86ac6ac36cc81d1fc3c5013a
+Author: freddy77 <freddy77>
+Date:   Fri Jul 11 09:25:56 2008 +0000
+
+    cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index 8adfbef..c6ab05f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,11 +1,14 @@
++Fri Jul 11 11:25:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: cleanup
++
+ Wed Jul  9 05:34:20 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/token.c use locally provided server name correctly
+ 
+ Tue Jul  8 15:38:37 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* src/dblib/dblib.c don't dereference a NULL dbproc. 
++	* src/dblib/dblib.c: don't dereference a NULL dbproc. 
+ 
+ Tue Jul  8 13:02:14 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* include/tds.h src/tds/token.c
++	* include/tds.h src/tds/token.c:
+ 	- use locally provided server name if the error message
+ 	- packet doesn't include one. 
+ 
+@@ -416,4 +419,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2551 2008/07/09 09:41:07 jklowden Exp $
++$Id: ChangeLog,v 1.2552 2008/07/11 09:25:56 freddy77 Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 58deec6..6fe7f1c 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.173 2008/04/23 21:36:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.174 2008/07/11 09:25:56 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -314,10 +314,7 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	int retval;
+ 	int connect_timeout = 0;
+ 	int db_selected = 0;
+-	char version[64];
+-	char *str;
+-	int len;
+-	
++
+ 	/*
+ 	 * A major version of 0 means try to guess the TDS version. 
+ 	 * We try them in an order that should work. 
+@@ -421,10 +418,6 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	memcpy(tds->capabilities, connection->capabilities, TDS_MAX_CAPABILITY);
+ 
+-	retval = tds_version(tds, version);
+-	if (!retval)
+-		version[0] = '\0';
+-
+ 	if (tds_open_socket(tds, tds_dstr_cstr(&connection->ip_addr), connection->port, connect_timeout) != TDS_SUCCEED)
+ 		return TDS_FAIL;
+ 	tds_set_state(tds, TDS_IDLE);
+@@ -447,6 +440,9 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	}
+ 
+ 	if (connection->text_size || (!db_selected && !tds_dstr_isempty(&connection->database))) {
++		char *str;
++		int len;
++
+ 		len = 64 + tds_quote_id(tds, NULL, tds_dstr_cstr(&connection->database),-1);
+ 		if ((str = (char *) malloc(len)) == NULL)
+ 			return TDS_FAIL;
+
+commit 41d3c02ab4269cde9b3f08de0971ea6a6177e446
+Author: freddy77 <freddy77>
+Date:   Fri Jul 11 09:29:17 2008 +0000
+
+    test improvements
+
+diff --git a/ChangeLog b/ChangeLog
+index c6ab05f..269213e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,4 +1,9 @@
+ Fri Jul 11 11:25:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c src/odbc/unittests/genparams.c:
++	- make some tests run even on mssql2005
++	- add initial test for NVARCHAR
++
++Fri Jul 11 11:25:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/login.c: cleanup
+ 
+ Wed Jul  9 05:34:20 EDT 2008	JK Lowden <jklowden@freetds.org>
+@@ -419,4 +424,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2552 2008/07/11 09:25:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2553 2008/07/11 09:29:17 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 640510e..12e96bb 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test various bind type */
+ 
+-static char software_version[] = "$Id: data.c,v 1.14 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.15 2008/07/11 09:29:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -102,7 +102,7 @@ main(int argc, char *argv[])
+ 	Test("TINYINT", "231", SQL_C_BINARY, "E7");
+ 	Test("SMALLINT", "4321", SQL_C_BINARY, big_endian ? "10E1" : "E110");
+ 	Test("INT", "1234567", SQL_C_BINARY, big_endian ? "0012D687" : "87D61200");
+-	if ((db_is_microsoft() && strncmp(version, "08.00.", 6) == 0)
++	if ((db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0))
+ 	    || (!db_is_microsoft() && strncmp(version, "15.00.", 6) >= 0)) {
+ 		int old_result = result;
+ 
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 96f153b..34fbfcb 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.25 2008/01/31 09:13:08 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.26 2008/07/11 09:29:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -133,7 +133,6 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	if (exec_direct) {
+ 		SQLRETURN rc;
+ 
+-		out_len = 1;
+ 		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
+ 
+ 		rc = SQLExecDirect(Statement, (SQLCHAR *) sbuf, SQL_NTS);
+@@ -145,7 +144,6 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		if (prepare_before)
+ 			CHK(SQLPrepare, (Statement, (SQLCHAR *) sbuf, SQL_NTS));
+ 
+-		out_len = 1;
+ 		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
+ 
+ 		if (!prepare_before)
+@@ -256,9 +254,10 @@ AllTests(void)
+ 	TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");
+ 
+ 	/* TODO some Sybase versions */
+-	if (db_is_microsoft() && strncmp(version, "08.00.", 6) == 0) {
++	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
+ 		Test("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
+ 	}
+ }
+ 
+
+commit 5900b4032e9b75b6d0a3340ee00590acc9a610b9
+Author: freddy77 <freddy77>
+Date:   Mon Jul 14 08:14:47 2008 +0000
+
+    minor SQLWCHAR improves
+
+diff --git a/ChangeLog b/ChangeLog
+index 269213e..29f3fd6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jul 14 10:14:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- minor SQLWCHAR improves
++
+ Fri Jul 11 11:25:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c src/odbc/unittests/genparams.c:
+ 	- make some tests run even on mssql2005
+@@ -424,4 +428,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2553 2008/07/11 09:29:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2554 2008/07/14 08:14:47 freddy77 Exp $
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 2904569..48a071d 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.66 2008/07/07 11:09:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.67 2008/07/14 08:14:48 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -245,6 +245,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	int need_bytes;
+ 	TDSCOLUMN *curcol;
+ 	TDSBLOB *blob;
++	int sql_src_type;
+ 
+ 	if (!stmt->params) {
+ 		tdsdump_log(TDS_DBG_FUNC, "error? continue_parse_prepared_query: no parameters provided");
+@@ -274,10 +275,17 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		}
+ 	}		
+ 
++	/* get C type */
++	sql_src_type = drec_apd->sql_desc_concise_type;
++	if (sql_src_type == SQL_C_DEFAULT)
++		sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
++
+ 	switch(StrLen_or_Ind) {
+ 	case SQL_NTS:
+-		/* TODO WCHAR */
+-		len = strlen((char *) DataPtr);
++		if (sql_src_type == SQL_C_WCHAR)
++			len = sqlwcslen((SQLWCHAR *) DataPtr);
++		else
++			len = strlen((char *) DataPtr);
+ 		break;
+ 	case SQL_NULL_DATA:
+ 		len = 0;
+@@ -306,24 +314,18 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	/* copy to destination */
+ 	if (blob) {
+ 		TDS_CHAR *p;
+-		int dest_type, src_type, sql_src_type, res;
++		int dest_type, src_type, res;
+ 		CONV_RESULT ores;
+ 		TDS_DBC * dbc = stmt->dbc;
+ 		void *free_ptr = NULL;
+ 		int start = 0;
+ 		SQLPOINTER extradata = NULL;
+ 		SQLLEN extralen = 0;
+-		
+ 
+ 		if (0 == (dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type))) {
+ 			odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
+ 			return SQL_ERROR;
+ 		}
+-			
+-		/* get C type */
+-		sql_src_type = drec_apd->sql_desc_concise_type;
+-		if (sql_src_type == SQL_C_DEFAULT)
+-			sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
+ 
+ 		/* test source type */
+ 		/* TODO test intervals */
+@@ -332,7 +334,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 			odbc_errs_add(&stmt->dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
+ 			return SQL_ERROR;
+ 		}
+-		
++
+ 		if (sql_src_type == SQL_C_CHAR) {
+ 			switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
+ 			case SYBBINARY:
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 449850d..6b217de 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.66 2008/07/07 11:27:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.67 2008/07/14 08:14:48 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -331,6 +331,9 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 	case SYBVARCHAR:
+ 	case XSYBCHAR:
+ 	case XSYBVARCHAR:
++	case XSYBNVARCHAR:
++	case XSYBNCHAR:
++	case SYBNVARCHAR:
+ 		ores.cc.c = (TDS_CHAR*) dest;
+ 		ores.cc.len = curcol->column_size;
+ 		res = tds_convert(dbc->env->tds_ctx, src_type, src, len, TDS_CONVERT_CHAR, &ores);
+@@ -385,9 +388,6 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 		res = tds_convert(dbc->env->tds_ctx, src_type, src, len, dest_type, (CONV_RESULT*) dest);
+ 		break;
+ 	default:
+-	case XSYBNVARCHAR:
+-	case XSYBNCHAR:
+-	case SYBNVARCHAR:
+ 	case SYBNTEXT:
+ 	case SYBVOID:
+ 	case SYBVARIANT:
+
+commit 6e183f821173c40ace8f034e430f4d9537a8a532
+Author: freddy77 <freddy77>
+Date:   Mon Jul 14 13:07:42 2008 +0000
+
+    improve test for nvarchar
+
+diff --git a/ChangeLog b/ChangeLog
+index 29f3fd6..df3edfe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul 14 15:06:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c: improve for nvarchar
++
+ Mon Jul 14 10:14:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
+ 	- minor SQLWCHAR improves
+@@ -428,4 +431,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2554 2008/07/14 08:14:47 freddy77 Exp $
++$Id: ChangeLog,v 1.2555 2008/07/14 13:07:42 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 12e96bb..5f97a73 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test various bind type */
+ 
+-static char software_version[] = "$Id: data.c,v 1.15 2008/07/11 09:29:18 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.16 2008/07/14 13:07:43 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -22,6 +22,8 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 
+ 	/* execute a select to get data as wire */
+ 	sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
++	if (strncmp(value_to_convert, "0x", 2) == 0)
++		sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
+ 	Command(Statement, sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHK(SQLFetch, (Statement));
+@@ -112,6 +114,11 @@ main(int argc, char *argv[])
+ 			if (!old_result)
+ 				result = 0;
+ 		}
++
++		/* nvarchar without extended characters */
++		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
++		/* nvarchar with extended characters */
++		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_CHAR, "4 \x83hi\xf2");
+ 	}
+ 
+ 	Test("DECIMAL", "1234.5678", SQL_C_BINARY, "120001D3040000000000000000000000000000");
+
+commit bc0a9e63bdaf111f4b1f15a6e0d4073ee5d21e76
+Author: jklowden <jklowden>
+Date:   Mon Jul 14 14:06:14 2008 +0000
+
+    added two symbols to a switch
+
+diff --git a/ChangeLog b/ChangeLog
+index df3edfe..9167726 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul 14 09:49:12 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/odbc/odbc_util.c added two symbols to a switch
++
+ Mon Jul 14 15:06:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: improve for nvarchar
+ 
+@@ -431,4 +434,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2555 2008/07/14 13:07:42 freddy77 Exp $
++$Id: ChangeLog,v 1.2556 2008/07/14 14:06:14 jklowden Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index b5e5e7c..2b87e1b 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.96 2008/01/29 09:35:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.97 2008/07/14 14:06:15 jklowden Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -361,6 +361,8 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBUINTN:
+ 	case SYBUNITEXT:
+ 	case SYBXML:
++	case SYBMSUDT:
++	case SYBMSXML:
+ 		break;
+ 	}
+ 	return SQL_UNKNOWN_TYPE;
+
+commit 2f51bcca74ed54f92ecb671da254a570bb324a1f
+Author: freddy77 <freddy77>
+Date:   Mon Jul 14 15:12:42 2008 +0000
+
+    small improves for SQLWCHAR support
+
+diff --git a/ChangeLog b/ChangeLog
+index 9167726..183fb5c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jul 14 17:09:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy src/odbc/odbc.c src/odbc/odbc_util.c:
++	- small improves for SQLWCHAR support
++
+ Mon Jul 14 09:49:12 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/odbc/odbc_util.c added two symbols to a switch
+ 
+@@ -434,4 +438,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2556 2008/07/14 14:06:14 jklowden Exp $
++$Id: ChangeLog,v 1.2557 2008/07/14 15:12:42 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index 521a55a..663dd53 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -43,6 +43,16 @@ Done handling
+ Callback when state goes to IDLE
+ Free unused cursors and dynamic and/or reuse them
+ 
++ODBC SQL_C_CHAR with wide
++-------------------------
++Check iso8859-1 for single ??
++test to review
++- data.c (char -> sql_c_char)
++- genparams.c
++- getdata.c ??
++- putdata.c ??
++- wchar.c
++
+ Other
+ -----
+ Implement some sort of fast write to network writing directly to 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 75645f2..bafb504 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.484 2008/07/04 21:08:39 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.485 2008/07/14 15:12:42 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -1232,7 +1232,7 @@ _SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQL
+ 	stmt->need_reprepare = 1;
+ 
+ 	/* TODO other types ?? handle SQL_C_DEFAULT */
+-	if (drec->sql_desc_type == SQL_C_CHAR || drec->sql_desc_type == SQL_C_BINARY)
++	if (drec->sql_desc_type == SQL_C_CHAR || drec->sql_desc_type == SQL_C_WCHAR || drec->sql_desc_type == SQL_C_BINARY)
+ 		drec->sql_desc_octet_length = cbValueMax;
+ 	drec->sql_desc_indicator_ptr = pcbValue;
+ 	drec->sql_desc_octet_length_ptr = pcbValue;
+@@ -1573,6 +1573,7 @@ SQLBindCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	/* check conversion type */
+ 	switch (fCType) {
+ 	case SQL_C_CHAR:
++	case SQL_C_WCHAR:
+ 	case SQL_C_BINARY:
+ 	case SQL_C_DEFAULT:
+ 		/* check max buffer length */
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 2b87e1b..ddebbe1 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.97 2008/07/14 14:06:15 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.98 2008/07/14 15:12:42 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -537,7 +537,13 @@ odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col)
+ 	case SQL_CHAR:
+ 	case SQL_VARCHAR:
+ 	case SQL_LONGVARCHAR:
+-		size = col->column_size;
++		size = col->on_server.column_size;
++		break;
++	/* FIXME sure ?? *2 or not ?? */
++	case SQL_WCHAR:
++	case SQL_WVARCHAR:
++	case SQL_WLONGVARCHAR:
++		size = col->on_server.column_size / 2;
+ 		break;
+ 	case SQL_BINARY:
+ 	case SQL_VARBINARY:
+@@ -618,6 +624,12 @@ odbc_sql_to_c_type_default(int sql_type)
+ 	case SQL_CHAR:
+ 	case SQL_VARCHAR:
+ 	case SQL_LONGVARCHAR:
++	/* these types map to SQL_C_CHAR for compatibility with old applications */
++#ifdef SQL_C_WCHAR
++	case SQL_WCHAR:
++	case SQL_WVARCHAR:
++	case SQL_WLONGVARCHAR:
++#endif
+ 		return SQL_C_CHAR;
+ 		/* for compatibility numeric are converted to CHAR, not to structure */
+ 	case SQL_DECIMAL:
+@@ -807,7 +819,8 @@ odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_
+ 		len = 0;
+ 		/* TODO add XML if defined */
+ 		/* FIXME, other types available */
+-		if (drec_axd->sql_desc_concise_type == SQL_C_CHAR || drec_axd->sql_desc_concise_type == SQL_C_BINARY) {
++		if (drec_axd->sql_desc_concise_type == SQL_C_CHAR || drec_axd->sql_desc_concise_type == SQL_C_WCHAR
++		    || drec_axd->sql_desc_concise_type == SQL_C_BINARY) {
+ 			len = SQL_NTS;
+ 		} else {
+ 			int type = drec_axd->sql_desc_concise_type;
+@@ -1055,6 +1068,7 @@ odbc_get_octet_len(int c_type, const struct _drecord *drec)
+ 	/* this shit is mine -- freddy77 */
+ 	switch (c_type) {
+ 	case SQL_C_CHAR:
++	case SQL_C_WCHAR:
+ 	case SQL_C_BINARY:
+ 		len = drec->sql_desc_octet_length;
+ 		break;
+
+commit 16d0e367ae8b4d7616eb3ee5fd8ec0da215a7d4c
+Author: freddy77 <freddy77>
+Date:   Tue Jul 15 09:52:16 2008 +0000
+
+    from 0.82 do all tests
+
+diff --git a/ChangeLog b/ChangeLog
+index 183fb5c..f3d0e18 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 15 11:51:59 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: from version 0.82 do all tests
++
+ Mon Jul 14 17:09:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	- small improves for SQLWCHAR support
+@@ -438,4 +441,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2557 2008/07/14 15:12:42 freddy77 Exp $
++$Id: ChangeLog,v 1.2558 2008/07/15 09:52:16 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 4ba053d..96bd004 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -215,7 +215,7 @@ upload "$OUTDIR/test2" '*.html'
+ cd ..
+ 
+ # do tests with sybase 15 server
+-if test "$OUTDIR" = "out"; then
++if test "$OUTDIR" != "out0"; then
+ 	cp -f ../PWD.sybase15 PWD
+ 	read_pwd_fields
+ 	rm -rf logs
+@@ -228,7 +228,7 @@ if test "$OUTDIR" = "out"; then
+ fi
+ 
+ # test autodiscovery
+-if test "$OUTDIR" = "out"; then
++if test "$OUTDIR" != "out0"; then
+ 	save_coverage
+ 	# using tsql directly with grep do not update coverage informations
+ 	echo -e 'select @@version\ngo\nbye' | TDSVER=0.0 ./src/apps/tsql -S "$tSRV" -U "$tUID" -P "$tPWD" > out.txt || true
+
+commit 11bf86f64705d51fcf53ff8ae83c9019456af75d
+Author: freddy77 <freddy77>
+Date:   Tue Jul 15 09:53:00 2008 +0000
+
+    remove warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index f3d0e18..cb93754 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jul 15 11:52:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/datafmt.c src/odbc/sql2tds.c:
++	* src/dblib/unittests/rpc.c:
++	- remove warnings
++
+ Tue Jul 15 11:51:59 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild: from version 0.82 do all tests
+ 
+@@ -441,4 +446,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2558 2008/07/15 09:52:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2559 2008/07/15 09:53:00 freddy77 Exp $
+diff --git a/src/ctlib/unittests/datafmt.c b/src/ctlib/unittests/datafmt.c
+index 1dcf934..473cf1b 100644
+--- a/src/ctlib/unittests/datafmt.c
++++ b/src/ctlib/unittests/datafmt.c
+@@ -11,7 +11,7 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: datafmt.c,v 1.2 2008/07/06 17:00:32 jklowden Exp $";
++static char software_version[] = "$Id: datafmt.c,v 1.3 2008/07/15 09:53:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Testing: data truncation behavior of ct_fetch */
+@@ -72,12 +72,14 @@ main(int argc, char *argv[])
+ 			break;
+ 		case CS_CMD_FAIL:
+ 			fprintf(stderr, "ct_results() result_type CS_CMD_FAIL.\n");
++			free(addr);
+ 			return 1;
+ 		case CS_ROW_RESULT:
+ 
+ 			ret = ct_res_info(cmd, CS_NUMDATA, &num_cols, CS_UNUSED, NULL);
+ 			if (ret != CS_SUCCEED) {
+ 				fprintf(stderr, "ct_res_info() failed");
++				free(addr);
+ 				return 1;
+ 			}
+ 			fprintf(stderr, "%d column%s\n", num_cols, num_cols==1? "":"s");
+@@ -85,6 +87,7 @@ main(int argc, char *argv[])
+ 			ret = ct_describe(cmd, 1, &datafmt);
+ 			if (ret != CS_SUCCEED) {
+ 				fprintf(stderr, "ct_describe() failed\n");
++				free(addr);
+ 				return 1;
+ 			}
+ 
+@@ -105,6 +108,7 @@ main(int argc, char *argv[])
+ 			ret = ct_bind(cmd, 1, &datafmt, addr, &copied, &ind);
+ 			if (ret != CS_SUCCEED) {
+ 				fprintf(stderr, "ct_bind() failed\n");
++				free(addr);
+ 				return 1;
+ 			}
+ 
+@@ -123,15 +127,19 @@ main(int argc, char *argv[])
+ 					break;
+ 				case CS_ROW_FAIL:
+ 					fprintf(stderr, "error: ct_fetch() returned CS_ROW_FAIL on row %d.\n", row_count);
++					free(addr);
+ 					return 1;
+ 				case CS_CANCELED:
+ 					fprintf(stderr, "error: ct_fetch() returned CS_CANCELED??\n");
++					free(addr);
+ 					return 1;
+ 				case CS_FAIL:
+ 					fprintf(stderr, "error: ct_fetch() returned CS_FAIL.\n");
++					free(addr);
+ 					return 1;
+ 				default:
+ 					fprintf(stderr, "error: ct_fetch() unexpected return.\n");
++					free(addr);
+ 					return 1;
+ 				}
+ 			}
+@@ -145,10 +153,12 @@ main(int argc, char *argv[])
+ 		break;
+ 	case CS_FAIL:
+ 		fprintf(stderr, "ct_results() failed.\n");
++		free(addr);
+ 		return 1;
+ 		break;
+ 	default:
+ 		fprintf(stderr, "ct_results() unexpected return.\n");
++		free(addr);
+ 		return 1;
+ 	}
+ 
+@@ -158,8 +168,10 @@ main(int argc, char *argv[])
+ 	ret = try_ctlogout(ctx, conn, cmd, verbose);
+ 	if (ret != CS_SUCCEED) {
+ 		fprintf(stderr, "Logout failed\n");
++		free(addr);
+ 		return 1;
+ 	}
+ 
++	free(addr);
+ 	return 0;
+ }
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index 82deff0..af41df7 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.33 2008/06/12 01:00:48 jklowden Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.34 2008/07/15 09:53:01 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[4096];
+@@ -124,7 +124,7 @@ ignore_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char
+ 	return erc;
+ }
+ 
+-int 
++static int 
+ colwidth( DBPROCESS * dbproc, int icol ) 
+ {
+ 	int width = dbwillconvert(dbcoltype(dbproc, icol), SYBCHAR);
+@@ -260,7 +260,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param5, 0, SYBVARCHAR, /*maxlen= */ -1, /* datalen= */ 2, &"OK:");
++	erc = dbrpcparam(dbproc, param5, 0, SYBVARCHAR, /*maxlen= */ -1, /* datalen= */ 2, (BYTE *) "OK:");
+ 	if (erc == FAIL) {
+ 		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+ 		failed = 1;
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 6b217de..e2cef12 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.67 2008/07/14 08:14:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.68 2008/07/15 09:53:00 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -242,7 +242,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			return SQL_ERROR;
+ 		}
+ 		if (sql_src_type == SQL_C_WCHAR)
+-			len = sqlwcslen(src);
++			len = sqlwcslen((const SQLWCHAR *) src);
+ 		else
+ 			len = strlen(src);
+ 		break;
+
+commit b4057d28e4ec60afb128a2e6f5219c6bcd8c21c8
+Author: freddy77 <freddy77>
+Date:   Tue Jul 15 15:14:12 2008 +0000
+
+    improved test for WCHARs
+
+diff --git a/ChangeLog b/ChangeLog
+index cb93754..5f7c7b5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 15 17:13:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: improved for WCHARs
++
+ Tue Jul 15 11:52:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/datafmt.c src/odbc/sql2tds.c:
+ 	* src/dblib/unittests/rpc.c:
+@@ -446,4 +449,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2559 2008/07/15 09:53:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2560 2008/07/15 15:14:12 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 34fbfcb..ca15a94 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.26 2008/07/11 09:29:18 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.27 2008/07/15 15:14:12 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -26,12 +26,16 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQL
+ 	SQLLEN out_len = 0;
+ 	SQL_NUMERIC_STRUCT *num;
+ 	int i;
++	const char *sep;
+ 
+ 	ResetStatement();
+ 
+ 	/* build store procedure to test */
+ 	Command(Statement, "IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
+-	sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, '%s')", type, type, value_to_convert);
++	sep = "'";
++	if (strncmp(value_to_convert, "0x", 2) == 0)
++		sep = "";
++	sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, %s%s%s)", type, type, sep, value_to_convert, sep);
+ 	Command(Statement, sbuf);
+ 	memset(out_buf, 0, sizeof(out_buf));
+ 
+@@ -77,6 +81,9 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQL
+ 		for (i = 0; i < out_len; ++i)
+ 			sprintf(strchr(sbuf, 0), "%02X", (int) out_buf[i]);
+ 		break;
++	case SQL_C_CHAR:
++		sprintf(sbuf, "%d %s", (int) out_len, out_buf);
++		break;
+ 	default:
+ 		/* not supported */
+ 		assert(0);
+@@ -99,6 +106,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	const char *expected = value_to_convert;
+ 	size_t value_len = strlen(value_to_convert);
+ 	const char *p;
++	const char *sep = "'";
+ 
+ 	ResetStatement();
+ 
+@@ -107,7 +115,9 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		value_len = p - value_to_convert;
+ 		expected = p + 4;
+ 	}
+-	sprintf(sbuf, "SELECT CONVERT(%s, '%.*s')", type, (int) value_len, value_to_convert);
++	if (value_len >= 2 && strncmp(value_to_convert, "0x", 2) == 0)
++		sep = "";
++	sprintf(sbuf, "SELECT CONVERT(%s, %s%.*s%s)", type, sep, (int) value_len, value_to_convert, sep);
+ 	Command(Statement, sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	if (!SQL_SUCCEEDED(SQLFetch(Statement)))
+@@ -156,7 +166,10 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 
+ 	/* check is row is present */
+ 	ResetStatement();
+-	sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, '%s')", param_type, expected);
++	sep = "'";
++	if (strncmp(expected, "0x", 2) == 0)
++		sep = "";
++	sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+ 	Command(Statement, sbuf);
+ 
+ 	CHK(SQLFetch, (Statement));
+@@ -253,11 +266,28 @@ AllTests(void)
+ 
+ 	TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");
+ 
++	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "1EasyTest");
++	/* TODO use collate in sintax if available */
++	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "me\xf4");
++
++	precision = 6;
++	/* output from char with conversions */
++	Test("VARCHAR(20)", "foo test", SQL_C_CHAR, SQL_VARCHAR, "6 foo te");
++	/* TODO use collate in sintax if available */
++	Test("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");
++
+ 	/* TODO some Sybase versions */
+ 	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
+ 		Test("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
++
++		precision = 12;
++		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
++		/* TODO use collate in sintax if available */
++		Test("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");
+ 	}
+ }
+ 
+
+commit 8ac7ead6685b0bdc4c7fa60f0d2788d14627bef2
+Author: freddy77 <freddy77>
+Date:   Tue Jul 15 15:20:54 2008 +0000
+
+    some code for mssql2005
+
+diff --git a/ChangeLog b/ChangeLog
+index 5f7c7b5..f14dda2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 15 17:20:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: some code for mssql2005
++
+ Tue Jul 15 17:13:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c: improved for WCHARs
+ 
+@@ -449,4 +452,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2560 2008/07/15 15:14:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2561 2008/07/15 15:20:54 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index e4ffcc8..07717c8 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.348 2008/07/09 10:01:04 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.349 2008/07/15 15:20:54 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -1437,6 +1437,11 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		break;
+ 	case 2:
+ 		curcol->column_size = tds_get_smallint(tds);
++#ifdef ENABLE_DEVELOPING
++		/* under TDS9 this means ?var???(MAX) */
++		if (curcol->column_size < 0 && IS_TDS90(tds))
++			curcol->column_size = 0x1ffffffflu;
++#endif
+ 		break;
+ 	case 1:
+ 		curcol->column_size = tds_get_byte(tds);
+@@ -1938,6 +1943,26 @@ tds_process_compute(TDSSOCKET * tds, TDS_INT * pcomputeid)
+ 	return TDS_SUCCEED;
+ }
+ 
++#ifdef ENABLE_DEVELOPING
++static int
++tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
++{
++	TDS_INT8 len = tds_get_int8(tds);
++	TDS_INT chunk_len;
++
++	/* NULL */
++	if (len == -1) {
++		curcol->column_cur_size = -1;
++		return TDS_SUCCEED;
++	}
++
++	for (;;) {
++		chunk_len = tds_get_int(tds);
++		if (chunk_len < 0)
++			return TDS_SUCCEED;
++	}
++}
++#endif
+ 
+ /**
+  * Read a data from wire
+@@ -1998,6 +2023,10 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		colsize = tds_get_int(tds);
+ 		break;
+ 	case 2:
++#ifdef ENABLE_DEVELOPING
++		if (curcol->column_size == 0x1ffffffflu)
++			return tds9_get_varmax(tds, curcol);
++#endif
+ 		colsize = tds_get_smallint(tds);
+ 		break;
+ 	case 1:
+
+commit bbb4a9cea28f2ab59038e52a88b26e3bc1376b38
+Author: freddy77 <freddy77>
+Date:   Tue Jul 15 15:25:07 2008 +0000
+
+    just a comment
+
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 867c8f5..12475c2 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.74 2008/01/17 06:56:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.75 2008/07/15 15:25:07 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -1028,6 +1028,7 @@ tds_ssl_write(BIO *b, const char* data, int len)
+ 		/* write to socket directly */
+ 		return tds_goodwrite(tds, data, len, 1);
+ 	}
++	/* write crypted data inside normal TDS packets */
+ 	tds_put_n(tds, data, len);
+ 	return len;
+ }
+
+commit 5b9aa4be10824b3b2a2516efcf50e21465dd0c9a
+Author: freddy77 <freddy77>
+Date:   Wed Jul 16 07:37:06 2008 +0000
+
+    fixed for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index f14dda2..6a8de1a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jul 16 09:36:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor6.c src/odbc/unittests/cursor7.c:
++	- fixed for Sybase
++
+ Tue Jul 15 17:20:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: some code for mssql2005
+ 
+@@ -452,4 +456,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2561 2008/07/15 15:20:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2562 2008/07/16 07:37:06 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c
+index 430788a..04a2909 100755
+--- a/src/odbc/unittests/cursor6.c
++++ b/src/odbc/unittests/cursor6.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with no binded columns */
+ 
+-static char software_version[] = "$Id: cursor6.c,v 1.1 2008/06/05 16:08:46 freddy77 Exp $";
++static char software_version[] = "$Id: cursor6.c,v 1.2 2008/07/16 07:37:07 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int bind_all = 0;
+@@ -97,17 +97,7 @@ main(int argc, char *argv[])
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE,  (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
+-	if (retcode != SQL_SUCCESS) {
+-		CHK(SQLGetDiagRec, (SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL));
+-		sqlstate[5] = 0;
+-		if (strcmp((const char*) sqlstate, "S1092") == 0) {
+-			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+-			Disconnect();
+-			exit(0);
+-		}
+-		ODBC_REPORT_ERROR("SQLSetConnectAttr");
+-	}
++	CheckCursor();
+ 
+ 	Init();
+ 
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index 9d5c096..8a2fbd7 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.3 2008/06/25 11:54:37 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.4 2008/07/16 07:37:07 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -88,17 +88,7 @@ main(int argc, char *argv[])
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
+-	if (retcode != SQL_SUCCESS) {
+-		CHK(SQLGetDiagRec, (SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL));
+-		sqlstate[5] = 0;
+-		if (strcmp((const char *) sqlstate, "S1092") == 0) {
+-			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+-			Disconnect();
+-			exit(0);
+-		}
+-		ODBC_REPORT_ERROR("SQLSetConnectAttr");
+-	}
++	CheckCursor();
+ 
+ 	Init();
+ 
+
+commit 2d5dc5abbde87a30a35708325c84c4fa45c96c86
+Author: freddy77 <freddy77>
+Date:   Wed Jul 16 07:47:02 2008 +0000
+
+    remove warnings
+
+diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c
+index 04a2909..3553852 100755
+--- a/src/odbc/unittests/cursor6.c
++++ b/src/odbc/unittests/cursor6.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with no binded columns */
+ 
+-static char software_version[] = "$Id: cursor6.c,v 1.2 2008/07/16 07:37:07 freddy77 Exp $";
++static char software_version[] = "$Id: cursor6.c,v 1.3 2008/07/16 07:47:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int bind_all = 0;
+@@ -90,10 +90,6 @@ static void Init(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	unsigned char sqlstate[6];
+-	unsigned char msg[256];
+-	SQLRETURN retcode;
+-
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index 8a2fbd7..acd58c9 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.4 2008/07/16 07:37:07 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.5 2008/07/16 07:47:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -82,9 +82,6 @@ Init(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	unsigned char sqlstate[6], msg[256];
+-	SQLRETURN retcode;
+-
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+
+commit d1b5dd83d142e9d0e849560f8b26a2827b66acd5
+Author: freddy77 <freddy77>
+Date:   Wed Jul 16 13:58:34 2008 +0000
+
+    just comments
+
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 0d54f27..128a441 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.221 2008/07/04 21:08:49 jklowden Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.222 2008/07/16 13:58:34 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -1471,7 +1471,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			s = tds_convert_string(tds, curcol->char_conv, s, colsize, &colsize);
+ 			if (!s) {
+ 				/* FIXME this is a bad place to return error... */
+-				/* TODO on memory failure we should compute comverted size and use chunks */
++				/* TODO on memory failure we should compute converted size and use chunks */
+ 				return TDS_FAIL;
+ 			}
+ 			converted = 1;
+@@ -1706,6 +1706,7 @@ tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags)
+ 	/* row data */
+ 	tds_put_byte(tds, TDS5_PARAMS_TOKEN);
+ 	for (i = 0; i < info->num_cols; i++) {
++		/* TODO check error */
+ 		tds_put_data(tds, info->columns[i]);
+ 	}
+ }
+
+commit 8d35c522265faa4ec4405eb13aa840f42518fcdc
+Author: freddy77 <freddy77>
+Date:   Thu Jul 17 05:37:43 2008 +0000
+
+    updates
+
+diff --git a/ChangeLog b/ChangeLog
+index 6a8de1a..b1d3932 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jul 17 07:37:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO: updated
++
+ Wed Jul 16 09:36:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor6.c src/odbc/unittests/cursor7.c:
+ 	- fixed for Sybase
+@@ -456,4 +459,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2562 2008/07/16 07:37:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2563 2008/07/17 05:37:43 freddy77 Exp $
+diff --git a/TODO b/TODO
+index 92f7d8a..821cd2b 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.169 2008/07/04 21:08:57 jklowden Exp $
++To Do List	$Id: TODO,v 1.170 2008/07/17 05:37:43 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -82,7 +82,7 @@ For future versions (in priority order within library):
+   for completeness). If the reader knows a library to handle named pipes
+   compatible with LGPL please tell us.
+ . read on partial packet, do not wait entire one
+-. detect if realloc/free accepts NULL pointers (in configure.in)
++. detect if realloc accepts NULL pointers (in configure.in)
+ . support for password longer than 30 characters under Sybase
+   (anybody know how ??)
+ . under Sybase using prepared statements and BLOBs we shouldn't try to
+@@ -93,6 +93,8 @@ For future versions (in priority order within library):
+   with the client's charset.  More flexibility one both sides would be good.  
+ . date/time on Sybase (from 12.5)
+ . encrypted connection for Sybase
++. new mssql2005 protocol
++. new mssql2008 types
+ 
+   db-lib
+ . add DBTEXTLIMIT (dbsetopt), PHP require it to support textlimit ini value
+@@ -136,10 +138,7 @@ For future versions (in priority order within library):
+    is however a setting which is a mssql extension which threat hidden
+    columns as normal)
+  (cfr "SQLNumResultCols() is wrong (+1)" Jan 8 2008)
+-. test: all binding types (input and output)
+ . test: descriptors work
+-  - ODBC 2 type returned (datetime)
+-  - SQLDescribeCol return ODBC 2 type or 3 or based on configuration?
+   - what happen to SQL_DESC_DATETIME_INTERVAL_CODE and SQL_DESC_CONCISE_TYPE
+     changing only SQL_DESC_TYPE (with SQLSetDescField)
+ . test: set SQL_C_DEFAULT and call SQLFetch (numeric, others)
+
+commit 975bd4e1cdb215c95523ffe7aaa9747a3d0e42cd
+Author: freddy77 <freddy77>
+Date:   Thu Jul 17 11:52:31 2008 +0000
+
+    updated due to file rename
+
+diff --git a/ChangeLog b/ChangeLog
+index b1d3932..7a7265e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jul 17 13:51:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* INSTALL INSTALL.CVS Makefile.am TODO vms/config_h.vms:
++	* win32/config.h:
++	- updated due to file rename
++
+ Thu Jul 17 07:37:28 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO: updated
+ 
+@@ -459,4 +464,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2563 2008/07/17 05:37:43 freddy77 Exp $
++$Id: ChangeLog,v 1.2564 2008/07/17 11:52:31 freddy77 Exp $
+diff --git a/INSTALL b/INSTALL
+index 77546be..0ba3c7a 100644
+--- a/INSTALL
++++ b/INSTALL
+@@ -1,4 +1,4 @@
+-$Id: INSTALL,v 1.5 2007/04/05 14:17:05 freddy77 Exp $
++$Id: INSTALL,v 1.6 2008/07/17 11:52:33 freddy77 Exp $
+ 
+ FreeTDS Installation
+ 
+@@ -44,8 +44,8 @@ diffs or instructions to the address given in the `README' so they can
+ be considered for the next release.  If at some point `config.cache'
+ contains results you don't want to keep, you may remove or edit it.
+ 
+-   The file `configure.in' is used to create `configure' by a program
+-called `autoconf'.  You only need `configure.in' if you want to change
++   The file `configure.ac' is used to create `configure' by a program
++called `autoconf'.  You only need `configure.ac' if you want to change
+ it or regenerate `configure' using a newer version of `autoconf'.
+ 
+ The simplest way to compile this package is:
+diff --git a/INSTALL.CVS b/INSTALL.CVS
+index 53d62d6..7fb6b55 100644
+--- a/INSTALL.CVS
++++ b/INSTALL.CVS
+@@ -9,7 +9,7 @@ connecting to the CVS server.  Then follow these steps:
+    installed:
+ 
+ 	automake	(GNU Automake, generates Makefile.in from Makefile.am)
+-	autoconf	(GNU Autoconf, generates configure from configure.in)
++	autoconf	(GNU Autoconf, generates configure from configure.ac)
+ 	libtool		(GNU Libtool, library creation support scripts)
+ 	make		(GNU or BSD Make.)
+ 	gcc		(GNU Compiler Collection, for C code compilation)
+@@ -62,4 +62,4 @@ the CVS tree via rsync:
+ $ rsync -av rsync://freetds.cvs.sourceforge.net/cvsroot/freetds/* .
+ 	
+ --
+-$Id: INSTALL.CVS,v 1.8 2008/01/10 22:57:39 jklowden Exp $
++$Id: INSTALL.CVS,v 1.9 2008/07/17 11:52:33 freddy77 Exp $
+diff --git a/Makefile.am b/Makefile.am
+index c1eef8c..8f1df10 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,7 +1,7 @@
+-# version $Id: Makefile.am,v 1.43 2006/03/24 21:59:51 jklowden Exp $
++# version $Id: Makefile.am,v 1.44 2008/07/17 11:52:34 freddy77 Exp $
+ 
+ ## SUBDIRS determines in which directories automake will generate a Makefile
+-## See also AC_OUTPUT in configure.in
++## See also AC_OUTPUT in configure.ac
+ 
+ SUBDIRS	=	include src doc samples win32
+ 
+diff --git a/TODO b/TODO
+index 821cd2b..984895a 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.170 2008/07/17 05:37:43 freddy77 Exp $
++To Do List	$Id: TODO,v 1.171 2008/07/17 11:52:34 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -82,7 +82,7 @@ For future versions (in priority order within library):
+   for completeness). If the reader knows a library to handle named pipes
+   compatible with LGPL please tell us.
+ . read on partial packet, do not wait entire one
+-. detect if realloc accepts NULL pointers (in configure.in)
++. detect if realloc accepts NULL pointers (in configure.ac)
+ . support for password longer than 30 characters under Sybase
+   (anybody know how ??)
+ . under Sybase using prepared statements and BLOBs we shouldn't try to
+diff --git a/vms/config_h.vms b/vms/config_h.vms
+index 945185c..6b847ab 100644
+--- a/vms/config_h.vms
++++ b/vms/config_h.vms
+@@ -1,6 +1,6 @@
+-/* $Id: config_h.vms,v 1.8 2008/05/22 03:53:18 jklowden Exp $ */
++/* $Id: config_h.vms,v 1.9 2008/07/17 11:52:35 freddy77 Exp $ */
+ 
+-/* include/config.h.in.  Generated from configure.in by autoheader.  */
++/* include/config.h.in.  Generated from configure.ac by autoheader.  */
+ /* and edited by hand for VMS */
+ 
+ #ifndef CONFIG_H_LOADED
+diff --git a/win32/config.h b/win32/config.h
+index 12f2ff0..cc63345 100644
+--- a/win32/config.h
++++ b/win32/config.h
+@@ -1,5 +1,5 @@
+ /* include/config.h.  Generated by configure.  */
+-/* include/config.h.in.  Generated from configure.in by autoheader.  */
++/* include/config.h.in.  Generated from configure.ac by autoheader.  */
+ 
+ /* Define to 1 if you need BSD_COMP defined to get FIONBIO defined. */
+ /* #undef BSD_COMP */
+
+commit e5b3c3d3842b50115d0234bc61ce4cb1fe3d8596
+Author: vorlon <vorlon>
+Date:   Sun Jul 20 01:44:20 2008 +0000
+
+    drop in a current email address for myself
+
+diff --git a/AUTHORS b/AUTHORS
+index 717d0e6..cbbc130 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -43,7 +43,7 @@ NTEXT support
+ Lothar Krauss <lkrauss@wbs-blank.de>
+ ODBC fixes
+ 
+-Steve Langasek <vorlon@netexpress.net>
++Steve Langasek <vorlon@dodds.net>
+ Off by one fixes and autoconf byte size thing. Debian package maintainer. 
+ 
+ Mark J. Lilback <mark@lilback.com>
+
+commit af36b834e953e7a523ad64b6930456fdebf0ead0
+Author: jklowden <jklowden>
+Date:   Wed Jul 23 20:07:17 2008 +0000
+
+    record error in log and remove some redundant logging of entry into static functions
+
+diff --git a/ChangeLog b/ChangeLog
+index 7a7265e..d4d4ad9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Jul 23 16:05:41 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/odbc/error.c src/odbc/odbc.c
++	- record error in log and remove some redundant logging of
++	- entry into static functions
++
+ Thu Jul 17 13:51:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* INSTALL INSTALL.CVS Makefile.am TODO vms/config_h.vms:
+ 	* win32/config.h:
+@@ -464,4 +469,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2564 2008/07/17 11:52:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2565 2008/07/23 20:07:17 jklowden Exp $
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 5606f5a..2d63dc5 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.52 2008/05/07 08:42:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.53 2008/07/23 20:07:18 jklowden Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -509,9 +509,6 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	SQLINTEGER odbc_ver = SQL_OV_ODBC2;
+ 	SQLHANDLE parent;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n", 
+-			handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+-
+ 	if (numRecord <= 0 || cbErrorMsgMax < 0)
+ 		return SQL_ERROR;
+ 
+@@ -559,6 +556,9 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 
+ 	if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
+ 		return SQL_ERROR;
++
++	tdsdump_log(TDS_DBG_FUNC, "_SQLError: \"%s\"\n", p);
++
+ 	result = odbc_set_string(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
+ 	free(p);
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index bafb504..460eaeb 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.485 2008/07/14 15:12:42 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.486 2008/07/23 20:07:18 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3998,9 +3998,6 @@ _SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEG
+ 
+ 	INIT_HSTMT;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_SQLGetStmtAttr(%p, %d, %p, %d, %p)\n", 
+-			hstmt, (int)Attribute, Value, (int)BufferLength, StringLength);
+-
+ 	/* TODO assign directly, use macro for size */
+ 	switch (Attribute) {
+ 	case SQL_ATTR_APP_PARAM_DESC:
+
+commit ac90403ec10d2607336373d7c6a177a7f17e7144
+Author: jklowden <jklowden>
+Date:   Wed Jul 23 20:11:33 2008 +0000
+
+    simplify log message
+
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 2d63dc5..903ae56 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.53 2008/07/23 20:07:18 jklowden Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.54 2008/07/23 20:11:33 jklowden Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -554,11 +554,11 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 
+ 	msg = errs->errs[numRecord].msg;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_SQLError: \"%s\"\n", msg);
++
+ 	if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
+ 		return SQL_ERROR;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_SQLError: \"%s\"\n", p);
+-
+ 	result = odbc_set_string(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
+ 	free(p);
+ 
+
+commit 7a6e54402a9f3642072c0db9b526a65cae1325b9
+Author: jklowden <jklowden>
+Date:   Wed Jul 23 20:20:37 2008 +0000
+
+    log when message is added, too
+
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 903ae56..bc844f1 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.54 2008/07/23 20:11:33 jklowden Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.55 2008/07/23 20:20:37 jklowden Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -405,6 +405,8 @@ odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
+ 	errs->errs[n].server = strdup("DRIVER");
+ 	errs->errs[n].msg = msg ? strdup(msg) : odbc_get_msg(errs->errs[n].state3);
+ 	++errs->num_errors;
++
++	tdsdump_log(TDS_DBG_FUNC, "odbc_errs_add: \"%s\"\n", errs->errs[n].msg);
+ }
+ 
+ /* TODO check if TDS_UINT is correct for native error */
+
+commit 7cbc7fb6506f913735f7c68d522bf26016607e1b
+Author: jklowden <jklowden>
+Date:   Thu Jul 24 22:04:49 2008 +0000
+
+    test parameter binding with SQL_LONGVARCHAR
+
+diff --git a/ChangeLog b/ChangeLog
+index d4d4ad9..b538776 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jul 24 18:02:52 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* samples/odbc_rpc.pl
++	* src/odbc/odbc.c src/odbc/prepare_query.c src/tds/net.c
++	- test parameter binding with SQL_LONGVARCHAR
++
+ Wed Jul 23 16:05:41 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/odbc/error.c src/odbc/odbc.c
+ 	- record error in log and remove some redundant logging of
+@@ -469,4 +474,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2565 2008/07/23 20:07:17 jklowden Exp $
++$Id: ChangeLog,v 1.2566 2008/07/24 22:04:49 jklowden Exp $
+diff --git a/samples/odbc_rpc.pl b/samples/odbc_rpc.pl
+index cc93942..78b309e 100755
+--- a/samples/odbc_rpc.pl
++++ b/samples/odbc_rpc.pl
+@@ -1,5 +1,5 @@
+ #!/usr/local/bin/perl
+-# $Id: odbc_rpc.pl,v 1.7 2006/07/27 19:24:42 jklowden Exp $
++# $Id: odbc_rpc.pl,v 1.8 2008/07/24 22:04:49 jklowden Exp $
+ #
+ # Contributed by James K. Lowden and is hereby placed in 
+ # the public domain.  No rights reserved.  
+@@ -48,7 +48,16 @@ sub setup_error_handler($)
+ 
+ $program = basename($0);
+ 
+-Getopt::Std::getopts('U:P:D:d:h', \%opts);
++Getopt::Std::getopts('U:P:D:d:hlv', \%opts);
++
++if( $opts{l} ) {
++	foreach (@{ $DBI::EXPORT_TAGS{sql_types} }) {
++	      printf "%s=%d\n", $_, &{"DBI::$_"};
++	}
++	exit 0;
++}
++
++open VERBOSE, $opts{v}? '>&STDERR' : '>/dev/null' or die;
+ 
+ my ($dsn, $user, $pass, $database);
+ $dsn  = $opts{D}? $opts{D} : "dbi:ODBC:JDBC";
+@@ -70,7 +79,7 @@ my $placeholders = '';
+ if( @ARGV > 1 ) {
+ 	my @placeholders = ('?') x (@ARGV - 1); 
+ 	$placeholders = '(' . join( q(, ),  @placeholders ) . ')';
+-	printf STDERR qq(%d arguments found for procedure "$ARGV[0]"\n), scalar(@placeholders);
++	printf VERBOSE qq(%d arguments found for procedure "$ARGV[0]"\n), scalar(@placeholders);
+ }
+ 
+ # Ready the odbc call
+@@ -79,7 +88,7 @@ my $sth = $dbh->prepare( $sql );
+ 
+ # Bind the return code as "inout".
+ my $rc;
+-print STDERR qq(Binding parameter #1, the return code\n);
++print VERBOSE qq(Binding parameter #1, the return code\n);
+ $sth->bind_param_inout(1, \$rc, SQL_INTEGER);
+ 
+ # Bind the input parameters (we don't do outputs in this example).
+@@ -90,22 +99,31 @@ for( my $i=1; $i < @ARGV; $i++ ) {
+     my $typename = 'SQL_VARCHAR';
+     my $data = $ARGV[$i];
+     if( $data =~ /^:([[:upper:]_]+):(.+)/ ) { # parse out the datatype, if any
+-	$typename = $1;
+-	$data = $2;
++    	$ARGV[$i] = $2;
++    	if( $1 eq 'FILE' ) {
++		$typename = 'SQL_LONGVARCHAR';
++		open INPUT, $2 or die qq(could not open "$2"\n);
++		my @data = <INPUT> or die qq(error reading "$2"\n);
++		$data = join '', @data;
++		close INPUT;
++	} else {
++		$typename = $1;
++		$data = $2;
++	}
+         $type = eval($typename);
+ 	warn qq("$typename" will probably cause a "can't rebind parameter" message\n) 
+ 		if $type == SQL_DATETIME;
+     }
+-    printf STDERR qq(Binding parameter #%d (%s): "$data"\n), ($i+1), $typename;
++    printf VERBOSE qq(Binding parameter #%d (%s): "$data"\n), ($i+1), $typename;
+     $sth->bind_param( 1 + $i, $data, $type );
+ }
+ 
+-print STDERR qq(\nExecuting: "$sth->{Statement}" with parameters '), 
++print STDOUT qq(\nExecuting: "$sth->{Statement}" with parameters '), 
+ 	     join(q(', '), @ARGV[1..$#ARGV]), qq('\n);
+ 
+ # Execute the SQL and print the (possibly several) results
+ $rc = $sth->execute;
+-print STDERR qq(execute returned: '$rc'\n) if $rc;
++print STDOUT qq(execute returned: '$rc'\n) if $rc;
+ 
+ $i = 1;
+ while ( $sth->{Active} ) { 
+@@ -121,3 +139,40 @@ $dbh->disconnect();
+ 
+ exit 0;
+ 
++
++__END__
++
++=head1 NAME
++
++odbc_rpc - execute a stored procedure via DBD::ODBC
++
++=head1 SYNOPSIS
++
++odbc_rpc [-D dsn] [-U username] [-P password] I<procedure> [arg1[, argn]]
++odbc_rpc -l 
++
++=head1 DESCRIPTION
++
++Execute I<procedure> with zero or more arguments.  Arguments are assumed to be bound to 
++SQL_VARCHAR.  To use other bindings -- which might or might not work -- prefix the value with 
++:SQL_type: where type is a valid binding type.  For a list of recognized types, use "odbc_rpc -l". 
++
++To populate your parameter from a file instead of inline, use the form :FILE:filename.  odbc_rpc will
++open I<filename> and pass its contents as data.  
++
++
++=head1 EXAMPLE
++
++  odbc_rpc -D dbi:ODBC:mpquant -d testdb -U $U -P $P \
++  	   xmltest :FILE:samples/data.xml
++
++=head1 BUGS
++
++There is no way in DBD::ODBC to pass "long data".  The contents of the file must fit in memory. 
++
++
++=head1 Author
++
++Contributed to the FreeTDS project by James K. Lowden.  
++
++=cut
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 460eaeb..d86f3d9 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.486 2008/07/23 20:07:18 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.487 2008/07/24 22:04:50 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -5927,20 +5927,21 @@ SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
+ {
+ 	INIT_HSTMT;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "SQLParamData(%p, %p)\n", 
+-			hstmt, prgbValue);
++	tdsdump_log(TDS_DBG_FUNC, "SQLParamData(%p, %p) [param_num %d, param_data_called = %d]\n", 
++					hstmt, prgbValue, stmt->param_num, stmt->param_data_called);
+ 
+ 	if (stmt->params && stmt->param_num <= stmt->param_count) {
+ 		SQLRETURN res;
+ 
+ 		if (stmt->param_num <= 0 || stmt->param_num > stmt->apd->header.sql_desc_count) {
+-			/* TODO what error ?? */
++			tdsdump_log(TDS_DBG_FUNC, "SQLParamData: logic_error: parameter out of bounds: 0 <= %d < %d\n", 
++						   stmt->param_num, stmt->apd->header.sql_desc_count);
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 		}
+ 
+ 		/*
+ 		 * TODO compute output value with this formula:
+-		 * Bound Address + Binding Offset + ((Row Number – 1) x Element Size)
++		 * Bound Address + Binding Offset + ((Row Number - 1) x Element Size)
+ 		 * (see SQLParamData documentation)
+ 		 * This is needed for updates using SQLBulkOperation (not currently supported)
+ 		 */
+@@ -5978,6 +5979,7 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 	}
+ 
+ 	/* TODO return correct error */
++	tdsdump_log(TDS_DBG_FUNC, "SQLPutData: returning SQL_ERROR\n");
+ 	ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ 
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 48a071d..02200d9 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.67 2008/07/14 08:14:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.68 2008/07/24 22:04:50 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -199,10 +199,15 @@ parse_prepared_query(struct _hstmt *stmt, int compute_row)
+ 	if (stmt->prepared_pos)
+ 		return prepared_rpc(stmt, compute_row);
+ 
++	tdsdump_log(TDS_DBG_FUNC, "parsing %d parameters\n", nparam);
++
+ 	for (; stmt->param_num <= stmt->param_count; ++nparam, ++stmt->param_num) {
+-		/* find binded parameter */
++		/* find bound parameter */
+ 		if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) {
+-			/* TODO set error */
++			tdsdump_log(TDS_DBG_FUNC, "parse_prepared_query: logic_error: parameter out of bounds: "
++						  "%d > %d || %d > %d\n", 
++						   stmt->param_num, stmt->apd->header.sql_desc_count, 
++						   stmt->param_num, stmt->ipd->header.sql_desc_count);
+ 			return SQL_ERROR;
+ 		}
+ 
+@@ -246,6 +251,10 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	TDSCOLUMN *curcol;
+ 	TDSBLOB *blob;
+ 	int sql_src_type;
++	
++	assert(stmt);
++	
++	tdsdump_log(TDS_DBG_FUNC, "continue_parse_prepared_query with parameter %d\n", stmt->param_num);
+ 
+ 	if (!stmt->params) {
+ 		tdsdump_log(TDS_DBG_FUNC, "error? continue_parse_prepared_query: no parameters provided");
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 12475c2..14d38a6 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.75 2008/07/15 15:25:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.76 2008/07/24 22:04:50 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -459,15 +459,14 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ /**
+  * Loops until we have received buflen characters
+  * return -1 on failure
+- * This function does not close the socket.  Maybe it should.  
+  */
+ static int
+ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfinished)
+ {
+ 	int rc, got = 0;
+ 
+-	if (buf == NULL || buflen < 1 || tds == NULL)
+-		return 0;
++	if (tds == NULL || buf == NULL || buflen < 1)
++		return -1;
+ 
+ 	for (;;) {
+ 		int len;
+
+commit 48d323d75bbbd558f4845a91aa80c88cdb59736c
+Author: jklowden <jklowden>
+Date:   Mon Jul 28 20:58:19 2008 +0000
+
+    tracking down SQLParamData behavior
+
+diff --git a/ChangeLog b/ChangeLog
+index b538776..3735d9d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jul 28 16:56:36 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* samples/odbc_rpc.pl src/odbc/error.c src/odbc/odbc.c
++	- tracking down SQLParamData behavior 
++
+ Thu Jul 24 18:02:52 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* samples/odbc_rpc.pl
+ 	* src/odbc/odbc.c src/odbc/prepare_query.c src/tds/net.c
+@@ -474,4 +478,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2566 2008/07/24 22:04:49 jklowden Exp $
++$Id: ChangeLog,v 1.2567 2008/07/28 20:58:19 jklowden Exp $
+diff --git a/samples/odbc_rpc.pl b/samples/odbc_rpc.pl
+index 78b309e..9e4cf2c 100755
+--- a/samples/odbc_rpc.pl
++++ b/samples/odbc_rpc.pl
+@@ -1,5 +1,5 @@
+ #!/usr/local/bin/perl
+-# $Id: odbc_rpc.pl,v 1.8 2008/07/24 22:04:49 jklowden Exp $
++# $Id: odbc_rpc.pl,v 1.9 2008/07/28 20:58:19 jklowden Exp $
+ #
+ # Contributed by James K. Lowden and is hereby placed in 
+ # the public domain.  No rights reserved.  
+@@ -42,7 +42,7 @@ sub setup_error_handler($)
+ { my ($dbh) = @_;
+ 
+ 	$dbh->{odbc_err_handler} = \&err_handler;
+-	$dbh->{odbc_async_exec} = 1;
++	#dbh->{odbc_async_exec} = 1;
+ 	print "odbc_async_exec is: $dbh->{odbc_async_exec}\n";
+ }
+ 
+@@ -68,7 +68,7 @@ die qq(Syntax: \t$program [-D dsn] [-U username] [-P password] procedure [arg1[,
+ 	if( $opts{h} || 0 == @ARGV );
+ 
+ # Connect
+-my $dbh = DBI->connect($dsn, $user, $pass, {RaiseError => 0, PrintError => 1, AutoCommit => 1})
++my $dbh = DBI->connect($dsn, $user, $pass, {RaiseError => 1, PrintError => 1, AutoCommit => 1})
+ 	or die "Unable for connect to $dsn $DBI::errstr";
+ 
+ setup_error_handler($dbh);
+@@ -115,7 +115,7 @@ for( my $i=1; $i < @ARGV; $i++ ) {
+ 		if $type == SQL_DATETIME;
+     }
+     printf VERBOSE qq(Binding parameter #%d (%s): "$data"\n), ($i+1), $typename;
+-    $sth->bind_param( 1 + $i, $data, $type );
++    $sth->bind_param( 1 + $i, $data, $type ) or die $sth->errstr;
+ }
+ 
+ print STDOUT qq(\nExecuting: "$sth->{Statement}" with parameters '), 
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index bc844f1..29cb953 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.55 2008/07/23 20:20:37 jklowden Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.56 2008/07/28 20:58:19 jklowden Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -608,9 +608,16 @@ SQLRETURN ODBC_API
+ SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState,
+ 	      SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
+ {
++	SQLRETURN ret;
++	
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n", 
+ 			handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+-	return _SQLGetDiagRec(handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
++	
++	ret =_SQLGetDiagRec(handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
++	
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec returning %d\n", ret);
++	
++	return ret;
+ }
+ 
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index d86f3d9..d4d5e1d 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.487 2008/07/24 22:04:50 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.488 2008/07/28 20:58:19 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -154,6 +154,28 @@ static void odbc_ird_check(TDS_STMT * stmt);
+  * Bah!
+  */
+ 
++static char *
++odbc_prret(SQLRETURN ret)
++{
++	static char unknown[32];
++	
++	switch (ret) {
++	case SQL_NULL_DATA:		return "SQL_ERROR or SQL_NULL_DATA";
++	case SQL_DATA_AT_EXEC:		return "SQL_DATA_AT_EXEC or SQL_INVALID_HANDLE";
++	case SQL_SUCCESS:		return "SQL_SUCCESS";
++	case SQL_SUCCESS_WITH_INFO:	return "SQL_SUCCESS_WITH_INFO";
++#if ODBCVER >= 0x0300
++	case SQL_NO_DATA:		return "SQL_NO_DATA";
++#endif
++	case SQL_STILL_EXECUTING:	return "SQL_STILL_EXECUTING";
++	case SQL_NEED_DATA:		return "SQL_NEED_DATA";
++	}
++	
++	snprintf(unknown, sizeof(unknown), "unknown: %d", (int)ret);
++
++	return unknown;
++}
++
+ static void
+ odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name)
+ {
+@@ -3293,26 +3315,32 @@ SQLExecute(SQLHSTMT hstmt)
+ 
+ 	INIT_HSTMT;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "SQLExecute(%p)\n", 
+-			hstmt);
++	tdsdump_log(TDS_DBG_FUNC, "SQLExecute(%p)\n", hstmt);
+ 
+-	if (!stmt->prepared_query)
++	if (!stmt->prepared_query) {
+ 		/* TODO error report, only without DM ?? */
++		tdsdump_log(TDS_DBG_FUNC, "SQLExecute returns SQL_ERROR (not prepared)\n");
+ 		ODBC_RETURN(stmt, SQL_ERROR);
++	}
+ 
+-	/* TODO rebuild should be done for every bingings change, not every time */
++	/* TODO rebuild should be done for every bindings change, not every time */
+ 	/* TODO free previous parameters */
+ 	/* build parameters list */
+ 	stmt->param_data_called = 0;
+ 	stmt->curr_param_row = 0;
+-	res = start_parse_prepared_query(stmt, 1);
+-	if (SQL_SUCCESS != res)
++	if ((res = start_parse_prepared_query(stmt, 1)) != SQL_SUCCESS) {
++		tdsdump_log(TDS_DBG_FUNC, "SQLExecute returns %s (start_parse_prepared_query failed)\n", odbc_prret(res));
+ 		ODBC_RETURN(stmt, res);
++	}
+ 
+ 	/* TODO test if two SQLPrepare on a statement */
+ 	/* TODO test unprepare on statement free or connection close */
+ 
+-	return _SQLExecute(stmt);
++	res = _SQLExecute(stmt);
++
++	tdsdump_log(TDS_DBG_FUNC, "SQLExecute returns %s\n", odbc_prret(res));
++
++	return res;
+ }
+ 
+ static int
+@@ -5922,8 +5950,8 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 	ODBC_RETURN(stmt, res);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
++static SQLRETURN 
++_SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
+ {
+ 	INIT_HSTMT;
+ 
+@@ -5966,6 +5994,16 @@ SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
+ }
+ 
+ SQLRETURN ODBC_API
++SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
++{
++	SQLRETURN ret = _SQLParamData(hstmt, prgbValue);
++	
++	tdsdump_log(TDS_DBG_FUNC, "SQLParamData returns %s\n", odbc_prret(ret));
++	
++	return ret;
++}
++
++SQLRETURN ODBC_API
+ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ {
+ 	INIT_HSTMT;
+@@ -5973,13 +6011,18 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLPutData(%p, %p, %i)\n", hstmt, rgbValue, (int)cbValue);
+ 
+ 	if (stmt->prepared_query || stmt->prepared_query_is_rpc) {
++		SQLRETURN ret;
++		const TDSCOLUMN *curcol = stmt->params->columns[stmt->param_num - (stmt->prepared_query_is_func ? 2 : 1)];
+ 		/* TODO do some more tests before setting this flag */
+-		stmt->param_data_called = 1;
+-		ODBC_RETURN(stmt, continue_parse_prepared_query(stmt, rgbValue, cbValue));
++		stmt->param_data_called = curcol->column_size == curcol->column_cur_size;
++		ret = continue_parse_prepared_query(stmt, rgbValue, cbValue);
++		tdsdump_log(TDS_DBG_FUNC, "SQLPutData returns %s, %d bytes left\n", 
++					  odbc_prret(ret), curcol->column_size - curcol->column_cur_size);
++		ODBC_RETURN(stmt, ret);
+ 	}
+ 
+-	/* TODO return correct error */
+-	tdsdump_log(TDS_DBG_FUNC, "SQLPutData: returning SQL_ERROR\n");
++	odbc_errs_add(&stmt->errs, "HY010", NULL);
++	tdsdump_log(TDS_DBG_FUNC, "SQLPutData returns SQL_ERROR (function sequence error)\n");
+ 	ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ 
+
+commit 79787d5ead314b3434a6fcd00ec898e3b27eca3f
+Author: jklowden <jklowden>
+Date:   Tue Jul 29 14:07:09 2008 +0000
+
+    patch from ML on 29 July 2008 from Andrew Victor  re BLOBs as parameters
+
+diff --git a/ChangeLog b/ChangeLog
+index 3735d9d..320f437 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jul 29 09:54:23 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/ct.c 
++	- patch from ML on 29 July 2008 from Andrew Victor 
++	- re BLOBs as parameters
++
+ Mon Jul 28 16:56:36 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* samples/odbc_rpc.pl src/odbc/error.c src/odbc/odbc.c
+ 	- tracking down SQLParamData behavior 
+@@ -478,4 +483,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2567 2008/07/28 20:58:19 jklowden Exp $
++$Id: ChangeLog,v 1.2568 2008/07/29 14:07:09 jklowden Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 2362777..2dcfb42 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.180 2008/07/05 22:57:54 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.181 2008/07/29 14:07:09 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -3851,11 +3851,22 @@ paramrowalloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *va
+ 
+ 	if (size > 0 && value) {
+ 		/* TODO check for BLOB and numeric */
+-		if (size > curcol->column_size)
++		if (size > curcol->column_size) {
++			tdsdump_log(TDS_DBG_FUNC, "paramrowalloc(): RESIZE %d to %d\n", size, curcol->column_size);
+ 			size = curcol->column_size;
++		}
+ 		/* TODO blobs */
+ 		if (!is_blob_type(curcol->column_type))
+ 			memcpy(curcol->column_data, value, size);
++		else {
++			TDSBLOB *blob = (TDSBLOB *) curcol->column_data;
++			blob->textvalue = malloc(size);
++			tdsdump_log(TDS_DBG_FUNC, "blob parameter supported, size %d textvalue pointer is %p\n",
++					size, blob->textvalue);
++			if (!blob->textvalue)
++				return NULL;
++			memcpy(blob->textvalue, value, size);
++		}
+ 		curcol->column_cur_size = size;
+ 	} else {
+ 		tdsdump_log(TDS_DBG_FUNC, "paramrowalloc(): setting parameter #%d to NULL\n", param_num);
+
+commit 60276e18f8b9bbf0bf991a32a87c2b1cd3f67cb1
+Author: freddy77 <freddy77>
+Date:   Wed Jul 30 08:02:53 2008 +0000
+
+    added needed hmac code for NTLMv2
+
+diff --git a/ChangeLog b/ChangeLog
+index 320f437..7526dd6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,19 +1,24 @@
++Wed Jul 30 10:01:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/hmac_md5.h(added) src/tds/hmac_md5.c(added):
++	* src/tds/Makefile.am:
++	- added needed hmac code for NTLMv2
++
+ Tue Jul 29 09:54:23 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* src/ctlib/ct.c 
++	* src/ctlib/ct.c:
+ 	- patch from ML on 29 July 2008 from Andrew Victor 
+ 	- re BLOBs as parameters
+ 
+ Mon Jul 28 16:56:36 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* samples/odbc_rpc.pl src/odbc/error.c src/odbc/odbc.c
++	* samples/odbc_rpc.pl src/odbc/error.c src/odbc/odbc.c:
+ 	- tracking down SQLParamData behavior 
+ 
+ Thu Jul 24 18:02:52 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* samples/odbc_rpc.pl
+-	* src/odbc/odbc.c src/odbc/prepare_query.c src/tds/net.c
++	* samples/odbc_rpc.pl:
++	* src/odbc/odbc.c src/odbc/prepare_query.c src/tds/net.c:
+ 	- test parameter binding with SQL_LONGVARCHAR
+ 
+ Wed Jul 23 16:05:41 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* src/odbc/error.c src/odbc/odbc.c
++	* src/odbc/error.c src/odbc/odbc.c:
+ 	- record error in log and remove some redundant logging of
+ 	- entry into static functions
+ 
+@@ -483,4 +488,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2568 2008/07/29 14:07:09 jklowden Exp $
++$Id: ChangeLog,v 1.2569 2008/07/30 08:02:53 freddy77 Exp $
+diff --git a/include/hmac_md5.h b/include/hmac_md5.h
+new file mode 100644
+index 0000000..e06c778
+--- /dev/null
++++ b/include/hmac_md5.h
+@@ -0,0 +1,29 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2008 Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#ifndef _hmac_md5_h_
++#define _hmac_md5_h_
++
++/* $Id: hmac_md5.h,v 1.1 2008/07/30 08:02:54 freddy77 Exp $ */
++
++void hmac_md5(const unsigned char key[16],
++              const unsigned char* data, size_t data_len,
++              unsigned char* digest);
++
++#endif
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index f609bb6..be636b9 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.63 2007/10/30 15:51:06 freddy77 Exp $
++# $Id: Makefile.am,v 1.64 2008/07/30 08:02:55 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -9,7 +9,7 @@ libtds_la_SOURCES=	mem.c token.c util.c login.c read.c \
+ 	locale.c challenge.c threadsafe.c vstrbuild.c md4.c md5.c \
+ 	des.c tdsstring.c getmac.c data.c net.c \
+ 	tds_checks.c tds_checks.h enum_cap.h log.c \
+-	gssapi.c
++	gssapi.c hmac_md5.c
+ libtds_la_LDFLAGS=
+ libtds_la_LIBADD=
+ 
+diff --git a/src/tds/hmac_md5.c b/src/tds/hmac_md5.c
+new file mode 100644
+index 0000000..f6e86e5
+--- /dev/null
++++ b/src/tds/hmac_md5.c
+@@ -0,0 +1,64 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2008  Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/* $Id: hmac_md5.c,v 1.1 2008/07/30 08:02:55 freddy77 Exp $ */
++
++#include "tds.h"
++#include "md5.h"
++#include "hmac_md5.h"
++#include <memory.h>
++
++/**
++ * Calculates the HMAC-MD5 hash of the given data using the specified
++ * hashing key.
++ *
++ * @param key      The hashing key.
++ * @param data     The data for which the hash will be calculated. 
++ * @param data_len data length. 
++ * @param digest   The HMAC-MD5 hash of the given data.
++ */
++void hmac_md5(const unsigned char key[16],
++              const unsigned char* data, size_t data_len,
++              unsigned char* digest)
++{
++	int i;
++	MD5_CTX ctx;
++	unsigned char k_ipad[64];
++	unsigned char k_opad[64];
++
++	/* compute ipad and opad */
++	memset(k_ipad, 0x36, sizeof(k_ipad));
++	memset(k_opad, 0x5c, sizeof(k_opad));
++	for (i=0; i<16; ++i) {
++		k_ipad[i] ^= key[i];
++		k_opad[i] ^= key[i];
++	}
++
++	MD5Init(&ctx);
++	MD5Update(&ctx, k_ipad, 64);
++	if (data_len != 0)
++		MD5Update(&ctx, data, data_len);
++	MD5Final(&ctx, digest);
++
++	MD5Init(&ctx);
++	MD5Update(&ctx, k_opad, 64);
++	MD5Update(&ctx, digest, 16);
++	MD5Final(&ctx, digest);
++}
++
+
+commit 8681ca744b263f0c6093863a74fe91416d54d952
+Author: freddy77 <freddy77>
+Date:   Wed Jul 30 08:06:11 2008 +0000
+
+    add missing header for hmac
+
+diff --git a/ChangeLog b/ChangeLog
+index 7526dd6..5a3502a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jul 30 10:05:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/Makefile.am: add missing header for hmac
++
+ Wed Jul 30 10:01:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/hmac_md5.h(added) src/tds/hmac_md5.c(added):
+ 	* src/tds/Makefile.am:
+@@ -488,4 +491,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2569 2008/07/30 08:02:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2570 2008/07/30 08:06:11 freddy77 Exp $
+diff --git a/include/Makefile.am b/include/Makefile.am
+index c257cf9..e28fa70 100644
+--- a/include/Makefile.am
++++ b/include/Makefile.am
+@@ -9,7 +9,7 @@ nodist_include_HEADERS	=	tds_sysdep_public.h
+ 
+ noinst_HEADERS	=	tds_configs.h \
+ 			tds_sysdep_private.h \
+-			md4.h md5.h des.h \
++			md4.h md5.h des.h hmac_md5.h \
+ 			replacements.h \
+ 			tdsstring.h \
+ 			tdsodbc.h \
+
+commit 452a0e059bd73c9da55f911d99c9a96697875b28
+Author: freddy77 <freddy77>
+Date:   Wed Jul 30 14:38:07 2008 +0000
+
+    merged patch #2031829 about NTLMv2
+
+diff --git a/ChangeLog b/ChangeLog
+index 5a3502a..4ee69bb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jul 30 16:36:52 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/challenge.c:
++	- merged patch #2031829 about NTLMv2, still some FIXME/TODO
++
+ Wed Jul 30 10:05:02 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/Makefile.am: add missing header for hmac
+ 
+@@ -491,4 +495,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2570 2008/07/30 08:06:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2571 2008/07/30 14:38:07 freddy77 Exp $
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index 6d26c83..bfd6e83 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -37,13 +37,15 @@
+ #include "tdsstring.h"
+ #include "md4.h"
+ #include "md5.h"
++#include "hmac_md5.h"
+ #include "des.h"
++#include "tdsiconv.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.30 2007/11/26 06:25:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.31 2008/07/30 14:38:09 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -66,10 +68,200 @@ typedef struct tds_answer
+ 	unsigned char nt_resp[24];
+ } TDSANSWER;
+ 
+-static void tds_answer_challenge(const char *passwd, const unsigned char *challenge, TDS_UINT *flags, TDSANSWER * answer);
++
++typedef struct
++{
++	TDS_TINYINT     response_type;
++	TDS_TINYINT     max_response_type;
++	TDS_SMALLINT    reserved1;
++	TDS_UINT        reserved2;
++	union {
++		TDS_UINT8       l;
++		unsigned char   s[8];
++	} timestamp;
++	TDS_UCHAR       challenge[8];
++	TDS_UINT        unknown;
++	/* target info block - variable length */
++} names_blob_prefix_t;
++
++static void
++tds_answer_challenge(TDSSOCKET * tds,
++		     TDSCONNECTION * connection,
++		     const unsigned char *challenge,
++		     TDS_UINT * flags,
++		     const unsigned char *names_blob, TDS_INT names_blob_len, TDSANSWER * answer, unsigned char **ntlm_v2_response);
+ static void tds_encrypt_answer(const unsigned char *hash, const unsigned char *challenge, unsigned char *answer);
+ static void tds_convert_key(const unsigned char *key_56, DES_KEY * ks);
+ 
++static void
++convert_to_upper(char *buf, int len)
++{
++	int i;
++
++	for (i = 0; i < len; i++)
++		buf[i] = toupper(buf[i]);
++}
++
++/* FIXME this function can fail, test result below in callers */
++static const char *
++convert_to_usc2le_string(TDSSOCKET * tds, const char *s, int len, int *out_len)
++{
++	char *buf;
++
++	const char *ib;
++	char *ob;
++	size_t il, ol;
++
++	const TDSICONV * char_conv = tds->char_convs[client2ucs2];
++
++	/* char_conv is only mostly const */
++	TDS_ERRNO_MESSAGE_FLAGS *suppress = (TDS_ERRNO_MESSAGE_FLAGS *) & char_conv->suppress;
++
++	if (char_conv->flags == TDS_ENCODING_MEMCPY) {
++		*out_len = len;
++		return s;
++	}
++
++	/* allocate needed buffer (+1 is to exclude 0 case) */
++	ol = len * char_conv->server_charset.max_bytes_per_char / char_conv->client_charset.min_bytes_per_char + 1;
++	buf = (char *) malloc(ol);
++	if (!buf)
++		return NULL;
++
++	ib = s;
++	il = len;
++	ob = buf;
++	memset(suppress, 0, sizeof(char_conv->suppress));
++	if (tds_iconv(tds, char_conv, to_server, &ib, &il, &ob, &ol) == (size_t) - 1) {
++		free(buf);
++		return NULL;
++	}
++	*out_len = ob - buf;
++	return buf;
++}
++
++
++static void
++convert_to_usc2le_string_free(const char *original, const char *converted)
++{
++	if (original != converted)
++		free((char *) converted);
++}
++
++
++static void
++generate_random_buffer(unsigned char *out, int len)
++{
++	int i;
++
++	/* TODO find a better random... */
++	for (i = 0; i < len; ++i)
++		out[i] = rand() / (RAND_MAX / 256);
++}
++
++
++static void
++make_ntlm_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_hash[16])
++{
++	MD4_CTX context;
++	int passwd_len = 0;
++	const char *passwd_usc2le = NULL;
++	int passwd_usc2le_len = 0;
++
++	passwd_len = strlen(passwd);
++
++	if (passwd_len > 128)
++		passwd_len = 128;
++
++	passwd_usc2le = convert_to_usc2le_string(tds, passwd, passwd_len, &passwd_usc2le_len);
++
++	/* compute NTLM hash */
++	MD4Init(&context);
++	MD4Update(&context, (unsigned char *) passwd_usc2le, passwd_usc2le_len);
++	MD4Final(&context, ntlm_hash);
++
++	/* with security is best be pedantic */
++	memset((char *) passwd_usc2le, 0, passwd_usc2le_len);
++	memset(&context, 0, sizeof(context));
++	convert_to_usc2le_string_free(passwd, passwd_usc2le);
++}
++
++
++static void
++make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_hash[16])
++{
++	const char *user_name, *domain;
++	int domain_len, user_name_len;
++	const char *p;
++
++	unsigned char ntlm_hash[16];
++	char buf[256];
++	int buf_len = 0;
++	const char *buf_usc2le;
++	int buf_usc2le_len = 0;
++
++	user_name = tds_dstr_cstr(&tds->connection->user_name);
++	user_name_len = strlen(user_name);
++
++	/* parse domain\username */
++	p = strchr(user_name, '\\');
++
++	domain = user_name;
++	domain_len = p - user_name;
++
++	user_name = p + 1;
++	user_name_len = strlen(user_name);
++
++	if (user_name_len > 128)
++		user_name_len = 128;
++	memcpy(buf, user_name, user_name_len);
++
++	convert_to_upper(buf, user_name_len);
++
++	if (domain_len > 128)
++		domain_len = 128;
++	memcpy(buf + user_name_len, domain, domain_len);
++	/* Target is supposed to be case-sensitive */
++
++	buf_len = user_name_len + domain_len;
++
++	buf_usc2le = convert_to_usc2le_string(tds, buf, buf_len, &buf_usc2le_len);
++
++	make_ntlm_hash(tds, passwd, ntlm_hash);
++	hmac_md5(ntlm_hash, (const unsigned char *) buf_usc2le, buf_usc2le_len, ntlm_v2_hash);
++
++	/* with security is best be pedantic */
++	memset(&ntlm_hash, 0, sizeof(ntlm_hash));
++	memset(buf, 0, sizeof(buf));
++	memset((char *) buf_usc2le, 0, buf_usc2le_len);
++	convert_to_usc2le_string_free(buf, buf_usc2le);
++}
++
++
++/*
++ * hash - The NTLMv2 Hash.
++ * client_data - The client data (blob or client nonce).
++ * challenge - The server challenge from the Type 2 message.
++ */
++static unsigned char *
++make_lm_v2_response(const unsigned char ntlm_v2_hash[16],
++		    const unsigned char *client_data, TDS_INT client_data_len, const unsigned char challenge[8])
++{
++	int mac_len = 16 + client_data_len;
++	unsigned char *mac;
++
++	mac = malloc(mac_len);
++	if (!mac)
++		return NULL;
++
++	memcpy(mac + 8, challenge, 8);
++	memcpy(mac + 16, client_data, client_data_len);
++	hmac_md5(ntlm_v2_hash, mac + 8, client_data_len + 8, mac);
++
++	return mac;
++}
++
++
+ /**
+  * Crypt a given password using schema required for NTLMv1 or NTLM2 authentication
+  * @param passwd clear text domain password
+@@ -78,20 +270,52 @@ static void tds_convert_key(const unsigned char *key_56, DES_KEY * ks);
+  * @param answer buffer where to store crypted password
+  */
+ static void
+-tds_answer_challenge(const char *passwd, const unsigned char *challenge, TDS_UINT *flags, TDSANSWER * answer)
++tds_answer_challenge(TDSSOCKET * tds,
++		     TDSCONNECTION * connection,
++		     const unsigned char *challenge,
++		     TDS_UINT * flags,
++		     const unsigned char *names_blob, TDS_INT names_blob_len, TDSANSWER * answer, unsigned char **ntlm_v2_response)
+ {
+ #define MAX_PW_SZ 14
++	const char *passwd = tds_dstr_cstr(&connection->password);
+ 	int len;
+ 	int i;
+ 	static const des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+ 	DES_KEY ks;
+ 	unsigned char hash[24], ntlm2_challenge[16];
+-	unsigned char passwd_buf[256];
+-	MD4_CTX context;
++	int ntlm_v;
+ 
+ 	memset(answer, 0, sizeof(TDSANSWER));
+ 
++	ntlm_v = 2;
++
++	if (ntlm_v == 2) {
++		/* NTLMv2 */
++		unsigned char *lm_v2_response;
++		unsigned char ntlm_v2_hash[16];
++		const names_blob_prefix_t *names_blob_prefix;
++
++		make_ntlm_v2_hash(tds, passwd, ntlm_v2_hash);
++
++		/* NTLMv2 response */
++		/* Size of lm_v2_response is 16 + names_blob_len */
++		/* FIXME check result */
++		*ntlm_v2_response = make_lm_v2_response(ntlm_v2_hash, names_blob, names_blob_len, challenge);
++
++		/* LMv2 response */
++		/* Take client's chalenge from names_blob */
++		names_blob_prefix = (const names_blob_prefix_t *) names_blob;
++		/* FIXME check result */
++		lm_v2_response = make_lm_v2_response(ntlm_v2_hash, names_blob_prefix->challenge, 8, challenge);
++		memcpy(answer->lm_resp, lm_v2_response, 24);
++		free(lm_v2_response);
++		return;
++	}
++
+ 	if (!(*flags & 0x80000)) {
++		/* NTLM */
++		unsigned char passwd_buf[MAX_PW_SZ];
++
+ 		/* convert password to upper and pad to 14 chars */
+ 		memset(passwd_buf, 0, MAX_PW_SZ);
+ 		len = strlen(passwd);
+@@ -111,13 +335,12 @@ tds_answer_challenge(const char *passwd, const unsigned char *challenge, TDS_UIN
+ 		memset(hash + 16, 0, 5);
+ 
+ 		tds_encrypt_answer(hash, challenge, answer->lm_resp);
++		memset(passwd_buf, 0, sizeof(passwd_buf));
+ 	} else {
+ 		MD5_CTX md5_ctx;
+ 
+ 		/* NTLM2 */
+-		/* TODO find a better random... */
+-		for (i = 0; i < 8; ++i)
+-			hash[i] = rand() / (RAND_MAX/256);
++		generate_random_buffer(hash, 8);
+ 		memset(hash + 8, 0, 16);
+ 		memcpy(answer->lm_resp, hash, 24);
+ 
+@@ -131,22 +354,7 @@ tds_answer_challenge(const char *passwd, const unsigned char *challenge, TDS_UIN
+ 	*flags = 0x8201;
+ 
+ 	/* NTLM/NTLM2 response */
+-	len = strlen(passwd);
+-	if (len > 128)
+-		len = 128;
+-	/*
+-	 * TODO we should convert this to ucs2le instead of
+-	 * using it blindly as iso8859-1
+-	 */
+-	for (i = 0; i < len; ++i) {
+-		passwd_buf[2 * i] = passwd[i];
+-		passwd_buf[2 * i + 1] = 0;
+-	}
+-
+-	/* compute NTLM hash */
+-	MD4Init(&context);
+-	MD4Update(&context, passwd_buf, len * 2);
+-	MD4Final(&context, hash);
++	make_ntlm_hash(tds, passwd, hash);
+ 	memset(hash + 16, 0, 5);
+ 
+ 	tds_encrypt_answer(hash, challenge, answer->nt_resp);
+@@ -154,9 +362,7 @@ tds_answer_challenge(const char *passwd, const unsigned char *challenge, TDS_UIN
+ 	/* with security is best be pedantic */
+ 	memset(&ks, 0, sizeof(ks));
+ 	memset(hash, 0, sizeof(hash));
+-	memset(passwd_buf, 0, sizeof(passwd_buf));
+ 	memset(ntlm2_challenge, 0, sizeof(ntlm2_challenge));
+-	memset(&context, 0, sizeof(context));
+ }
+ 
+ 
+@@ -209,7 +415,8 @@ tds_convert_key(const unsigned char *key_56, DES_KEY * ks)
+ 
+ 
+ static int
+-tds7_send_auth(TDSSOCKET * tds, const unsigned char *challenge, TDS_UINT flags)
++tds7_send_auth(TDSSOCKET * tds,
++	       const unsigned char *challenge, TDS_UINT flags, const unsigned char *names_blob, TDS_INT names_blob_len)
+ {
+ 	int current_pos;
+ 	TDSANSWER answer;
+@@ -223,6 +430,10 @@ tds7_send_auth(TDSSOCKET * tds, const unsigned char *challenge, TDS_UINT flags)
+ 	int password_len;
+ 	int domain_len;
+ 
++	unsigned char *ntlm_v2_response = NULL;
++	unsigned int ntlm_response_len = 24;
++	unsigned int lm_response_len = 24;
++
+ 	TDSCONNECTION *connection = tds->connection;
+ 
+ 	/* check connection */
+@@ -245,6 +456,12 @@ tds7_send_auth(TDSSOCKET * tds, const unsigned char *challenge, TDS_UINT flags)
+ 	user_name = p + 1;
+ 	user_name_len = strlen(user_name);
+ 
++	tds_answer_challenge(tds, connection, challenge, &flags, names_blob, names_blob_len, &answer, &ntlm_v2_response);
++	ntlm_response_len = ntlm_v2_response ? 16 + names_blob_len : 24;
++	lm_response_len = ntlm_v2_response ? 0 : 24;
++	/* lm_response_len = 24; */
++	/* ntlm_response_len = 0; */
++
+ 	tds->out_flag = TDS7_AUTH;
+ 	tds_put_n(tds, "NTLMSSP", 8);
+ 	tds_put_int(tds, 3);	/* sequence 3 */
+@@ -252,18 +469,20 @@ tds7_send_auth(TDSSOCKET * tds, const unsigned char *challenge, TDS_UINT flags)
+ 	/* FIXME *2 work only for single byte encodings */
+ 	current_pos = 64 + (domain_len + user_name_len + host_name_len) * 2;
+ 
+-	tds_put_smallint(tds, 24);	/* lan man resp length */
+-	tds_put_smallint(tds, 24);	/* lan man resp length */
++	/* LM/LMv2 Response */
++	tds_put_smallint(tds, lm_response_len);	/* lan man resp length */
++	tds_put_smallint(tds, lm_response_len);	/* lan man resp length */
+ 	tds_put_int(tds, current_pos);	/* resp offset */
+-	current_pos += 24;
++	current_pos += lm_response_len;
+ 
+-	tds_put_smallint(tds, 24);	/* nt resp length */
+-	tds_put_smallint(tds, 24);	/* nt resp length */
++	/* NTLM/NTLMv2 Response */
++	tds_put_smallint(tds, ntlm_response_len);	/* nt resp length */
++	tds_put_smallint(tds, ntlm_response_len);	/* nt resp length */
+ 	tds_put_int(tds, current_pos);	/* nt resp offset */
+ 
+ 	current_pos = 64;
+ 
+-	/* domain */
++	/* Target Name - domain or server name */
+ 	tds_put_smallint(tds, domain_len * 2);
+ 	tds_put_smallint(tds, domain_len * 2);
+ 	tds_put_int(tds, current_pos);
+@@ -275,27 +494,41 @@ tds7_send_auth(TDSSOCKET * tds, const unsigned char *challenge, TDS_UINT flags)
+ 	tds_put_int(tds, current_pos);
+ 	current_pos += user_name_len * 2;
+ 
+-	/* hostname */
++	/* Workstation Name */
+ 	tds_put_smallint(tds, host_name_len * 2);
+ 	tds_put_smallint(tds, host_name_len * 2);
+ 	tds_put_int(tds, current_pos);
+ 	current_pos += host_name_len * 2;
+ 
+-	/* unknown */
++	/* Session Key (optional) */
+ 	tds_put_smallint(tds, 0);
+ 	tds_put_smallint(tds, 0);
+-	tds_put_int(tds, current_pos + (24 * 2));
++	tds_put_int(tds, current_pos + lm_response_len + ntlm_response_len);
+ 
+ 	/* flags */
+-	tds_answer_challenge(tds_dstr_cstr(&connection->password), challenge, &flags, &answer);
++	/* "challenge" is 8 bytes long */
++	/* tds_answer_challenge(tds_dstr_cstr(&connection->password), challenge, &flags, &answer); */
+ 	tds_put_int(tds, flags);
+ 
++	/* OS Version Structure (Optional) */
++
++	/* Data itself */
+ 	tds_put_string(tds, domain, domain_len);
+ 	tds_put_string(tds, user_name, user_name_len);
+ 	tds_put_string(tds, tds_dstr_cstr(&connection->client_host_name), host_name_len);
+ 
+-	tds_put_n(tds, answer.lm_resp, 24);
+-	tds_put_n(tds, answer.nt_resp, 24);
++	/* data block */
++	tds_put_n(tds, answer.lm_resp, lm_response_len);
++
++	if (ntlm_v2_response == NULL) {
++		/* NTLMv1 */
++		tds_put_n(tds, answer.nt_resp, ntlm_response_len);
++	} else {
++		/* NTLMv2 */
++		tds_put_n(tds, ntlm_v2_response, ntlm_response_len);
++		memset(ntlm_v2_response, 0, ntlm_response_len);
++		free(ntlm_v2_response);
++	}
+ 
+ 	/* for security reason clear structure */
+ 	memset(&answer, 0, sizeof(TDSANSWER));
+@@ -321,6 +554,81 @@ tds_ntlm_free(TDSSOCKET * tds, TDSAUTHENTICATION * tds_auth)
+ 
+ static const unsigned char ntlm_id[] = "NTLMSSP";
+ 
++/**
++ * put a 8 byte filetime from a time_t
++ * This takes GMT as input
++ */
++static void
++unix_to_nt_time(TDS_UINT8 * nt, time_t t)
++{
++#define TIME_FIXUP_CONSTANT 11644473600LLU
++
++	TDS_UINT8 t2;
++
++	if (t == (time_t) - 1) {
++		*nt = (TDS_UINT8) - 1LL;
++		return;
++	}
++	if (t == 0) {
++		*nt = 0;
++		return;
++	}
++
++	t2 = t;
++	t2 += TIME_FIXUP_CONSTANT;
++	t2 *= 1000 * 1000 * 10;
++
++	*nt = t2;
++}
++
++/* TODO I don't like this stuf here -- freddy77 */
++#ifdef WORDS_BIGENDIAN
++static TDS_UINT
++swap_32(TDS_UINT val)
++{
++	return (((((TDS_UINT) val) & 0xff000000) >> 24) | ((((TDS_UINT) val) & 0x00ff0000) >> 8) |
++		((((TDS_UINT) val) & 0x0000ff00) << 8) | ((((TDS_UINT) val) & 0x000000ff) << 24));
++}
++#endif
++
++static TDS_UINT8
++to_le(TDS_UINT8 val)
++{
++#ifndef WORDS_BIGENDIAN
++	return val;
++#else
++	union
++	{
++		TDS_UINT8 ll;
++		TDS_UINT l[2];
++	} w, r;
++
++	w.ll = val;
++	r.l[0] = swap_32(w.l[1]);
++	r.l[1] = swap_32(w.l[0]);
++	return r.ll;
++#endif
++}
++
++
++static void
++fill_names_blob_prefix(names_blob_prefix_t * prefix)
++{
++	TDS_UINT8 nttime = 0;
++
++	/* TODO use more precision, not only seconds */
++	unix_to_nt_time(&nttime, time(NULL));
++
++	prefix->response_type = 0x01;
++	prefix->max_response_type = 0x01;
++	prefix->reserved1 = 0x0000;
++	prefix->reserved2 = 0x00000000;
++	prefix->timestamp.l = to_le(nttime);
++	generate_random_buffer(prefix->challenge, sizeof(prefix->challenge));
++
++	prefix->unknown = 0x00000000;
++}
++
+ static int
+ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t len)
+ {
+@@ -328,6 +636,17 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 	TDS_UINT flags;
+ 	int where;
+ 
++	int domain_len;
++	int data_block_offset;
++
++	int target_info_len = 0;
++	int target_info_offset;
++
++	int names_blob_len;
++	unsigned char *names_blob;
++
++	int rc;
++
+ 	/* at least 32 bytes (till context) */
+ 	if (len < 32)
+ 		return TDS_FAIL;
+@@ -337,24 +656,64 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 		return TDS_FAIL;
+ 	if (tds_get_int(tds) != 2)	/* sequence -> 2 */
+ 		return TDS_FAIL;
+-	tds_get_n(tds, NULL, 4);	/* domain len (2 time) */
+-	tds_get_int(tds);	/* domain offset */
++	domain_len = tds_get_smallint(tds);	/* domain len */
++	domain_len = tds_get_smallint(tds);	/* domain len */
++	data_block_offset = tds_get_int(tds);	/* domain offset */
+ 	flags = tds_get_int(tds);	/* flags */
+ 	tds_get_n(tds, nonce, 8);
+ 	tdsdump_dump_buf(TDS_DBG_INFO1, "TDS_AUTH_TOKEN nonce", nonce, 8);
+ 	where = 32;
+ 
+-	/*
+-	 * tds_get_string(tds, domain, domain_len); 
+-	 * tdsdump_log(TDS_DBG_INFO1, "TDS_AUTH_TOKEN domain %s\n", domain);
+-	 * where += strlen(domain);
+-	 */
++	/*data_block_offset == 32 */
++	/* Version 1 -- The Context, Target Information, and OS Version structure are all omitted */
++
++	if (data_block_offset >= 48 && where + 16 <= len) {
++		/* Version 2 -- The Context and Target Information fields are present, but the OS Version structure is not. */
++		tds_get_n(tds, NULL, 8);	/* Context (two consecutive longs) */
++
++		target_info_len = tds_get_smallint(tds);	/* Target Information len */
++		target_info_len = tds_get_smallint(tds);	/* Target Information len */
++		target_info_offset = tds_get_int(tds);	/* Target Information offset */
++
++		where += 16;
+ 
+-	/* discard context, target and data informations */
++		if (data_block_offset >= 56 && where + 8 <= len) {
++			/* Version 3 -- The Context, Target Information, and OS Version structure are all present. */
++			tds_get_n(tds, NULL, 8);	/* OS Version Structure */
++			where += 8;
++		}
++	}
++
++	/* read Target Info if possible */
++	if (target_info_len > 0 && target_info_offset >= where && target_info_offset + target_info_len <= len) {
++		tds_get_n(tds, NULL, target_info_offset - where);
++		where = target_info_offset;
++
++		/* TODO why + 4 ?? -- freddy77 */
++		names_blob_len = sizeof(names_blob_prefix_t) + target_info_len + 4;
++
++		/* read Target Info */
++		names_blob = (unsigned char *) malloc(names_blob_len);
++		if (!names_blob)
++			return TDS_FAIL;
++		memset(names_blob, 0, names_blob_len);
++
++		fill_names_blob_prefix((names_blob_prefix_t *) names_blob);
++		tds_get_n(tds, names_blob + sizeof(names_blob_prefix_t), target_info_len);
++		where += target_info_len;
++	} else {
++		names_blob = NULL;
++		names_blob_len = 0;
++	}
++	/* discard anything left */
+ 	tds_get_n(tds, NULL, len - where);
+ 	tdsdump_log(TDS_DBG_INFO1, "Draining %d bytes\n", (int) (len - where));
+ 
+-	return tds7_send_auth(tds, nonce, flags);
++	rc = tds7_send_auth(tds, nonce, flags, names_blob, names_blob_len);
++
++	free(names_blob);
++
++	return rc;
+ }
+ 
+ /**
+
+commit d0d786ddd594521d075cdc67a8906ef21ae0936f
+Author: freddy77 <freddy77>
+Date:   Wed Jul 30 21:25:53 2008 +0000
+
+    additional cleanup and notes
+
+diff --git a/ChangeLog b/ChangeLog
+index 4ee69bb..f567614 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jul 30 23:25:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/challenge.c: additional cleanup and notes
++
+ Wed Jul 30 16:36:52 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c:
+ 	- merged patch #2031829 about NTLMv2, still some FIXME/TODO
+@@ -495,4 +498,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2571 2008/07/30 14:38:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2572 2008/07/30 21:25:53 freddy77 Exp $
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index bfd6e83..7f93978 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.31 2008/07/30 14:38:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.32 2008/07/30 21:25:53 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -75,10 +75,7 @@ typedef struct
+ 	TDS_TINYINT     max_response_type;
+ 	TDS_SMALLINT    reserved1;
+ 	TDS_UINT        reserved2;
+-	union {
+-		TDS_UINT8       l;
+-		unsigned char   s[8];
+-	} timestamp;
++	TDS_UINT8       timestamp;
+ 	TDS_UCHAR       challenge[8];
+ 	TDS_UINT        unknown;
+ 	/* target info block - variable length */
+@@ -581,36 +578,6 @@ unix_to_nt_time(TDS_UINT8 * nt, time_t t)
+ 	*nt = t2;
+ }
+ 
+-/* TODO I don't like this stuf here -- freddy77 */
+-#ifdef WORDS_BIGENDIAN
+-static TDS_UINT
+-swap_32(TDS_UINT val)
+-{
+-	return (((((TDS_UINT) val) & 0xff000000) >> 24) | ((((TDS_UINT) val) & 0x00ff0000) >> 8) |
+-		((((TDS_UINT) val) & 0x0000ff00) << 8) | ((((TDS_UINT) val) & 0x000000ff) << 24));
+-}
+-#endif
+-
+-static TDS_UINT8
+-to_le(TDS_UINT8 val)
+-{
+-#ifndef WORDS_BIGENDIAN
+-	return val;
+-#else
+-	union
+-	{
+-		TDS_UINT8 ll;
+-		TDS_UINT l[2];
+-	} w, r;
+-
+-	w.ll = val;
+-	r.l[0] = swap_32(w.l[1]);
+-	r.l[1] = swap_32(w.l[0]);
+-	return r.ll;
+-#endif
+-}
+-
+-
+ static void
+ fill_names_blob_prefix(names_blob_prefix_t * prefix)
+ {
+@@ -623,7 +590,10 @@ fill_names_blob_prefix(names_blob_prefix_t * prefix)
+ 	prefix->max_response_type = 0x01;
+ 	prefix->reserved1 = 0x0000;
+ 	prefix->reserved2 = 0x00000000;
+-	prefix->timestamp.l = to_le(nttime);
++#ifdef WORDS_BIGENDIAN
++	tds_swap_bytes(&nttime, 8);
++#endif
++	prefix->timestamp = nttime;
+ 	generate_random_buffer(prefix->challenge, sizeof(prefix->challenge));
+ 
+ 	prefix->unknown = 0x00000000;
+@@ -689,7 +659,12 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 		tds_get_n(tds, NULL, target_info_offset - where);
+ 		where = target_info_offset;
+ 
+-		/* TODO why + 4 ?? -- freddy77 */
++		/*
++		 * the + 4 came from blob structure, after Target Info 4
++		 * additional reserved bytes must be present
++		 * Search "davenport port"
++		 * (currently http://davenport.sourceforge.net/ntlm.html)
++		 */
+ 		names_blob_len = sizeof(names_blob_prefix_t) + target_info_len + 4;
+ 
+ 		/* read Target Info */
+
+commit 76b15cc10b79f4aaab3f39d73ad66e70235ad767
+Author: jklowden <jklowden>
+Date:   Thu Jul 31 10:13:37 2008 +0000
+
+    updated and cleaned up somewhat
+
+diff --git a/ChangeLog b/ChangeLog
+index f567614..0cbf86d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jul 31 06:12:05 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/tds.html updated and cleaned up somewhat
++
+ Wed Jul 30 23:25:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c: additional cleanup and notes
+ 
+@@ -498,4 +501,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2572 2008/07/30 21:25:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2573 2008/07/31 10:13:37 jklowden Exp $
+diff --git a/doc/tds.html b/doc/tds.html
+index f219226..2045388 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -17,8 +17,8 @@ This document attempts to cover the TDS protocol for:
+ 	<tr><td align=center>4.2</td><td>Sybase SQL Server &lt; 10 and  Microsoft SQL Server 6.5</td></tr>
+ 	<tr><td align=center>5.0</td><td>Sybase SQL Server &gt;= 10</td></tr>
+ 	<tr><td align=center>7.0</td><td>Microsoft SQL Server 7.0</td></tr>
+-	<tr><td align=center>8.0</td><td>Microsoft SQL Server 2000</td></tr>
+-	<tr><td align=center>9.0</td><td>Microsoft SQL Server 2005</td></tr>
++	<tr><td align=center>7.1</td><td>Microsoft SQL Server 2000</td></tr>
++	<tr><td align=center>7.2</td><td>Microsoft SQL Server 2005</td></tr>
+ </table>
+ 
+ <h2>Contents</h2>
+@@ -29,7 +29,7 @@ This document attempts to cover the TDS protocol for:
+ <li><a href="#packet">The Packet Format</a>
+ <li><a href="#login">Login Packet</a>
+ <li><a href="#login7">TDS 7.0 Login Packet</a>
+-<li><a href="#collate">Collate structure</a>
++<li><a href="#collate">Collation structure</a>
+ <li><a href="#requests">Client requests</a>
+ <li><a href="#responses">Server Responses</a>
+ </ul>
+@@ -39,16 +39,16 @@ This document attempts to cover the TDS protocol for:
+ <a name="terms"></a>
+ <pre>
+ TDS protocol versions
+-  TDS5    tds version 5.0
+-  TDS7    tds version 7.0
+-  TDS7+   tds version 7.0, 8.0 and 9.0
+-  TDS5-   tds version 5.0 and previous
++  TDS 5.0    tds version 5.0
++  TDS 7.0    tds version 7.0
++  TDS 7.0+   tds version 7.0, 7.1 and 7.2
++  TDS 5.0-   tds version 5.0 and previous
+ 
+ Variable types used in this document:
+   CHAR      8-bit char
+     CHAR[6]	string of 6 chars
+     CHAR[n]     variable length string
+-  XCHAR    single byte (TDS5-) or ucs2le (TDS7+) characters
++  XCHAR    single byte (TDS 5.0-) or ucs2le (TDS 7.0+) characters
+   INT8      8-bit int
+   INT16    16-bit int
+   INT32    32-bit int
+@@ -139,11 +139,11 @@ above header.</p>
+   512 is the block_size in the login packet, so it could be set to a
+   different values.
+   In Sybase you can configure a range of valid block sizes.
+-  TDS7+ use a default of 4096 as block size.</p>
++  TDS 7.0+ use a default of 4096 as block size.</p>
+ <hr>
+ <p>
+ <a name="login"></a>
+-<h2 class="section">Login Packet</h2>
++<h2 class="section">TDS 4.2 &amp; 5.0 Login Packet</h2>
+ 
+ <p>
+ Packet type (first byte) is 2. The numbers
+@@ -200,13 +200,15 @@ byte   var type    description
+ <hr>
+ <p>
+ <a name="login7"></a>
+-<h2 class="section">TDS7.0 Login Packet</h2>
++<h2 class="section">TDS 7.0+ Login Packet</h2>
+ <pre>
+ byte  var type  description
+ ---------------------------
+   0   INT32	total packet size
+-  4   INT8[4]	TDS Version	0x00000070 for TDS7, 0x01000071 for TDS8
+-                0x02000972 for mssql 2005
++  4   INT8[4]	TDS Version	
++                	0x00000070 7.0
++			0x01000071 7.1
++                	0x02000972 7.2 (7.2.9?)
+   8   INT32	packet size (default 4096)
+  12   INT8[4]	client program version
+  16   INT32	PID of client
+@@ -216,16 +218,27 @@ byte  var type  description
+                 0x40 change to initial database must succeed
+                 0x20 enable warning messages if USE &lt;database&gt; issued
+                 0x10 enable BCP
++		0x08 use ND5000 floating point format (untested)
++		0x04 use VAX floating point format (untested)
++		0x02 use EBCDIC encoding (untested)
++		0x01 use big-endian byte order (untested)
+  25   INT8	option flags 2
+                 0x80 enable domain login security
++		0x40 "USER_SERVER - reserved" 
++		0x20 user type is "DQ login"
++		0x10 user type is "replication login"
++		0x08 "fCacheConnect"
++		0x04 "fTranBoundary"
+                 0x02 client is an ODBC driver
+                 0x01 change to initial language must succeed
+- 26   INT8	sql type flags (0)
+- 27   INT8	reserved flags (must be 0)
++ 26   INT8	0x04 spawn user instance (TDS 7.2)
++                0x02 XML data type instances are returned as binary XML (TDS 7.2)
++                0x01 password change requested (TDS 7.2)
++ 27   INT8	0x01 SQL Type: 0 = use default, 1 = use T-SQL (TDS 7.2)
+  28   INT8[4]	time zone (0x88ffffff ???)
+  32   INT8[4]	collation information
+  36   INT16	position of client hostname (86)
+- 38   INT16	hostname lenght
++ 38   INT16	hostname length
+  40   INT16	position of username
+  42   INT16	username length
+  44   INT16	position of password
+@@ -234,19 +247,18 @@ byte  var type  description
+  50   INT16	app name length
+  52   INT16	position of server name
+  54   INT16	server name length
+- 56   INT16	0
+- 58   INT16	0
++ 56   INT16	position of remote server/password pairs
++ 58   INT16	remote server/password pairs length
+  60   INT16	position of library name
+  62   INT16	library name length
+  64   INT16	position of language
+- 66   INT16	language name
+-                (for italian "Italiano" coded UCS2)
++ 66   INT16	language name (for italian "Italiano", coded UCS2)
+  68   INT16	position of database name
+  70   INT16	database name length
+  72   INT8[6]	MAC address of client
+  78   INT16	position of auth portion
+  80   INT16	NT authentication length
+- 82   INT16	next position (same of total packet size)
++ 82   INT16	next position (same as total packet size)
+  84   INT16	0
+  86   UCS2LE[n] hostname
+       UCS2LE[n]	username
+@@ -273,11 +285,14 @@ NT Authentication packet
+ See documentation on Samba for detail (or search ntlm authentication for IIS)
+ 
+ For mssql 2005 before hostname (byte 86) you have
+- 86   INT16     next position
+- 88   INT16     0
+- 90   INT8[4]   0x00000000 ???
++ 86   INT16     next position,  or 
++                position of file name for a database to be 
++                attached during the connection process
++ 88   INT16     database filename length
++ 90   INT16     new password position
++ 92   INT16     new password length
+  94   UCS2LE[n] hostname
+-      ... (like above)
++      ... (as above)
+ </pre>
+ <p>"current pos" is the starting byte address for a Unicode string within
+ the packet.  The length of that Unicode string immediately follows.  
+@@ -285,13 +300,13 @@ That implies there are at least 2 more strings that could be defined.
+ (character set??)
+ </p>
+ 
+-<p>Password and user is not used is NT authentication is used (setted as empty).</p>
++<p>Username and password are empty if domain authentication is used.</p>
+ 
+-<p>If client use an authentication packet server reply with 
+-<a href="#t237">Authentication</a> token followed by a <a href="#auth7">Authentication packet</a>.</p>
++<p>If the client uses an authentication packet, the server replies with an
++<a href="#t237">Authentication</a> token followed by an <a href="#auth7">Authentication packet</a>.</p>
+ 
+ <hr>
+-<h2 class="section">TDS7.0 Authentication Packet</h2>
++<h2 class="section">TDS 7.0 Authentication Packet</h2>
+ <p>
+ <a name="auth7"></a>
+ </p>
+@@ -306,14 +321,14 @@ auth   authentication data
+        for NTLM this message 3
+ </pre>
+ 
+-<p>This packet usually follow <a href="#t237">Authentication</a> token.</p>
++<p>This packet usually follows <a href="#t237">Authentication</a> token.</p>
+ 
+ <hr>
+ <h2 class="section">Types</h2>
+ <p>
+ <a name="types"></a>
+ </p>
+-<table border="1" summary="packets">
++<table border="0" summary="packets">
+ <tr>
+   <th>HEX</th><th>DEC</th><th>type</th><th>protocol</th><th>nullable</th><th>size</th><th>collate</th>
+ </tr>
+@@ -439,20 +454,19 @@ auth   authentication data
+ </tr>
+ </table>
+ <hr>
+-<p>* Under TDS9+ these types allow size to be -1. These types represents varchar(max), varbinary(max) and nvarchar(max).
+-Data representation for these types change in this way: </p>
++<p>* Under TDS 7.2+ these types allow size to be -1, representing varchar(max), varbinary(max) and nvarchar(max).
++Data representation for them changes: </p>
+ <ul>
+- <li>size is 64 bit not 16 bit</li>
+- <li>if size is -1 meaning NULL</li>
+- <li>if size is -2 size is unknown</li>
+- <li>data is splitted in chunks where ever chunk start with a 32 bit size</li>
++ <li>size is 64 (not 16) bits</li>
++ <li>size of -1 means NULL</li>
++ <li>size of -2 means the size is unknown</li>
++ <li>the data are split in chunks,  where each chunk starts with a 32-bit size</li>
+  <li>a chunk with size &lt;= 0 is the terminal chunk</li>
+ </ul>
+ <p>
+ <a name="collate"></a>
+-<h2 class="section">Collate type - TDS8</h2>
+-<p>Collate structure contain information on characters set encoding and compare
+-method.</p>
++<h2 class="section">Collation type - TDS 7.1</h2>
++<p>The collation structure contains information about the character set encoding and comparison method.</p>
+ <pre>
+  INT16      INT16    INT8
+ +----------+--------+------------+
+@@ -495,7 +509,7 @@ query</p>
+ column name length 
+ column name        column name in result set, not necessarily db column name
+ flags              bit flags
+-                   0x1  hidden (TDS5)
++                   0x1  hidden (TDS 5.0)
+                    0x2  key
+                    0x10 writable
+                    0x20 can be NULL
+@@ -508,9 +522,9 @@ scale              present only for SYBDECIMAL and SYBNUMERIC
+ t length           present only for SYBTEXT and SYBIMAGE, length of table name
+ table name         present only for SYBTEXT and SYBIMAGE
+ locale length      length of locale info (in bytes)
+-                   only for TDS5 results (not for parameters)
++                   only for TDS 5.0 results (not for parameters)
+ locale info        unknown
+-                   only for TDS5 results (not for parameters)
++                   only for TDS 5.0 results (not for parameters)
+ </pre>
+ 
+ <hr>
+@@ -534,7 +548,7 @@ TODO
+ <h2><a name="p1"><b class="section">Language packet (0x1 1)</b></a></h2>
+ <p>
+ This sample packet contain just SQL commands. It's supported by all TDS version
+-(although TDS5 have others token with similar use)
++(although TDS 5.0 have others token with similar use)
+ <pre>
+   XCHAR[n]
+ +---------+
+@@ -581,8 +595,8 @@ name length   length of RPC name in characters.
+               version instead of number.
+ rpc name      name of RPC.
+ flags         bit flags. 
+-               0x1 1 recompile procedure (TDS7+/TDS5)
+-               0x2 2 no metadata (TDS7+)
++               0x1 1 recompile procedure (TDS 7.0+/TDS 5.0)
++               0x2 2 no metadata (TDS 7.0+)
+                      (I don't know meaning of "no metadata" -- freddy77)
+ params        parameters. See below
+ </pre>
+@@ -601,12 +615,12 @@ data         data. See results for detail
+ <pre>
+   INT8          XCHAR[n]     INT8    INT32
+ +-------------+------------+-------+-----------------+
+-| name length | param name | flags | usertype (TDS5) |
++| name length | param name | flags | usertype (TDS 5.0) |
+ +-------------+------------+-------+-----------------+
+   INT8   varies  varies     INT8[5]      INT8
+ +------+-------+----------+------------+---------------+
+ | type | size  | optional | collate    | locale        |
+-|      | (opt) | (opt)    | info(TDS8) | length (TDS5) |
++|      | (opt) | (opt)    | info(TDS 7.1) | length (TDS 5.0) |
+ +------+-------+----------+------------+---------------+
+ 
+ name length   parameter name length (0 if unused)
+@@ -622,18 +636,18 @@ size          see <a href="#t129">Results</a>
+ optional      see <a href="#t129">Results</a>. Blobs DO NOT have 
+               optional on input parameters (output blob parameters
+               are not supported by any version of TDS).
+-collate info  only for type that want collate info and using TDS8
++collate info  only for type that want collate info and using TDS 7.1
+ locale length locale information length. Usually 0 (if not locale
+               information follow, the structure is unknown)
+ </pre>
+ 
+ <h2>Chained RPCs</h2>
+-<p>Under TDS7+ is possible to chain multiple RPCs together. This is useful to limit packets and round-trips with server. RPCs can be chained using byte 0x80 (TDS7/TDS8) or 0xFF (TDS9).</p>
++<p>Under TDS 7.0+ is possible to chain multiple RPCs together. This is useful to limit packets and round-trips with server. RPCs can be chained using byte 0x80 (TDS 7.0/TDS 7.1) or 0xFF (TDS 7.2).</p>
+ 
+ <pre>
+        INT8               INT8
+ +-----+------------------+-------------+-----+
+-| RPC | 0x80 (TDS7/TDS8) | 0xFF (TDS9) | RPC | ...
++| RPC | 0x80 (TDS 7.0/TDS 7.1) | 0xFF (TDS 7.2) | RPC | ...
+ +-----+------------------+-------------+-----+
+ </pre>
+ 
+@@ -755,7 +769,7 @@ its type. If variable length, they generally have the length as the second
+ and third bytes
+ <p>
+ Tokens encountered thus far:
+-<table border="1" summary="tokens">
++<table border="0" summary="tokens">
+ <tr>
+  <th>HEX</th><th>DEC</th><th>name</th><th>note</th>
+ </tr>
+@@ -809,7 +823,6 @@ Tokens encountered thus far:
+ </tr>
+ <tr>
+  <td>0xA1</td><td>161</td><td><a href="#t161">Column Format</a></td><td>4.2 only</td>
+-<td>31</td>
+ </tr>
+ <tr>
+  <td>0xA3</td><td>163</td><td><a href="#t163">Dynamic 2</a></td><td>5.0 only</td>
+@@ -891,12 +904,12 @@ Tokens encountered thus far:
+ </tr>
+ </table>
+ 
+-<h2 class="section">Param Format 2 - TDS5 (0x20 32)</h2>
++<h2 class="section">Param Format 2 - TDS 5.0 (0x20 32)</h2>
+ 
+ <p>TODO.
+ <a name="t32">&nbsp;</a> <hr>
+ 
+-<h2 id="t33" class="section">Language - TDS5 (0x21 33)</h2>
++<h2 id="t33" class="section">Language - TDS 5.0 (0x21 33)</h2>
+ 
+ <pre>
+  INT32    INT8     CHAR[n]
+@@ -915,7 +928,7 @@ query   query (total length - 1)
+ <p>TODO.
+ <a name="t34">&nbsp;</a> <hr>
+ 
+-<h2 id="t97" class="section">Row Format 2 - TDS5 (0x61 97)</h2>
++<h2 id="t97" class="section">Row Format 2 - TDS 5.0 (0x61 97)</h2>
+ 
+ <p>TODO.
+ 
+@@ -953,17 +966,17 @@ No information. (1 byte, value=0 ?)
+ <a name="t128">&nbsp;</a> </p>
+ 
+ <hr>
+-<h2 class="subsection">Cursor Close - TDS5 (0x80 128)</h2>
++<h2 class="subsection">Cursor Close - TDS 5.0 (0x80 128)</h2>
+ 
+ <p>TODO.
+ 
+ <a name="t129c">&nbsp;</a> <hr>
+-<h2 class="subsection">Cursor Delete - TDS5 (0x81 129)</h2>
++<h2 class="subsection">Cursor Delete - TDS 5.0 (0x81 129)</h2>
+ 
+ <p>TODO.
+ 
+ <a name="t129">&nbsp;</a> <hr>
+-<h2 class="subsection">Result - TDS7+ (0x81 129)</h2>
++<h2 class="subsection">Result - TDS 7.0+ (0x81 129)</h2>
+ 
+ <pre>
+  INT16  
+@@ -978,7 +991,7 @@ No information. (1 byte, value=0 ?)
+  INT16      INT16   INT8   varies  varies     INT8[5]      INT8          UCS2LE[n]
+ +----------+-------+------+-------+----------+------------+-------------+---------+
+ | usertype | flags | type | size  | optional | collate    | name length | name    | 
+-|          |       |      | (opt) | (opt)    | info(TDS8) |             |         |
++|          |       |      | (opt) | (opt)    | info(TDS 7.1) |             |         |
+ +----------+-------+------+-------+----------+------------+-------------+---------+
+ 
+ usertype	type modifier
+@@ -1002,28 +1015,28 @@ optional
+   blob/text types:            | table name length | table name |
+                               +-------------------+------------+
+ 
+-  collate info are available only using TDS8 and for characters types (but not
++  collate info are available only using TDS 7.1 and for characters types (but not
+   for old type like short VARCHAR, only 2byte length versions)
+ </pre>
+ 
+ 
+-<h2 id="t130" class="subsection">Cursor Fetch - TDS5 (0x82 130)</h2>
++<h2 id="t130" class="subsection">Cursor Fetch - TDS 5.0 (0x82 130)</h2>
+ 
+ <p>TODO.
+ 
+-<h2 id="t131" class="subsection">Cursor Info - TDS5 (0x83 131)</h2>
++<h2 id="t131" class="subsection">Cursor Info - TDS 5.0 (0x83 131)</h2>
+ 
+ <p>TODO.
+ 
+-<h2 id="t132" class="subsection">Cursor Open - TDS5 (0x84 132)</h2>
++<h2 id="t132" class="subsection">Cursor Open - TDS 5.0 (0x84 132)</h2>
+ 
+ <p>TODO.
+ 
+-<h2 id="t134" class="subsection">Cursor Declare - TDS5 (0x86 134)</h2>
++<h2 id="t134" class="subsection">Cursor Declare - TDS 5.0 (0x86 134)</h2>
+ 
+ <p>TODO.
+ 
+-<h2 id="t136" class="subsection">Compute Result - TDS7+ (0x88 136)</h2>
++<h2 id="t136" class="subsection">Compute Result - TDS 7.0+ (0x88 136)</h2>
+ 
+ <p>TODO.
+ 
+@@ -1094,11 +1107,11 @@ optional
+                               +-------------------+------------+
+ </pre>
+ 
+-<h2 id="t163" class="subsection">Dynamic 2 - TDS5 (0xA3 163)</h2>
++<h2 id="t163" class="subsection">Dynamic 2 - TDS 5.0 (0xA3 163)</h2>
+ 
+ <p>TODO.
+ 
+-<h2 id="t166" class="subsection">Option Cmd - TDS5 (0xA6 166)</h2>
++<h2 id="t166" class="subsection">Option Cmd - TDS 5.0 (0xA6 166)</h2>
+ 
+ <p>TODO.
+ 
+@@ -1117,7 +1130,7 @@ optional
+  INT8       INT8      INT32      INT8     varies  INT8            varies
+ +----------+---------+----------+--------+-------+---------------+-------------+
+ | operator | operand | usertype | column | size  | locale length | locale info |
+-|          |         |          |  type  | (opt) |  info (TDS5)  | (TDS5)      |
++|          |         |          |  type  | (opt) |  info (TDS 5.0)  | (TDS 5.0)      |
+ +----------+---------+----------+--------+-------+---------------+-------------+
+ 
+ operator      operator
+@@ -1160,7 +1173,7 @@ name length   table name length
+ table name    table name
+ </pre>
+ 
+-<p>TDS8:</p>
++<p>TDS 7.1:</p>
+ 
+ <pre>
+  INT16          varies
+@@ -1272,7 +1285,7 @@ to a column is the number
+ 
+  INT16      XCHAR[n]  INT8       XCHAR[n]  INT8       XCHAR[n]  INT16          INT32
+ +----------+---------+----------+---------+----------+---------+--------------+--------------+
+-| m length | message | s length | server  | p length | process | line#(TDS8-) | line# (TDS9) |
++| m length | message | s length | server  | p length | process | line#(TDS 7.1-) | line# (TDS 7.2) |
+ +----------+---------+----------+---------+----------+---------+--------------+--------------+
+ 
+ length		Length of packet
+@@ -1375,11 +1388,11 @@ hex  D1  01  00  0C  72  65  63  76  20  73  6C  65  65  70  20  20
+     209   1   0  12   r   e   c   v ' '   s   l   e   e   p ' ' ' '
+ </pre>
+ 
+-<h2 id="t215" class="section">Params - TDS5 (0xD7 215)</h2>
++<h2 id="t215" class="section">Params - TDS 5.0 (0xD7 215)</h2>
+ <p>
+ TODO.
+ 
+-<h2 id="t226" class="section">Capability - TDS5 (0xE2 226)</h2>
++<h2 id="t226" class="section">Capability - TDS 5.0 (0xE2 226)</h2>
+ 
+ <pre>
+  INT16    variable
+@@ -1404,25 +1417,25 @@ env code	Code for what part of environment changed
+ 	0x02  language
+ 	0x03  character set
+ 	0x04  packet size
+-	0x05  TDS7+ LCID
+-	0x06  TDS7+ ??? (sort method? sql server encoding?)
++	0x05  TDS 7.0+ LCID
++	0x06  TDS 7.0+ ??? (sort method? sql server encoding?)
+ 	0x07  Collation info
+ text1		Old value
+ text2		New value
+ 
+-text1 and text2 are text information (coded in ucs2 in TDS7+) except 
++text1 and text2 are text information (coded in ucs2 in TDS 7.0+) except 
+ collation info that's a structure (see collation structure)
+ </pre>
+ 
+-<h2 id="t230" class="section">DBRPC - TDS5 (0xE6 230)</h2>
++<h2 id="t230" class="section">DBRPC - TDS 5.0 (0xE6 230)</h2>
+ <p>
+ TODO.
+ 
+-<h2 id="t231" class="section">Dynamic - TDS5 (0xE7 231)</h2>
++<h2 id="t231" class="section">Dynamic - TDS 5.0 (0xE7 231)</h2>
+ <p>
+ TODO.
+ 
+-<h2 id="t236" class="section">Param Format - TDS5 (0xEC 236)</h2>
++<h2 id="t236" class="section">Param Format - TDS 5.0 (0xEC 236)</h2>
+ <pre>
+  INT16     INT16        variable size
+ +---------+------------+-------------------+
+@@ -1435,7 +1448,7 @@ number of parameters	number of parameter formats following
+ list of formats		I (*bdw*) imagine it uses the column format structure.
+ </pre>
+ 
+-<h2 id="t237" class="section">Authentication - TDS7 (0xED 237)</h2>
++<h2 id="t237" class="section">Authentication - TDS 7.0 (0xED 237)</h2>
+ <pre>
+  INT16     varies
+ +---------+------+
+@@ -1449,7 +1462,7 @@ auth     authentication data
+ 
+ <p>Client reply with <a href="#auth7">Authentication packet</a>.</p>
+ 
+-<h2 id="t238" class="section">Result Set - TDS5 (0xEE 238)</h2>
++<h2 id="t238" class="section">Result Set - TDS 5.0 (0xEE 238)</h2>
+ 
+ <pre>
+  INT16     INT16        variable size
+@@ -1479,7 +1492,7 @@ column info        <a href="#colInfo">column info</a>
+ <pre>
+  INT16       INT16     INT32               INT64
+ +-----------+---------+-------------------+------------------+
+-| bit flags | unknown | row count (TDS8-) | row count (TDS9) |
++| bit flags | unknown | row count (TDS 7.1-) | row count (TDS 7.2) |
+ +-----------+---------+-------------------+------------------+
+ 
+ Fields:
+@@ -1489,7 +1502,7 @@ bit flags          0x01 more results
+ 		   0x20 cancelled
+ unknown            2,0  /* something to do with block size perhaps */
+ row count          number of rows affected / returned in the result set. 
+-                   row count is 64-bit using TDS9.
++                   row count is 64-bit using TDS 7.2.
+ 		(FIXME check if "affected / returned" is correct)
+ </pre>
+ <P>
+@@ -1517,7 +1530,7 @@ The following people have contributed to this document:
+ (short list)
+ 
+ <h2>Document Status </h2>
+-<P>$Id: tds.html,v 1.38 2008/05/07 12:16:34 freddy77 Exp $</p>
++<P>$Id: tds.html,v 1.39 2008/07/31 10:13:38 jklowden Exp $</p>
+ <p>
+     <a href="http://validator.w3.org/check?uri=referer"><img
+         src="http://www.w3.org/Icons/valid-html401"
+
+commit 3fc04ea1ad918bc72f2095ecfeafd83cfccccd32
+Author: freddy77 <freddy77>
+Date:   Thu Jul 31 14:57:01 2008 +0000
+
+    removed important FIXMEs
+
+diff --git a/ChangeLog b/ChangeLog
+index 0cbf86d..1bef97c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,5 +1,8 @@
++Thu Jul 31 16:53:35 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/challenge.c: removed important FIXMEs
++
+ Thu Jul 31 06:12:05 EDT 2008	JK Lowden <jklowden@freetds.org>
+-	* doc/tds.html updated and cleaned up somewhat
++	* doc/tds.html: updated and cleaned up somewhat
+ 
+ Wed Jul 30 23:25:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c: additional cleanup and notes
+@@ -501,4 +504,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2573 2008/07/31 10:13:37 jklowden Exp $
++$Id: ChangeLog,v 1.2574 2008/07/31 14:57:01 freddy77 Exp $
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index 7f93978..5476d16 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.32 2008/07/30 21:25:53 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.33 2008/07/31 14:57:02 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -81,7 +81,7 @@ typedef struct
+ 	/* target info block - variable length */
+ } names_blob_prefix_t;
+ 
+-static void
++static int
+ tds_answer_challenge(TDSSOCKET * tds,
+ 		     TDSCONNECTION * connection,
+ 		     const unsigned char *challenge,
+@@ -99,12 +99,9 @@ convert_to_upper(char *buf, int len)
+ 		buf[i] = toupper(buf[i]);
+ }
+ 
+-/* FIXME this function can fail, test result below in callers */
+-static const char *
+-convert_to_usc2le_string(TDSSOCKET * tds, const char *s, int len, int *out_len)
++static int
++convert_to_usc2le_string(TDSSOCKET * tds, const char *s, int len, char *out)
+ {
+-	char *buf;
+-
+ 	const char *ib;
+ 	char *ob;
+ 	size_t il, ol;
+@@ -115,34 +112,20 @@ convert_to_usc2le_string(TDSSOCKET * tds, const char *s, int len, int *out_len)
+ 	TDS_ERRNO_MESSAGE_FLAGS *suppress = (TDS_ERRNO_MESSAGE_FLAGS *) & char_conv->suppress;
+ 
+ 	if (char_conv->flags == TDS_ENCODING_MEMCPY) {
+-		*out_len = len;
+-		return s;
++		memcpy(out, s, len);
++		return len;
+ 	}
+ 
+-	/* allocate needed buffer (+1 is to exclude 0 case) */
+-	ol = len * char_conv->server_charset.max_bytes_per_char / char_conv->client_charset.min_bytes_per_char + 1;
+-	buf = (char *) malloc(ol);
+-	if (!buf)
+-		return NULL;
+-
++	/* convert */
+ 	ib = s;
+ 	il = len;
+-	ob = buf;
++	ob = out;
++	ol = len * 2;
+ 	memset(suppress, 0, sizeof(char_conv->suppress));
+-	if (tds_iconv(tds, char_conv, to_server, &ib, &il, &ob, &ol) == (size_t) - 1) {
+-		free(buf);
+-		return NULL;
+-	}
+-	*out_len = ob - buf;
+-	return buf;
+-}
+-
++	if (tds_iconv(tds, char_conv, to_server, &ib, &il, &ob, &ol) == (size_t) - 1)
++		return -1;
+ 
+-static void
+-convert_to_usc2le_string_free(const char *original, const char *converted)
+-{
+-	if (original != converted)
+-		free((char *) converted);
++	return ob - out;
+ }
+ 
+ 
+@@ -156,13 +139,12 @@ generate_random_buffer(unsigned char *out, int len)
+ 		out[i] = rand() / (RAND_MAX / 256);
+ }
+ 
+-
+-static void
++static int
+ make_ntlm_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_hash[16])
+ {
+ 	MD4_CTX context;
+ 	int passwd_len = 0;
+-	const char *passwd_usc2le = NULL;
++	char passwd_usc2le[256];
+ 	int passwd_usc2le_len = 0;
+ 
+ 	passwd_len = strlen(passwd);
+@@ -170,7 +152,11 @@ make_ntlm_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_hash[16])
+ 	if (passwd_len > 128)
+ 		passwd_len = 128;
+ 
+-	passwd_usc2le = convert_to_usc2le_string(tds, passwd, passwd_len, &passwd_usc2le_len);
++	passwd_usc2le_len = convert_to_usc2le_string(tds, passwd, passwd_len, passwd_usc2le);
++	if (passwd_usc2le_len < 0) {
++		memset((char *) passwd_usc2le, 0, sizeof(passwd_usc2le));
++		return TDS_FAIL;
++	}
+ 
+ 	/* compute NTLM hash */
+ 	MD4Init(&context);
+@@ -180,11 +166,11 @@ make_ntlm_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_hash[16])
+ 	/* with security is best be pedantic */
+ 	memset((char *) passwd_usc2le, 0, passwd_usc2le_len);
+ 	memset(&context, 0, sizeof(context));
+-	convert_to_usc2le_string_free(passwd, passwd_usc2le);
++	return TDS_SUCCEED;
+ }
+ 
+ 
+-static void
++static int
+ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_hash[16])
+ {
+ 	const char *user_name, *domain;
+@@ -192,10 +178,9 @@ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_has
+ 	const char *p;
+ 
+ 	unsigned char ntlm_hash[16];
+-	char buf[256];
+-	int buf_len = 0;
+-	const char *buf_usc2le;
+-	int buf_usc2le_len = 0;
++	char buf[128];
++	char buf_usc2le[512];
++	int buf_usc2le_len = 0, l, res;
+ 
+ 	user_name = tds_dstr_cstr(&tds->connection->user_name);
+ 	user_name_len = strlen(user_name);
+@@ -212,26 +197,31 @@ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_has
+ 	if (user_name_len > 128)
+ 		user_name_len = 128;
+ 	memcpy(buf, user_name, user_name_len);
+-
+ 	convert_to_upper(buf, user_name_len);
+ 
++	l = convert_to_usc2le_string(tds, buf, user_name_len, buf_usc2le);
++	if (l < 0)
++		return TDS_FAIL;
++	buf_usc2le_len = l;
++
+ 	if (domain_len > 128)
+ 		domain_len = 128;
+-	memcpy(buf + user_name_len, domain, domain_len);
+ 	/* Target is supposed to be case-sensitive */
+ 
+-	buf_len = user_name_len + domain_len;
++	l = convert_to_usc2le_string(tds, domain, domain_len, buf_usc2le + l);
++	if (l < 0)
++		return TDS_FAIL;
++	buf_usc2le_len += l;
+ 
+-	buf_usc2le = convert_to_usc2le_string(tds, buf, buf_len, &buf_usc2le_len);
+ 
+-	make_ntlm_hash(tds, passwd, ntlm_hash);
++	res = make_ntlm_hash(tds, passwd, ntlm_hash);
+ 	hmac_md5(ntlm_hash, (const unsigned char *) buf_usc2le, buf_usc2le_len, ntlm_v2_hash);
+ 
+ 	/* with security is best be pedantic */
+ 	memset(&ntlm_hash, 0, sizeof(ntlm_hash));
+ 	memset(buf, 0, sizeof(buf));
+ 	memset((char *) buf_usc2le, 0, buf_usc2le_len);
+-	convert_to_usc2le_string_free(buf, buf_usc2le);
++	return res;
+ }
+ 
+ 
+@@ -266,7 +256,7 @@ make_lm_v2_response(const unsigned char ntlm_v2_hash[16],
+  * @param flags NTLM flags from server side
+  * @param answer buffer where to store crypted password
+  */
+-static void
++static int
+ tds_answer_challenge(TDSSOCKET * tds,
+ 		     TDSCONNECTION * connection,
+ 		     const unsigned char *challenge,
+@@ -280,7 +270,7 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 	static const des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+ 	DES_KEY ks;
+ 	unsigned char hash[24], ntlm2_challenge[16];
+-	int ntlm_v;
++	int ntlm_v, res;
+ 
+ 	memset(answer, 0, sizeof(TDSANSWER));
+ 
+@@ -292,21 +282,26 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 		unsigned char ntlm_v2_hash[16];
+ 		const names_blob_prefix_t *names_blob_prefix;
+ 
+-		make_ntlm_v2_hash(tds, passwd, ntlm_v2_hash);
+-
+-		/* NTLMv2 response */
+-		/* Size of lm_v2_response is 16 + names_blob_len */
+-		/* FIXME check result */
+-		*ntlm_v2_response = make_lm_v2_response(ntlm_v2_hash, names_blob, names_blob_len, challenge);
++		res = make_ntlm_v2_hash(tds, passwd, ntlm_v2_hash);
++		if (res != TDS_SUCCEED)
++			return res;
+ 
+ 		/* LMv2 response */
+ 		/* Take client's chalenge from names_blob */
+ 		names_blob_prefix = (const names_blob_prefix_t *) names_blob;
+-		/* FIXME check result */
+ 		lm_v2_response = make_lm_v2_response(ntlm_v2_hash, names_blob_prefix->challenge, 8, challenge);
++		if (!lm_v2_response)
++			return TDS_FAIL;
+ 		memcpy(answer->lm_resp, lm_v2_response, 24);
+ 		free(lm_v2_response);
+-		return;
++
++		/* NTLMv2 response */
++		/* Size of lm_v2_response is 16 + names_blob_len */
++		*ntlm_v2_response = make_lm_v2_response(ntlm_v2_hash, names_blob, names_blob_len, challenge);
++		if (!*ntlm_v2_response)
++			return TDS_FAIL;
++
++		return TDS_SUCCEED;
+ 	}
+ 
+ 	if (!(*flags & 0x80000)) {
+@@ -351,7 +346,7 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 	*flags = 0x8201;
+ 
+ 	/* NTLM/NTLM2 response */
+-	make_ntlm_hash(tds, passwd, hash);
++	res = make_ntlm_hash(tds, passwd, hash);
+ 	memset(hash + 16, 0, 5);
+ 
+ 	tds_encrypt_answer(hash, challenge, answer->nt_resp);
+@@ -360,6 +355,7 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 	memset(&ks, 0, sizeof(ks));
+ 	memset(hash, 0, sizeof(hash));
+ 	memset(ntlm2_challenge, 0, sizeof(ntlm2_challenge));
++	return res;
+ }
+ 
+ 
+@@ -426,6 +422,7 @@ tds7_send_auth(TDSSOCKET * tds,
+ 	int host_name_len;
+ 	int password_len;
+ 	int domain_len;
++	int rc;
+ 
+ 	unsigned char *ntlm_v2_response = NULL;
+ 	unsigned int ntlm_response_len = 24;
+@@ -453,7 +450,10 @@ tds7_send_auth(TDSSOCKET * tds,
+ 	user_name = p + 1;
+ 	user_name_len = strlen(user_name);
+ 
+-	tds_answer_challenge(tds, connection, challenge, &flags, names_blob, names_blob_len, &answer, &ntlm_v2_response);
++	rc = tds_answer_challenge(tds, connection, challenge, &flags, names_blob, names_blob_len, &answer, &ntlm_v2_response);
++	if (rc != TDS_SUCCEED)
++		return rc;
++
+ 	ntlm_response_len = ntlm_v2_response ? 16 + names_blob_len : 24;
+ 	lm_response_len = ntlm_v2_response ? 0 : 24;
+ 	/* lm_response_len = 24; */
+
+commit 5b1d149c375860c7a31a7753b7e4c84213ab9f49
+Author: freddy77 <freddy77>
+Date:   Thu Jul 31 16:40:32 2008 +0000
+
+    indended tables
+
+diff --git a/doc/tds.html b/doc/tds.html
+index 2045388..7e5db61 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -614,14 +614,14 @@ data         data. See results for detail
+ <h4>Data info structure</h4>
+ <pre>
+   INT8          XCHAR[n]     INT8    INT32
+-+-------------+------------+-------+-----------------+
+++-------------+------------+-------+--------------------+
+ | name length | param name | flags | usertype (TDS 5.0) |
+-+-------------+------------+-------+-----------------+
+-  INT8   varies  varies     INT8[5]      INT8
+-+------+-------+----------+------------+---------------+
+-| type | size  | optional | collate    | locale        |
+++-------------+------------+-------+--------------------+
++  INT8   varies  varies     INT8[5]         INT8
+++------+-------+----------+---------------+------------------+
++| type | size  | optional | collate       | locale           |
+ |      | (opt) | (opt)    | info(TDS 7.1) | length (TDS 5.0) |
+-+------+-------+----------+------------+---------------+
+++------+-------+----------+---------------+------------------+
+ 
+ name length   parameter name length (0 if unused)
+ param name    parameter name
+@@ -645,10 +645,10 @@ locale length locale information length. Usually 0 (if not locale
+ <p>Under TDS 7.0+ is possible to chain multiple RPCs together. This is useful to limit packets and round-trips with server. RPCs can be chained using byte 0x80 (TDS 7.0/TDS 7.1) or 0xFF (TDS 7.2).</p>
+ 
+ <pre>
+-       INT8               INT8
+-+-----+------------------+-------------+-----+
++       INT8                     INT8
+++-----+------------------------+----------------+-----+
+ | RPC | 0x80 (TDS 7.0/TDS 7.1) | 0xFF (TDS 7.2) | RPC | ...
+-+-----+------------------+-------------+-----+
+++-----+------------------------+----------------+-----+
+ </pre>
+ 
+ <hr>
+@@ -988,11 +988,11 @@ No information. (1 byte, value=0 ?)
+ <p>The TDS 7.0 column_info is formatted as follows for each column:</p>
+ 
+ <pre>
+- INT16      INT16   INT8   varies  varies     INT8[5]      INT8          UCS2LE[n]
+-+----------+-------+------+-------+----------+------------+-------------+---------+
+-| usertype | flags | type | size  | optional | collate    | name length | name    | 
++ INT16      INT16   INT8   varies  varies     INT8[5]         INT8          UCS2LE[n]
+++----------+-------+------+-------+----------+---------------+-------------+---------+
++| usertype | flags | type | size  | optional | collate       | name length | name    | 
+ |          |       |      | (opt) | (opt)    | info(TDS 7.1) |             |         |
+-+----------+-------+------+-------+----------+------------+-------------+---------+
+++----------+-------+------+-------+----------+---------------+-------------+---------+
+ 
+ usertype	type modifier
+ flags		bit flags
+@@ -1127,11 +1127,11 @@ optional
+ <p>column info:</p>
+ 
+ <pre>
+- INT8       INT8      INT32      INT8     varies  INT8            varies
+-+----------+---------+----------+--------+-------+---------------+-------------+
+-| operator | operand | usertype | column | size  | locale length | locale info |
++ INT8       INT8      INT32      INT8     varies  INT8               varies
+++----------+---------+----------+--------+-------+------------------+----------------+
++| operator | operand | usertype | column | size  | locale length    | locale info    |
+ |          |         |          |  type  | (opt) |  info (TDS 5.0)  | (TDS 5.0)      |
+-+----------+---------+----------+--------+-------+---------------+-------------+
+++----------+---------+----------+--------+-------+------------------+----------------+
+ 
+ operator      operator
+               0x4b COUNT
+@@ -1283,10 +1283,10 @@ to a column is the number
+ | length | msg number | state | level |
+ +--------+------------+-------+-------+
+ 
+- INT16      XCHAR[n]  INT8       XCHAR[n]  INT8       XCHAR[n]  INT16          INT32
+-+----------+---------+----------+---------+----------+---------+--------------+--------------+
++ INT16      XCHAR[n]  INT8       XCHAR[n]  INT8       XCHAR[n]  INT16             INT32
+++----------+---------+----------+---------+----------+---------+-----------------+-----------------+
+ | m length | message | s length | server  | p length | process | line#(TDS 7.1-) | line# (TDS 7.2) |
+-+----------+---------+----------+---------+----------+---------+--------------+--------------+
+++----------+---------+----------+---------+----------+---------+-----------------+-----------------+
+ 
+ length		Length of packet
+ msg number	SQL message number
+@@ -1490,10 +1490,10 @@ column info        <a href="#colInfo">column info</a>
+ <b class="section">Done Inside Process (0xFF 255)</b><br>
+ 
+ <pre>
+- INT16       INT16     INT32               INT64
+-+-----------+---------+-------------------+------------------+
++ INT16       INT16     INT32                  INT64
+++-----------+---------+----------------------+---------------------+
+ | bit flags | unknown | row count (TDS 7.1-) | row count (TDS 7.2) |
+-+-----------+---------+-------------------+------------------+
+++-----------+---------+----------------------+---------------------+
+ 
+ Fields:
+ bit flags          0x01 more results
+@@ -1530,7 +1530,7 @@ The following people have contributed to this document:
+ (short list)
+ 
+ <h2>Document Status </h2>
+-<P>$Id: tds.html,v 1.39 2008/07/31 10:13:38 jklowden Exp $</p>
++<P>$Id: tds.html,v 1.40 2008/07/31 16:40:32 freddy77 Exp $</p>
+ <p>
+     <a href="http://validator.w3.org/check?uri=referer"><img
+         src="http://www.w3.org/Icons/valid-html401"
+
+commit 8a825bb497d8801c39fafec0005c11f13da631ea
+Author: freddy77 <freddy77>
+Date:   Wed Aug 6 07:40:10 2008 +0000
+
+    keep packet size to safe values
+
+diff --git a/ChangeLog b/ChangeLog
+index 1bef97c..7e437fa 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Aug 06 09:32:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c src/tds/login.c src/tds/mem.c src/tds/token.c:
++	- keep packet size to safe values
++
+ Thu Jul 31 16:53:35 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c: removed important FIXMEs
+ 
+@@ -504,4 +508,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2574 2008/07/31 14:57:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2575 2008/08/06 07:40:10 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 9be062a..b70310c 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.133 2008/01/18 13:37:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.134 2008/08/06 07:40:15 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -495,8 +495,9 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ 	if (!strcmp(option, TDS_STR_VERSION)) {
+ 		tds_config_verstr(value, connection);
+ 	} else if (!strcmp(option, TDS_STR_BLKSZ)) {
+-		if (atoi(value))
+-			connection->block_size = atoi(value);
++		int val = atoi(value);
++		if (val >= 512 && val < 65536)
++			connection->block_size = val;
+ 	} else if (!strcmp(option, TDS_STR_SWAPDT)) {
+ 		connection->broken_dates = tds_config_boolean(value);
+ 	} else if (!strcmp(option, TDS_STR_SWAPMNY)) {
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 6fe7f1c..bf22c20 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.174 2008/07/11 09:25:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.175 2008/08/06 07:40:16 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -628,7 +628,7 @@ tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	tds_put_byte(tds, 1);
+ 
+ 	/* network packet size */
+-	if (connection->block_size < 1000000 && connection->block_size)
++	if (connection->block_size < 65536 && connection->block_size > 0)
+ 		sprintf(blockstr, "%d", connection->block_size);
+ 	else
+ 		strcpy(blockstr, "512");
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 35953b2..14ec4f9 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.176 2008/05/26 13:56:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.177 2008/08/06 07:40:17 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -991,7 +991,8 @@ tds_realloc_socket(TDSSOCKET * tds, int bufsize)
+ 	if (tds->env.block_size == bufsize)
+ 		return tds;
+ 
+-	if ((new_out_buf = (unsigned char *) realloc(tds->out_buf, bufsize + TDS_ADDITIONAL_SPACE)) != NULL) {
++	if (tds->out_pos <= bufsize && bufsize > 0 && 
++	    (new_out_buf = (unsigned char *) realloc(tds->out_buf, bufsize + TDS_ADDITIONAL_SPACE)) != NULL) {
+ 		tds->out_buf = new_out_buf;
+ 		tds->env.block_size = bufsize;
+ 		return tds;
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 07717c8..e91c316 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.349 2008/07/15 15:20:54 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.350 2008/08/06 07:40:17 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2408,14 +2408,13 @@ tds_process_env_chg(TDSSOCKET * tds)
+ 	switch (type) {
+ 	case TDS_ENV_PACKSIZE:
+ 		new_block_size = atoi(newval);
+-		if (new_block_size > tds->env.block_size) {
+-			tdsdump_log(TDS_DBG_INFO1, "increasing block size from %s to %d\n", oldval, new_block_size);
++		if (new_block_size >= 512) {
++			tdsdump_log(TDS_DBG_INFO1, "changing block size from %s to %d\n", oldval, new_block_size);
+ 			/* 
+-			 * I'm not aware of any way to shrink the 
+-			 * block size but if it is possible, we don't 
+-			 * handle it.
++			 * Is possible to have a shrink if server limits packet
++			 * size more than what we specified
+ 			 */
+-			/* Reallocate buffer if impossible (strange values from server or out of memory) use older buffer */
++			/* Reallocate buffer if possible (strange values from server or out of memory) use older buffer */
+ 			tds_realloc_socket(tds, new_block_size);
+ 		}
+ 		break;
+
+commit 8d77d55d9e20c64c8c86f0d5d6956d5edea307af
+Author: freddy77 <freddy77>
+Date:   Thu Aug 7 07:18:51 2008 +0000
+
+    use NTLMv2 if possible
+
+diff --git a/ChangeLog b/ChangeLog
+index 7e437fa..87c84c9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 07 09:17:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/challenge.c: use NTLMv2 if possible
++
+ Wed Aug 06 09:32:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c src/tds/login.c src/tds/mem.c src/tds/token.c:
+ 	- keep packet size to safe values
+@@ -508,4 +511,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2575 2008/08/06 07:40:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2576 2008/08/07 07:18:51 freddy77 Exp $
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index 5476d16..a053d94 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.33 2008/07/31 14:57:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.34 2008/08/07 07:18:53 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -270,13 +270,35 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 	static const des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+ 	DES_KEY ks;
+ 	unsigned char hash[24], ntlm2_challenge[16];
+-	int ntlm_v, res;
++	int res;
+ 
+ 	memset(answer, 0, sizeof(TDSANSWER));
+ 
+-	ntlm_v = 2;
++	if (!(*flags & 0x80000)) {
++		/* NTLM */
++		unsigned char passwd_buf[MAX_PW_SZ];
++
++		/* convert password to upper and pad to 14 chars */
++		memset(passwd_buf, 0, MAX_PW_SZ);
++		len = strlen(passwd);
++		if (len > MAX_PW_SZ)
++			len = MAX_PW_SZ;
++		for (i = 0; i < len; i++)
++			passwd_buf[i] = toupper((unsigned char) passwd[i]);
++
++		/* hash the first 7 characters */
++		tds_convert_key(passwd_buf, &ks);
++		tds_des_ecb_encrypt(&magic, sizeof(magic), &ks, (hash + 0));
+ 
+-	if (ntlm_v == 2) {
++		/* hash the second 7 characters */
++		tds_convert_key(passwd_buf + 7, &ks);
++		tds_des_ecb_encrypt(&magic, sizeof(magic), &ks, (hash + 8));
++
++		memset(hash + 16, 0, 5);
++
++		tds_encrypt_answer(hash, challenge, answer->lm_resp);
++		memset(passwd_buf, 0, sizeof(passwd_buf));
++	} else if (names_blob_len > 0) {
+ 		/* NTLMv2 */
+ 		unsigned char *lm_v2_response;
+ 		unsigned char ntlm_v2_hash[16];
+@@ -287,7 +309,7 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 			return res;
+ 
+ 		/* LMv2 response */
+-		/* Take client's chalenge from names_blob */
++		/* Take client's challenge from names_blob */
+ 		names_blob_prefix = (const names_blob_prefix_t *) names_blob;
+ 		lm_v2_response = make_lm_v2_response(ntlm_v2_hash, names_blob_prefix->challenge, 8, challenge);
+ 		if (!lm_v2_response)
+@@ -302,36 +324,10 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 			return TDS_FAIL;
+ 
+ 		return TDS_SUCCEED;
+-	}
+-
+-	if (!(*flags & 0x80000)) {
+-		/* NTLM */
+-		unsigned char passwd_buf[MAX_PW_SZ];
+-
+-		/* convert password to upper and pad to 14 chars */
+-		memset(passwd_buf, 0, MAX_PW_SZ);
+-		len = strlen(passwd);
+-		if (len > MAX_PW_SZ)
+-			len = MAX_PW_SZ;
+-		for (i = 0; i < len; i++)
+-			passwd_buf[i] = toupper((unsigned char) passwd[i]);
+-
+-		/* hash the first 7 characters */
+-		tds_convert_key(passwd_buf, &ks);
+-		tds_des_ecb_encrypt(&magic, sizeof(magic), &ks, (hash + 0));
+-
+-		/* hash the second 7 characters */
+-		tds_convert_key(passwd_buf + 7, &ks);
+-		tds_des_ecb_encrypt(&magic, sizeof(magic), &ks, (hash + 8));
+-
+-		memset(hash + 16, 0, 5);
+-
+-		tds_encrypt_answer(hash, challenge, answer->lm_resp);
+-		memset(passwd_buf, 0, sizeof(passwd_buf));
+ 	} else {
++		/* NTLM2 */
+ 		MD5_CTX md5_ctx;
+ 
+-		/* NTLM2 */
+ 		generate_random_buffer(hash, 8);
+ 		memset(hash + 8, 0, 16);
+ 		memcpy(answer->lm_resp, hash, 24);
+
+commit 856577b6d655e5a97c48d2f564a800d6d5420070
+Author: freddy77 <freddy77>
+Date:   Thu Aug 7 10:06:05 2008 +0000
+
+    small network optimization
+
+diff --git a/ChangeLog b/ChangeLog
+index 87c84c9..49eb3bf 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 07 12:05:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: small network optimization
++
+ Thu Aug 07 09:17:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c: use NTLMv2 if possible
+ 
+@@ -511,4 +514,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2576 2008/08/07 07:18:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2577 2008/08/07 10:06:05 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 14d38a6..3cd4b49 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.76 2008/07/24 22:04:50 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.77 2008/08/07 10:06:08 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -1025,7 +1025,8 @@ tds_ssl_write(BIO *b, const char* data, int len)
+ 
+ 	if (tds->tls_session) {
+ 		/* write to socket directly */
+-		return tds_goodwrite(tds, data, len, 1);
++		/* TODO use cork if available here to fluch only on last chunk of packet ?? */
++		return tds_goodwrite(tds, data, len, tds->out_buf[1]);
+ 	}
+ 	/* write crypted data inside normal TDS packets */
+ 	tds_put_n(tds, data, len);
+
+commit c818e93949c657d13904596f6e4e2bb1c08306f5
+Author: freddy77 <freddy77>
+Date:   Fri Aug 8 13:43:50 2008 +0000
+
+    add a note
+
+diff --git a/TODO.freddy b/TODO.freddy
+index 663dd53..d60b592 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -52,6 +52,10 @@ test to review
+ - getdata.c ??
+ - putdata.c ??
+ - wchar.c
++Is it possible to support direct binding for parameters using different
++encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
++possible changing TDSCOLUMN->char_conv. Some work should be done in 
++src/tds/iconv.c in order to get a valid char_conv changing client encoding.
+ 
+ Other
+ -----
+
+commit db3a6f5bc4e216a5d787461d4bbb828bb5c5d92b
+Author: jklowden <jklowden>
+Date:   Wed Aug 13 04:09:32 2008 +0000
+
+    clarified log messages
+
+diff --git a/ChangeLog b/ChangeLog
+index 49eb3bf..26afd46 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Aug 13 00:08:28 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* src/tds/iconv.c clarified log messages
++
+ Thu Aug 07 12:05:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: small network optimization
+ 
+@@ -514,4 +517,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2577 2008/08/07 10:06:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2578 2008/08/13 04:09:32 jklowden Exp $
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 81d48e3..6f0c4ae 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.132 2007/01/02 20:47:05 jklowden Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.133 2008/08/13 04:09:32 jklowden Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -101,7 +101,7 @@ tds_iconv_init(void)
+ 
+ 	/* fast tests for GNU-iconv */
+ 	cd = tds_sys_iconv_open("ISO-8859-1", "UTF-8");
+-	if (cd != (iconv_t) - 1) {
++	if (cd != (iconv_t) -1) {
+ 		iconv_names[POS_ISO1] = "ISO-8859-1";
+ 		iconv_names[POS_UTF8] = "UTF-8";
+ 		tds_sys_iconv_close(cd);
+@@ -118,7 +118,7 @@ tds_iconv_init(void)
+ 					continue;
+ 
+ 				cd = tds_sys_iconv_open(iconv_aliases[i].alias, iconv_aliases[j].alias);
+-				if (cd != (iconv_t) - 1) {
++				if (cd != (iconv_t) -1) {
+ 					iconv_names[POS_ISO1] = iconv_aliases[i].alias;
+ 					iconv_names[POS_UTF8] = iconv_aliases[j].alias;
+ 					tds_sys_iconv_close(cd);
+@@ -135,12 +135,12 @@ tds_iconv_init(void)
+ 
+ 	/* now search for UCS-2 */
+ 	cd = tds_sys_iconv_open(iconv_names[POS_ISO1], "UCS-2LE");
+-	if (cd != (iconv_t) - 1) {
++	if (cd != (iconv_t) -1) {
+ 		iconv_names[POS_UCS2LE] = "UCS-2LE";
+ 		tds_sys_iconv_close(cd);
+ 	}
+ 	cd = tds_sys_iconv_open(iconv_names[POS_ISO1], "UCS-2BE");
+-	if (cd != (iconv_t) - 1) {
++	if (cd != (iconv_t) -1) {
+ 		iconv_names[POS_UCS2BE] = "UCS-2BE";
+ 		tds_sys_iconv_close(cd);
+ 	}
+@@ -152,7 +152,7 @@ tds_iconv_init(void)
+ 				continue;
+ 
+ 			cd = tds_sys_iconv_open(iconv_aliases[i].alias, iconv_names[POS_ISO1]);
+-			if (cd != (iconv_t) - 1) {
++			if (cd != (iconv_t) -1) {
+ 				char ib[1];
+ 				char ob[4];
+ 				size_t il, ol;
+@@ -194,7 +194,7 @@ tds_iconv_init(void)
+ 	ucs2name = iconv_names[POS_UCS2LE] ? iconv_names[POS_UCS2LE] : iconv_names[POS_UCS2BE];
+ 
+ 	for (i = 0; i < 4; ++i)
+-		tdsdump_log(TDS_DBG_INFO1, "names for %s: %s\n", canonic_charsets[i].name,
++		tdsdump_log(TDS_DBG_INFO1, "local name for %s is %s\n", canonic_charsets[i].name,
+ 			    iconv_names[i] ? iconv_names[i] : "(null)");
+ 
+ 	/* success (it should always occurs) */
+@@ -214,13 +214,13 @@ tds_get_iconv_name(int charset)
+ 
+ 	/* try using canonic name and UTF-8 and UCS2 */
+ 	cd = tds_sys_iconv_open(iconv_names[POS_UTF8], canonic_charsets[charset].name);
+-	if (cd != (iconv_t) - 1) {
++	if (cd != (iconv_t) -1) {
+ 		iconv_names[charset] = canonic_charsets[charset].name;
+ 		tds_sys_iconv_close(cd);
+ 		return;
+ 	}
+ 	cd = tds_sys_iconv_open(ucs2name, canonic_charsets[charset].name);
+-	if (cd != (iconv_t) - 1) {
++	if (cd != (iconv_t) -1) {
+ 		iconv_names[charset] = canonic_charsets[charset].name;
+ 		tds_sys_iconv_close(cd);
+ 		return;
+@@ -232,14 +232,14 @@ tds_get_iconv_name(int charset)
+ 			continue;
+ 
+ 		cd = tds_sys_iconv_open(iconv_names[POS_UTF8], iconv_aliases[i].alias);
+-		if (cd != (iconv_t) - 1) {
++		if (cd != (iconv_t) -1) {
+ 			iconv_names[charset] = iconv_aliases[i].alias;
+ 			tds_sys_iconv_close(cd);
+ 			return;
+ 		}
+ 
+ 		cd = tds_sys_iconv_open(ucs2name, iconv_aliases[i].alias);
+-		if (cd != (iconv_t) - 1) {
++		if (cd != (iconv_t) -1) {
+ 			iconv_names[charset] = iconv_aliases[i].alias;
+ 			tds_sys_iconv_close(cd);
+ 			return;
+@@ -263,10 +263,10 @@ tds_iconv_reset(TDSICONV *conv)
+ 	conv->client_charset.max_bytes_per_char = 1;
+ 
+ 	conv->server_charset.name = conv->client_charset.name = "";
+-	conv->to_wire = (iconv_t) - 1;
+-	conv->to_wire2 = (iconv_t) - 1;
+-	conv->from_wire = (iconv_t) - 1;
+-	conv->from_wire2 = (iconv_t) - 1;
++	conv->to_wire = (iconv_t) -1;
++	conv->to_wire2 = (iconv_t) -1;
++	conv->from_wire = (iconv_t) -1;
++	conv->from_wire2 = (iconv_t) -1;
+ }
+ 
+ /**
+@@ -334,6 +334,8 @@ tds_iconv_open(TDSSOCKET * tds, const char *charset)
+ 	TDS_ENCODING *client = &tds->char_convs[client2ucs2]->client_charset;
+ 	TDS_ENCODING *server = &tds->char_convs[client2ucs2]->server_charset;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "tds_iconv_open(%p, %s)\n", tds, charset);
++
+ #if !HAVE_ICONV_ALWAYS
+ 
+ 	strcpy(client->name, "ISO-8859-1");
+@@ -360,7 +362,9 @@ tds_iconv_open(TDSSOCKET * tds, const char *charset)
+ 	/* 
+ 	 * Client <-> UCS-2 (client2ucs2)
+ 	 */
+-	tdsdump_log(TDS_DBG_FUNC, "iconv to convert client-side data to the \"%s\" character set\n", charset);
++	tdsdump_log(TDS_DBG_FUNC, "setting up conversions for client charset \"%s\"\n", charset);
++
++	tdsdump_log(TDS_DBG_FUNC, "preparing iconv for \"%s\" <-> \"%s\" conversion\n", charset, UCS_2LE);
+ 
+ 	fOK = tds_iconv_info_init(tds->char_convs[client2ucs2], charset, UCS_2LE);
+ 	if (!fOK)
+@@ -382,6 +386,7 @@ tds_iconv_open(TDSSOCKET * tds, const char *charset)
+ 	 */
+ 	tds->char_convs[client2server_chardata]->flags = TDS_ENCODING_MEMCPY;
+ 	if (tds->env.charset) {
++		tdsdump_log(TDS_DBG_FUNC, "preparing iconv for \"%s\" <-> \"%s\" conversion\n", charset, tds->env.charset);
+ 		fOK = tds_iconv_info_init(tds->char_convs[client2server_chardata], charset, tds->env.charset);
+ 		if (!fOK)
+ 			return;
+@@ -396,8 +401,10 @@ tds_iconv_open(TDSSOCKET * tds, const char *charset)
+ 		if (tds->env.charset)
+ 			name = tds->env.charset;
+ 	}
++	tdsdump_log(TDS_DBG_FUNC, "preparing iconv for \"%s\" <-> \"%s\" conversion\n", "ISO-8859-1", name);
+ 	fOK = tds_iconv_info_init(tds->char_convs[iso2server_metadata], "ISO-8859-1", name);
+ 
++	tdsdump_log(TDS_DBG_FUNC, "tds_iconv_open: done\n");
+ #endif
+ }
+ 
+@@ -420,10 +427,10 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 
+ 	assert(client_name && server_name);
+ 
+-	assert(char_conv->to_wire == (iconv_t) - 1);
+-	assert(char_conv->to_wire2 == (iconv_t) - 1);
+-	assert(char_conv->from_wire == (iconv_t) - 1);
+-	assert(char_conv->from_wire2 == (iconv_t) - 1);
++	assert(char_conv->to_wire == (iconv_t) -1);
++	assert(char_conv->to_wire2 == (iconv_t) -1);
++	assert(char_conv->from_wire == (iconv_t) -1);
++	assert(char_conv->from_wire2 == (iconv_t) -1);
+ 
+ 	client_canonical = tds_canonical_charset(client_name);
+ 	server_canonical = tds_canonical_charset(server_name);
+@@ -443,8 +450,8 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 
+ 	/* special case, same charset, no conversion */
+ 	if (client_canonical == server_canonical) {
+-		char_conv->to_wire = (iconv_t) - 1;
+-		char_conv->from_wire = (iconv_t) - 1;
++		char_conv->to_wire = (iconv_t) -1;
++		char_conv->from_wire = (iconv_t) -1;
+ 		char_conv->flags = TDS_ENCODING_MEMCPY;
+ 		return 1;
+ 	}
+@@ -471,8 +478,8 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 
+ 	/* names available ?? */
+ 	if (!iconv_names[client_canonical][0] || !iconv_names[server_canonical][0]) {
+-		char_conv->to_wire = (iconv_t) - 1;
+-		char_conv->from_wire = (iconv_t) - 1;
++		char_conv->to_wire = (iconv_t) -1;
++		char_conv->from_wire = (iconv_t) -1;
+ 		char_conv->flags = TDS_ENCODING_MEMCPY;
+ 		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: use memcpy to convert \"%s\"->\"%s\"\n", client->name,
+ 			    server->name);
+@@ -480,17 +487,17 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 	}
+ 
+ 	char_conv->to_wire = tds_sys_iconv_open(iconv_names[server_canonical], iconv_names[client_canonical]);
+-	if (char_conv->to_wire == (iconv_t) - 1) {
++	if (char_conv->to_wire == (iconv_t) -1) {
+ 		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: cannot convert \"%s\"->\"%s\"\n", client->name, server->name);
+ 	}
+ 
+ 	char_conv->from_wire = tds_sys_iconv_open(iconv_names[client_canonical], iconv_names[server_canonical]);
+-	if (char_conv->from_wire == (iconv_t) - 1) {
++	if (char_conv->from_wire == (iconv_t) -1) {
+ 		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: cannot convert \"%s\"->\"%s\"\n", server->name, client->name);
+ 	}
+ 
+ 	/* try indirect conversions */
+-	if (char_conv->to_wire == (iconv_t) - 1 || char_conv->from_wire == (iconv_t) - 1) {
++	if (char_conv->to_wire == (iconv_t) -1 || char_conv->from_wire == (iconv_t) -1) {
+ 		tds_iconv_info_close(char_conv);
+ 
+ 		/* TODO reuse some conversion, client charset is usually constant in all connection (or ISO8859-1) */
+@@ -499,8 +506,8 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 		char_conv->from_wire = tds_sys_iconv_open(iconv_names[POS_UTF8], iconv_names[server_canonical]);
+ 		char_conv->from_wire2 = tds_sys_iconv_open(iconv_names[client_canonical], iconv_names[POS_UTF8]);
+ 
+-		if (char_conv->to_wire == (iconv_t) - 1 || char_conv->to_wire2 == (iconv_t) - 1
+-		    || char_conv->from_wire == (iconv_t) - 1 || char_conv->from_wire2 == (iconv_t) - 1) {
++		if (char_conv->to_wire == (iconv_t) -1 || char_conv->to_wire2 == (iconv_t) -1
++		    || char_conv->from_wire == (iconv_t) -1 || char_conv->from_wire2 == (iconv_t) -1) {
+ 
+ 			tds_iconv_info_close(char_conv);
+ 			tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: cannot convert \"%s\"->\"%s\" indirectly\n",
+@@ -513,7 +520,7 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 	
+ 	/* TODO, do some optimizations like UCS2 -> UTF8 min,max = 2,2 (UCS2) and 1,4 (UTF8) */
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: converting \"%s\"->\"%s\"\n", client->name, server->name);
++	/* tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: converting \"%s\"->\"%s\"\n", client->name, server->name); */
+ 
+ 	return 1;
+ }
+@@ -523,7 +530,7 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ static void
+ _iconv_close(iconv_t * cd)
+ {
+-	static const iconv_t invalid = (iconv_t) - 1;
++	static const iconv_t invalid = (iconv_t) -1;
+ 
+ 	if (*cd != invalid) {
+ 		tds_sys_iconv_close(*cd);
+@@ -606,7 +613,7 @@ size_t
+ tds_iconv(TDSSOCKET * tds, const TDSICONV * conv, TDS_ICONV_DIRECTION io,
+ 	  const char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft)
+ {
+-	static const iconv_t invalid = (iconv_t) - 1;
++	static const iconv_t invalid = (iconv_t) -1;
+ 	const TDS_ENCODING *input_charset = NULL;
+ 	const char *output_charset_name = NULL;
+ 
+@@ -851,7 +858,7 @@ tds_iconv_fread(iconv_t cd, FILE * stream, size_t field_len, size_t term_len, ch
+ 	/*
+ 	 * If cd isn't valid, it's just an indication that this column needs no conversion.  
+ 	 */
+-	if (cd == (iconv_t) - 1) {
++	if (cd == (iconv_t) -1) {
+ 		assert(field_len <= *outbytesleft);
+ 		if (field_len > 0) {
+ 			if (1 != fread(outbuf, field_len, 1, stream)) {
+@@ -1096,7 +1103,7 @@ skip_one_input_sequence(iconv_t cd, const TDS_ENCODING * charset, const char **i
+ 	/* init destination conversion */
+ 	/* TODO use largest fixed size for this platform */
+ 	cd2 = tds_sys_iconv_open("UCS-4", charset->name);
+-	if (cd2 == (iconv_t) - 1)
++	if (cd2 == (iconv_t) -1)
+ 		return 0;
+ 
+ 	/* add part of input */
+
+commit 2b2fa088a623afc76cf6adf56ef1ca28f5e15621
+Author: jklowden <jklowden>
+Date:   Wed Aug 13 19:08:30 2008 +0000
+
+    advice about unicode strings
+
+diff --git a/ChangeLog b/ChangeLog
+index 26afd46..ce48b41 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Aug 13 15:06:17 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml advice about unicode strings
++	* src/dblib/dblib.c tdserror for setting invalid TDS version
++
+ Wed Aug 13 00:08:28 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/iconv.c clarified log messages
+ 
+@@ -517,4 +521,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2578 2008/08/13 04:09:32 jklowden Exp $
++$Id: ChangeLog,v 1.2579 2008/08/13 19:08:30 jklowden Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 317983c..dc9a961 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/05/06 17:42:44 $</date>
+-		<releaseinfo>$Revision: 1.113 $</releaseinfo>
++		<date>$Date: 2008/08/13 19:08:31 $</date>
++		<releaseinfo>$Revision: 1.114 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.113 $</>
+-<member>$Date: 2008/05/06 17:42:44 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.113 2008/05/06 17:42:44 jklowden Exp $.</>
++<member>$Revision: 1.114 $</>
++<member>$Date: 2008/08/13 19:08:31 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.114 2008/08/13 19:08:31 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/05/06 17:42:44 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/08/13 19:08:31 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1822,6 +1822,34 @@ In the following example, a server named <literal>mssql</literal> will return da
+ 			<para>
+ It is also worth clarifying that <acronym>TDS 7.0</> and above do not accept any specified character set during login, as 4.2 does.  A <acronym>TDS 7.0</> login packet uses <acronym>UCS-2</>.  
+ 			</para>
++		<sect2 id="localization.servernote"><title>Microsoft Server Note</title>
++			<para>
++String literals in SQL must be prefixed with 'N' unless the enclosed string can be represented in the server's <emphasis>single-byte</> character set, irrespective of the column's datatype.  For example, in the SQL statement 
++
++<para><informalexample>
++INSERT INTO tablename (greeting) VALUES ('Hallå')
++</informalexample></para>
++
++the string is subject to somewhat surprising treatment by the server.  
++			</para>
++			<para>
++When the server parses the SQL, it extracts the data values for insertion (or update, or comparison, etc.)  Unprefixed strings are converted to the single-byte character set of the server/database.<footnote><para>The precise rules are unknown to the author.</para></footnote>   Inserted data are then of course stored in the column.  In the case of UCS-2 columns &mdash; nchar/nvarchar/ntext &mdash; the value stored is that which results from a <emphasis>second</> conversion: from the single-byte form to the <acronym>UCS-2</> form.  
++			</para>
++			<para>
++The <emphasis>only</> safe way to enclose strings in SQL text is with an 'N' prefix:
++
++<para><informalexample>
++INSERT INTO tablename (greeting) VALUES (N'Hallå')
++</informalexample></para>
++
++			</para>
++			<formalpara><title>Commentary</>
++What's surprising about this?  Versions 7.0 and later of the TDS protocol use UCS-2 to send SQL text.  No matter how your local client is configured &mdash; with <acronym>UCS-2</> or <acronym>ISO 8859-1</> or anything else &mdash; it's converted to <acronym>UCS-2</> before it's sent to the server.  And obviously arrives at the server as <acronym>UCS-2</>.  If the column into which it's being inserted is also <acronym>UCS-2</>, there's no need to <empahsis>any</> conversion, much less two, and <emphasis>certainly</> no need to lose infomation.  
++			</para>
++			<para>
++Why this happens is anyone's guess.  Here's one: it makes the datatype of the column unimportant.  Regardless of whether you use char/varchar/text or nchar/nvarchar/ntext or a mixture of the two, the arriving SQL (if naïvely written) will store exactly the same characters.  
++			</para>
++		</sect2>
+ 		</sect1>
+ 		<sect1 id="domains">
+ 			<title>Domain Logins</title>
+
+commit a0aacc86b9cf232b241d3755d0bcec46c77870be
+Author: jklowden <jklowden>
+Date:   Wed Aug 13 19:08:38 2008 +0000
+
+    tdserror for setting invalid TDS version
+
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 0686e7c..e43c290 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.327 2008/07/08 19:41:25 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.328 2008/08/13 19:08:38 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -5659,6 +5659,8 @@ dbsetversion(DBINT version)
+ 	default:
+ 		break;
+ 	}
++	
++	dbperror(NULL, SYBEIVERS, 0);
+ 	return FAIL;
+ }
+ 
+
+commit 80b52e66222897e1be842080fb0701b6208237c5
+Author: freddy77 <freddy77>
+Date:   Thu Aug 14 08:49:22 2008 +0000
+
+    add "asa database" option to specify ASA database
+
+diff --git a/ChangeLog b/ChangeLog
+index ce48b41..9ecfb22 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Aug 14 10:48:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/config.c:
++	- add "asa database" option to specify ASA database
++
+ Wed Aug 13 15:06:17 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml advice about unicode strings
+ 	* src/dblib/dblib.c tdserror for setting invalid TDS version
+@@ -521,4 +525,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2579 2008/08/13 19:08:30 jklowden Exp $
++$Id: ChangeLog,v 1.2580 2008/08/14 08:49:22 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 42d9978..bdce7a6 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.292 2008/07/08 17:16:55 jklowden Exp $ */
++/* $Id: tds.h,v 1.293 2008/08/14 08:49:22 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -809,6 +809,7 @@ typedef enum tds_encryption_level {
+ #define TDS_STR_APPENDMODE	"dump file append"
+ #define TDS_STR_DATEFMT	"date format"
+ #define TDS_STR_INSTANCE "instance"
++#define TDS_STR_ASA_DATABASE	"asa database"
+ #define TDS_STR_ENCRYPTION	 "encryption"
+ /* conf values */
+ #define TDS_STR_ENCRYPTION_OFF	 "off"
+diff --git a/src/tds/config.c b/src/tds/config.c
+index b70310c..9dcaf05 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.134 2008/08/06 07:40:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.135 2008/08/14 08:49:22 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -547,6 +547,8 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ 		tds_dstr_copy(&connection->instance_name, value);
+ 	} else if (!strcmp(option, TDS_STR_ENCRYPTION)) {
+ 		tds_config_encryption(value, connection);
++	} else if (!strcmp(option, TDS_STR_ASA_DATABASE)) {
++		tds_dstr_copy(&connection->server_name, value);
+ 	} else {
+ 		tdsdump_log(TDS_DBG_INFO1, "UNRECOGNIZED option '%s' ... ignoring.\n", option);
+ 	}
+@@ -555,7 +557,7 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ static void
+ tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login)
+ {
+-	if (!tds_dstr_isempty(&login->server_name)) {
++	if (!tds_dstr_isempty(&login->server_name) && tds_dstr_isempty(&connection->server_name)) {
+ 		tds_dstr_dup(&connection->server_name, &login->server_name);
+ 	}
+ 	if (login->major_version || login->minor_version) {
+
+commit 5250e7770549a616429440dfa7496e50ff50ec9b
+Author: freddy77 <freddy77>
+Date:   Thu Aug 14 09:14:48 2008 +0000
+
+    make openjade happy
+
+diff --git a/ChangeLog b/ChangeLog
+index 9ecfb22..a362cd4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 14 11:14:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: make openjade happy
++
+ Thu Aug 14 10:48:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/config.c:
+ 	- add "asa database" option to specify ASA database
+@@ -525,4 +528,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2580 2008/08/14 08:49:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2581 2008/08/14 09:14:48 freddy77 Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index dc9a961..bc85603 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/08/13 19:08:31 $</date>
+-		<releaseinfo>$Revision: 1.114 $</releaseinfo>
++		<date>$Date: 2008/08/14 09:14:48 $</date>
++		<releaseinfo>$Revision: 1.115 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.114 $</>
+-<member>$Date: 2008/08/13 19:08:31 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.114 2008/08/13 19:08:31 jklowden Exp $.</>
++<member>$Revision: 1.115 $</>
++<member>$Date: 2008/08/14 09:14:48 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.115 2008/08/14 09:14:48 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/08/13 19:08:31 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/08/14 09:14:48 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1826,9 +1826,9 @@ It is also worth clarifying that <acronym>TDS 7.0</> and above do not accept any
+ 			<para>
+ String literals in SQL must be prefixed with 'N' unless the enclosed string can be represented in the server's <emphasis>single-byte</> character set, irrespective of the column's datatype.  For example, in the SQL statement 
+ 
+-<para><informalexample>
+-INSERT INTO tablename (greeting) VALUES ('Hallå')
+-</informalexample></para>
++<informalexample><screen>
++INSERT INTO tablename (greeting) VALUES ('Hall&aring;')
++</screen></informalexample>
+ 
+ the string is subject to somewhat surprising treatment by the server.  
+ 			</para>
+@@ -1838,14 +1838,15 @@ When the server parses the SQL, it extracts the data values for insertion (or up
+ 			<para>
+ The <emphasis>only</> safe way to enclose strings in SQL text is with an 'N' prefix:
+ 
+-<para><informalexample>
+-INSERT INTO tablename (greeting) VALUES (N'Hallå')
+-</informalexample></para>
++<informalexample><screen>
++INSERT INTO tablename (greeting) VALUES (N'Hall&aring;')
++</screen></informalexample>
+ 
+ 			</para>
+ 			<formalpara><title>Commentary</>
+-What's surprising about this?  Versions 7.0 and later of the TDS protocol use UCS-2 to send SQL text.  No matter how your local client is configured &mdash; with <acronym>UCS-2</> or <acronym>ISO 8859-1</> or anything else &mdash; it's converted to <acronym>UCS-2</> before it's sent to the server.  And obviously arrives at the server as <acronym>UCS-2</>.  If the column into which it's being inserted is also <acronym>UCS-2</>, there's no need to <empahsis>any</> conversion, much less two, and <emphasis>certainly</> no need to lose infomation.  
++<para>What's surprising about this?  Versions 7.0 and later of the TDS protocol use UCS-2 to send SQL text.  No matter how your local client is configured &mdash; with <acronym>UCS-2</> or <acronym>ISO 8859-1</> or anything else &mdash; it's converted to <acronym>UCS-2</> before it's sent to the server.  And obviously arrives at the server as <acronym>UCS-2</>.  If the column into which it's being inserted is also <acronym>UCS-2</>, there's no need to <emphasis>any</> conversion, much less two, and <emphasis>certainly</> no need to lose infomation.  
+ 			</para>
++			</formalpara>
+ 			<para>
+ Why this happens is anyone's guess.  Here's one: it makes the datatype of the column unimportant.  Regardless of whether you use char/varchar/text or nchar/nvarchar/ntext or a mixture of the two, the arriving SQL (if naïvely written) will store exactly the same characters.  
+ 			</para>
+
+commit 3e208c6ede918c414294e2299c08a70c92ccf5bb
+Author: jklowden <jklowden>
+Date:   Fri Aug 15 04:47:05 2008 +0000
+
+    Generate UTF-8 output with content-type header
+
+diff --git a/ChangeLog b/ChangeLog
+index a362cd4..394722b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Aug 15 00:42:28 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* doc/Makefile.am doc/userguide.dsl.in doc/userguide.sgml
++	- Generate UTF-8 output with content-type header
++
+ Thu Aug 14 11:14:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/userguide.sgml: make openjade happy
+ 
+@@ -528,4 +532,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2581 2008/08/14 09:14:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2582 2008/08/15 04:47:05 jklowden Exp $
+diff --git a/doc/Makefile.am b/doc/Makefile.am
+index a03f624..b10e470 100644
+--- a/doc/Makefile.am
++++ b/doc/Makefile.am
+@@ -2,7 +2,7 @@
+ # Converting DocBook to HTML (several small files)
+ # http://www.freebsd.org/tutorials/docproj-primer/x3132.html#AEN3140
+ 
+-# $Id: Makefile.am,v 1.64 2008/05/08 18:37:21 jklowden Exp $
++# $Id: Makefile.am,v 1.65 2008/08/15 04:47:05 jklowden Exp $
+ 
+ SHELL = /bin/sh
+ TXT2MAN = $(srcdir)/txt2man
+@@ -169,7 +169,8 @@ $(DOCDIR)/userguide/index.htm: userguide.sgml  userguide.dsl.in api_status.txt
+ ##		The crazy path is due to the above 'cd' command
+ 		SRCDOC=../../../$(srcdir); \
+ 		if test ! -r userguide.sgml; then ln -s $${SRCDOC}/userguide.sgml userguide.sgml; fi; \
+-		openjade -d ../../../userguide.dsl -t sgml userguide.sgml; \
++		openjade -b utf-8 -w all -w no-empty -w no-unused-param \
++			 -d ../../../userguide.dsl -t sgml userguide.sgml; \
+ 		if test -h userguide.sgml; then rm userguide.sgml; fi; \
+ ## 		and copy the stylesheet
+ 		cp $${SRCDOC}/userguide.css .; \
+diff --git a/doc/userguide.dsl.in b/doc/userguide.dsl.in
+index 373db44..18c4894 100644
+--- a/doc/userguide.dsl.in
++++ b/doc/userguide.dsl.in
+@@ -11,7 +11,8 @@
+ ;;	by Norman Walsh
+ ;; See Chapter 3, "Customizing the Stylesheets"
+ ;; http://docbook.sourceforge.net/release/dsssl/current/doc/custom.html
+-;; $Id: userguide.dsl.in,v 1.2 2005/10/03 02:52:22 jklowden Exp $
++
++;; $Id: userguide.dsl.in,v 1.3 2008/08/15 04:47:05 jklowden Exp $
+ 
+ ;; For note, tip, and warning: include little
+ ;; gifs of a hand pointing a finger, or a yield sign, and so on.  
+@@ -50,6 +51,12 @@
+   ;; Generate HTML 4.0
+   #t)
+ 
++;; Insert meta tag with encoding information into each generated HTML file.
++;; cf. http://www.dpawson.co.uk/docbook/dsssl/dssslgeneral.html 
++
++(define %html-header-tags% 
++  '(("META" ("HTTP-EQUIV" "Content-Type") ("CONTENT" "text/html; charset=utf-8"))))
++
+ ;; Should the role attribute of emphasis be propagated to HTML as a
+ ;; class attribute value? Source Code
+ 
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index bc85603..f9957ba 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/08/14 09:14:48 $</date>
+-		<releaseinfo>$Revision: 1.115 $</releaseinfo>
++		<date>$Date: 2008/08/15 04:47:06 $</date>
++		<releaseinfo>$Revision: 1.116 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.115 $</>
+-<member>$Date: 2008/08/14 09:14:48 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.115 2008/08/14 09:14:48 freddy77 Exp $.</>
++<member>$Revision: 1.116 $</>
++<member>$Date: 2008/08/15 04:47:06 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.116 2008/08/15 04:47:06 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -343,7 +343,7 @@ The <acronym>GNU</> development system can generate code for a wide variety of h
+ 			<sidebar><title>ODBC Preparation</title>
+ 	<para>If you intend to build the <productname>FreeTDS</> ODBC driver &mdash; and want to use a Driver Manager (DM), as most people do &mdash; install the Driver Manager before configuring <productname>FreeTDS</>.  <Command>configure</> will detect the the DM and use its header (<filename>.h</>) files for ODBC constants and such.  If your DM is installed in an unusual directory, you may have to provide the directory name as a parameter to <Command>configure</>.</para>
+ 	
+-	<para><productname>FreeTDS</> doesn't <emphasis>require</> a DM.  You can build the ODBC driver without one, as long as you have the requisite header files: <filename>sql.h</>, <filename>sqlext.h</> and <filename>sqltypes.h</>.  These can be taken from either the iODBC or UnixODBC distributions. Put them wherever you like (e.g.,  <filename>/usr/local/include</filename>).  Because <productname>FreeTDS</> won't detect your (missing) DM, it won't automatically build the ODBC driver, so you'll have to tell <Command>configure</> what to do and where to look.  Cf. <link linkend="withOdbcNoDM"><option>--with-odbc-nodm</></link> <option</>.
++	<para><productname>FreeTDS</> doesn't <emphasis>require</> a DM.  You can build the ODBC driver without one, as long as you have the requisite header files: <filename>sql.h</>, <filename>sqlext.h</> and <filename>sqltypes.h</>.  These can be taken from either the iODBC or UnixODBC distributions. Put them wherever you like (e.g.,  <filename>/usr/local/include</filename>).  Because <productname>FreeTDS</> won't detect your (missing) DM, it won't automatically build the ODBC driver, so you'll have to tell <Command>configure</> what to do and where to look.  Cf. <link linkend="withOdbcNoDM"><option>--with-odbc-nodm</></link>.
+ </para>
+ 			</sidebar>
+ 			<para>
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/08/14 09:14:48 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/08/15 04:47:06 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1771,7 +1771,7 @@ In this example we want to force connections to a server named <literal>mssql</l
+ <acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.  (Background information on Unicode and how it affects <productname>FreeTDS</productname> can be found in the <link linkend="Unicode">appendix</link>.)
+ 			</para>
+ 			<para>
+-Because most Unix tools and environments do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> provides for conversion by the client to other character sets.  The mechanism used is determined by the <filename>configure</> script, which looks for a <function>iconv</>(3) function, an implementation of the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.    If no <function>iconv</> library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in <function>iconv</> substitute, and will be capable of converting among only <acronym>ISO 8859-1</>, <acronym>UTF-8</>, and <acronym>UCS-2</>.  
++Because most Unix tools and environments do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> provides for conversion by the client to other character sets.  The mechanism used is determined by the <filename>configure</> script, which looks for a <function>iconv(3)</> function, an implementation of the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.    If no <function>iconv</> library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in <function>iconv</> substitute, and will be capable of converting among only <acronym>ISO 8859-1</>, <acronym>UTF-8</>, and <acronym>UCS-2</>.  
+ 			</para>
+ 			<para>
+ To learn what character set the client wants, <productname>FreeTDS</productname> prefers the applicable <link linkend="clientcharset"><filename>freetds.conf</></link> <literal>client charset</> property.  If that is not set, it parses the <envar>LANG</> environment variable.  In either case, the found string is passed to <function>iconv</>(3) (or its built-in replacment).  <footnote><para>The built-in replacement expects GNU iconv names: <literal>ISO-8859-1</>, <literal>US-ASCII</>, or <literal>UTF-8</>.</para></footnote>.  If neither is found, <acronym>UCS-2</> data are converted to <acronym>ISO 8859-1</>.  
+@@ -1833,7 +1833,7 @@ INSERT INTO tablename (greeting) VALUES ('Hall&aring;')
+ the string is subject to somewhat surprising treatment by the server.  
+ 			</para>
+ 			<para>
+-When the server parses the SQL, it extracts the data values for insertion (or update, or comparison, etc.)  Unprefixed strings are converted to the single-byte character set of the server/database.<footnote><para>The precise rules are unknown to the author.</para></footnote>   Inserted data are then of course stored in the column.  In the case of UCS-2 columns &mdash; nchar/nvarchar/ntext &mdash; the value stored is that which results from a <emphasis>second</> conversion: from the single-byte form to the <acronym>UCS-2</> form.  
++When the server parses the SQL, it extracts the data values for insertion (or update, or comparison, etc.)  Unprefixed strings are converted to the single-byte character set of the server/database.<footnote><para>The precise rules are unknown to the author.</para></footnote>   Inserted data are then of course stored in the column.  In the case of UCS-2 columns &mdash; <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</> &mdash; the value stored is that which results from a <emphasis>second</> conversion: from the single-byte form to the <acronym>UCS-2</> form.  
+ 			</para>
+ 			<para>
+ The <emphasis>only</> safe way to enclose strings in SQL text is with an 'N' prefix:
+@@ -1843,10 +1843,10 @@ INSERT INTO tablename (greeting) VALUES (N'Hall&aring;')
+ </screen></informalexample>
+ 
+ 			</para>
+-			<formalpara><title>Commentary</>
+-<para>What's surprising about this?  Versions 7.0 and later of the TDS protocol use UCS-2 to send SQL text.  No matter how your local client is configured &mdash; with <acronym>UCS-2</> or <acronym>ISO 8859-1</> or anything else &mdash; it's converted to <acronym>UCS-2</> before it's sent to the server.  And obviously arrives at the server as <acronym>UCS-2</>.  If the column into which it's being inserted is also <acronym>UCS-2</>, there's no need to <emphasis>any</> conversion, much less two, and <emphasis>certainly</> no need to lose infomation.  
++			<bridgehead renderas='sect3'>Commentary</bridgehead>
++			<para>
++What's surprising about this?  Versions 7.0 and later of the TDS protocol use UCS-2 to send SQL text.  No matter how your local client is configured &mdash; with <acronym>UCS-2</> or <acronym>ISO 8859-1</> or anything else &mdash; it's converted to <acronym>UCS-2</> before it's sent to the server.  And obviously arrives at the server as <acronym>UCS-2</>.  If the column into which it's being inserted is also <acronym>UCS-2</>, there's no need of <emphasis>any</> conversion, much less two, and <emphasis>certainly</> no need to lose infomation.  
+ 			</para>
+-			</formalpara>
+ 			<para>
+ Why this happens is anyone's guess.  Here's one: it makes the datatype of the column unimportant.  Regardless of whether you use char/varchar/text or nchar/nvarchar/ntext or a mixture of the two, the arriving SQL (if naïvely written) will store exactly the same characters.  
+ 			</para>
+
+commit 160029e479d0bc4e3f29b999fb79fa1700f6680f
+Author: freddy77 <freddy77>
+Date:   Fri Aug 15 08:13:09 2008 +0000
+
+    remove strange characters
+
+diff --git a/ChangeLog b/ChangeLog
+index 394722b..c865c12 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Aug 15 10:12:34 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: remove strange characters
++
+ Fri Aug 15 00:42:28 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/Makefile.am doc/userguide.dsl.in doc/userguide.sgml
+ 	- Generate UTF-8 output with content-type header
+@@ -532,4 +535,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2582 2008/08/15 04:47:05 jklowden Exp $
++$Id: ChangeLog,v 1.2583 2008/08/15 08:13:09 freddy77 Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index f9957ba..f1d9c32 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/08/15 04:47:06 $</date>
+-		<releaseinfo>$Revision: 1.116 $</releaseinfo>
++		<date>$Date: 2008/08/15 08:13:09 $</date>
++		<releaseinfo>$Revision: 1.117 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.116 $</>
+-<member>$Date: 2008/08/15 04:47:06 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.116 2008/08/15 04:47:06 jklowden Exp $.</>
++<member>$Revision: 1.117 $</>
++<member>$Date: 2008/08/15 08:13:09 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.117 2008/08/15 08:13:09 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/08/15 04:47:06 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/08/15 08:13:09 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1848,7 +1848,7 @@ INSERT INTO tablename (greeting) VALUES (N'Hall&aring;')
+ What's surprising about this?  Versions 7.0 and later of the TDS protocol use UCS-2 to send SQL text.  No matter how your local client is configured &mdash; with <acronym>UCS-2</> or <acronym>ISO 8859-1</> or anything else &mdash; it's converted to <acronym>UCS-2</> before it's sent to the server.  And obviously arrives at the server as <acronym>UCS-2</>.  If the column into which it's being inserted is also <acronym>UCS-2</>, there's no need of <emphasis>any</> conversion, much less two, and <emphasis>certainly</> no need to lose infomation.  
+ 			</para>
+ 			<para>
+-Why this happens is anyone's guess.  Here's one: it makes the datatype of the column unimportant.  Regardless of whether you use char/varchar/text or nchar/nvarchar/ntext or a mixture of the two, the arriving SQL (if naïvely written) will store exactly the same characters.  
++Why this happens is anyone's guess.  Here's one: it makes the datatype of the column unimportant.  Regardless of whether you use char/varchar/text or nchar/nvarchar/ntext or a mixture of the two, the arriving SQL (if na&iuml;vely written) will store exactly the same characters.  
+ 			</para>
+ 		</sect2>
+ 		</sect1>
+@@ -3822,7 +3822,7 @@ msg_handler(DBPROCESS *dbproc, DBINT msgno, int msgstate, int severity,
+ 	fprintf(stderr, "%s\n", msgtext);
+ 	
+ 	if (severity > 10) {						<co id="samplecode.errors.msghandler.severity">
+-		fprintf(stderr, "%s: error: severity %d > 10, exiting\n", 
++		fprintf(stderr, "%s: error: severity %d > 10, exiting\n", 
+ 				options.appname, severity);
+ 		exit(severity);
+ 	}
+@@ -3870,7 +3870,7 @@ err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr,
+ 							<function>getuserdata()</>. </para></listitem>
+ 			</orderedlist>
+ 			
+-			<tip><para>If your application is written in <symbol>C++</>, you may be tempted to use <function>throw()</>. Don't!  Your handler is a <symbol>C</> function and, more important, <emphasis>it's an extension of <symbol>db-lib</></emphasis>.  You can put a <function>throw()</> in your handler and it will compile. But when it executes, it's going to rip through <symbol>db-lib</>'s stack.  Your application will be unuseable at that point, if it doesn't cause a segment fault.  </para></tip>
++			<tip><para>If your application is written in <symbol>C++</>, you may be tempted to use <function>throw()</>. Don't!  Your handler is a <symbol>C</> function and, more important, <emphasis>it's an extension of <symbol>db-lib</></emphasis>.  You can put a <function>throw()</> in your handler and it will compile. But when it executes, it's going to rip through <symbol>db-lib</>'s stack.  Your application will be unuseable at that point, if it doesn't cause a segment fault.  </para></tip>
+ 			</para>
+ 	
+ 			</sect2>
+
+commit c1a406a82676e44210919e9885d43f9f848b46ea
+Author: freddy77 <freddy77>
+Date:   Fri Aug 15 09:55:22 2008 +0000
+
+    make win64 compile again
+
+diff --git a/ChangeLog b/ChangeLog
+index c865c12..086c144 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Aug 15 11:55:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/Makefile.am:
++	- make win64 compile again
++
+ Fri Aug 15 10:12:34 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/userguide.sgml: remove strange characters
+ 
+@@ -535,4 +539,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2583 2008/08/15 08:13:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2584 2008/08/15 09:55:22 freddy77 Exp $
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index 4d177cd..b2b3694 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.28 2008/07/08 08:41:06 freddy77 Exp $
++# $Id: Makefile.am,v 1.29 2008/08/15 09:55:23 freddy77 Exp $
+ 
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT) t0004$(EXEEXT) \
+ 			t0005$(EXEEXT) t0006$(EXEEXT) t0007$(EXEEXT) t0008$(EXEEXT) \
+@@ -48,5 +48,5 @@ AM_LDFLAGS	=	-no-fast-install
+ else
+ AM_LDFLAGS	=	-no-install
+ endif
+-LIBS		=	../libct.la -static @NETWORK_LIBS@
++LIBS		=	../libct.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+
+commit 2fd0aff2e5eb8b5b6e951916303ee27e05295791
+Author: freddy77 <freddy77>
+Date:   Sat Aug 16 14:48:57 2008 +0000
+
+    allow SQL_WCHAR/SQL_WVARCHAR to be used
+
+diff --git a/ChangeLog b/ChangeLog
+index 086c144..1c9d6a7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Sat Aug 16 16:47:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/odbc_util.c src/odbc/sql2tds.c:
++	- allow SQL_WCHAR/SQL_WVARCHAR
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/utf8.c:
++	- add test for utf-8 encoding on client
++
+ Fri Aug 15 11:55:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/Makefile.am:
+ 	- make win64 compile again
+@@ -539,4 +545,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2584 2008/08/15 09:55:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2585 2008/08/16 14:48:57 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index d4d5e1d..1de1ae5 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.488 2008/07/28 20:58:19 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.489 2008/08/16 14:48:57 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -2830,7 +2830,7 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		/* TODO SQL_FALSE ?? */
+ 		drec->sql_desc_case_sensitive = SQL_TRUE;
+ 		/* TODO test error ?? */
+-		odbc_set_concise_sql_type(odbc_server_to_sql_type(col->column_type, col->column_size), drec, 0);
++		odbc_set_concise_sql_type(odbc_server_to_sql_type(col->on_server.column_type, col->on_server.column_size), drec, 0);
+ 		/*
+ 		 * TODO how to handle when in datetime we change precision ?? 
+ 		 * should we change display size too ??
+@@ -2846,8 +2846,16 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		/* TODO other types for date ?? SQL_TYPE_DATE, SQL_TYPE_TIME */
+ 		if (drec->sql_desc_concise_type == SQL_TIMESTAMP || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
+ 			drec->sql_desc_length = sizeof("2000-01-01 12:00:00.0000")-1;
+-		else
+-			drec->sql_desc_length = col->column_size;
++		else switch (drec->sql_desc_concise_type) {
++		case SQL_WCHAR:
++		case SQL_WVARCHAR:
++		case SQL_WLONGVARCHAR:
++			drec->sql_desc_length = col->on_server.column_size / 2;
++			break;
++		default:
++			drec->sql_desc_length = col->on_server.column_size;
++			break;
++		}
+ 		odbc_set_sql_type_info(col, drec, stmt->dbc->env->attr.odbc_version);
+ 
+ 		if (!col->table_column_name) {
+@@ -2924,7 +2932,7 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 			else if (drec->sql_desc_type == SQL_DATETIME)
+ 				len = sizeof(TIMESTAMP_STRUCT);
+ 			else
+-				len = col->column_size;
++				len = col->on_server.column_size;
+ 			drec->sql_desc_octet_length = len;
+ 		}
+ 
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index ddebbe1..7ba3145 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.98 2008/07/14 15:12:42 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.99 2008/08/16 14:48:57 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -262,6 +262,14 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 		return SQL_VARCHAR;
+ 	case SYBTEXT:
+ 		return SQL_LONGVARCHAR;
++	case XSYBNCHAR:
++		return SQL_WCHAR;
++	/* TODO really sure ?? SYBNVARCHAR sybase only ?? */
++	case SYBNVARCHAR:
++	case XSYBNVARCHAR:
++		return SQL_WVARCHAR;
++	case SYBNTEXT:
++		return SQL_WLONGVARCHAR;
+ 	case SYBBIT:
+ 	case SYBBITN:
+ 		return SQL_BIT;
+@@ -326,12 +334,6 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBNUMERIC:
+ 	case SYBDECIMAL:
+ 		return SQL_NUMERIC;
+-		/* TODO this is ODBC 3.5 */
+-	case SYBNTEXT:
+-	case SYBNVARCHAR:
+-	case XSYBNVARCHAR:
+-	case XSYBNCHAR:
+-		break;
+ #if (ODBCVER >= 0x0300)
+ 	case SYBUNIQUE:
+ #ifdef SQL_GUID
+@@ -679,11 +681,19 @@ odbc_sql_to_server_type(TDSSOCKET * tds, int sql_type)
+ {
+ 
+ 	switch (sql_type) {
+-
++	case SQL_WCHAR:
++		if (IS_TDS7_PLUS(tds))
++			return XSYBNCHAR;
+ 	case SQL_CHAR:
+ 		return SYBCHAR;
++	case SQL_WVARCHAR:
++		if (IS_TDS7_PLUS(tds))
++			return XSYBNVARCHAR;
+ 	case SQL_VARCHAR:
+ 		return SYBVARCHAR;
++	case SQL_WLONGVARCHAR:
++		if (IS_TDS7_PLUS(tds))
++			return SYBNTEXT;
+ 	case SQL_LONGVARCHAR:
+ 		return SYBTEXT;
+ 	case SQL_DECIMAL:
+@@ -860,6 +870,9 @@ odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_
+ 	TYPE_NORMAL(SQL_CHAR) \
+ 	TYPE_NORMAL(SQL_VARCHAR) \
+ 	TYPE_NORMAL(SQL_LONGVARCHAR) \
++	TYPE_NORMAL(SQL_WCHAR) \
++	TYPE_NORMAL(SQL_WVARCHAR) \
++	TYPE_NORMAL(SQL_WLONGVARCHAR) \
+ \
+ 	TYPE_NORMAL(SQL_DECIMAL) \
+ 	TYPE_NORMAL(SQL_NUMERIC) \
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index e2cef12..f9f118b 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.68 2008/07/15 09:53:00 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.69 2008/08/16 14:48:57 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -354,11 +354,11 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 	case SYBLONGBINARY:
+ 	case SYBIMAGE:
+ 		res = tds_convert(dbc->env->tds_ctx, src_type, src, len, dest_type, &ores);
+-		if (res < 0)
+-			return SQL_ERROR;
+-		blob = (TDSBLOB *) dest;
+-		free(blob->textvalue);
+-		blob->textvalue = ores.ib;
++		if (res >= 0) {
++			blob = (TDSBLOB *) dest;
++			free(blob->textvalue);
++			blob->textvalue = ores.ib;
++		}
+ 		break;
+ 	case SYBNUMERIC:
+ 	case SYBDECIMAL:
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index 6a3f662..af134ad 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -71,3 +71,5 @@ cancel
+ test64
+ wchar
+ transaction2
++utf8
++
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 3496168..9afecee 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.76 2008/06/12 03:52:05 jklowden Exp $
++# $Id: Makefile.am,v 1.77 2008/08/16 14:48:57 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -22,7 +22,7 @@ TESTS		=	\
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+ 			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT) \
+-			cursor6$(EXEEXT) cursor7$(EXEEXT)
++			cursor6$(EXEEXT) cursor7$(EXEEXT) utf8$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -87,6 +87,7 @@ wchar_SOURCES = wchar.c common.c common.h
+ transaction2_SOURCES = transaction2.c common.c common.h
+ cursor6_SOURCES	= cursor6.c common.c common.h
+ cursor7_SOURCES	= cursor7.c common.c common.h
++utf8_SOURCES	= utf8.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+new file mode 100755
+index 0000000..479dac9
+--- /dev/null
++++ b/src/odbc/unittests/utf8.c
+@@ -0,0 +1,169 @@
++#include "common.h"
++
++/* test binding with UTF-8 encoding */
++static char software_version[] = "$Id: utf8.c,v 1.1 2008/08/16 14:48:57 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static void init_connect(void);
++
++static void
++init_connect(void)
++{
++	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
++		printf("Unable to allocate env\n");
++		exit(1);
++	}
++	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
++		printf("Unable to allocate connection\n");
++		SQLFreeEnv(Environment);
++		exit(1);
++	}
++}
++
++static void
++CheckNoRow(const char *query)
++{
++	SQLRETURN retcode;
++
++	retcode = SQLExecDirect(Statement, (SQLCHAR *) query, SQL_NTS);
++	if (retcode == SQL_NO_DATA)
++		return;
++
++	if (!SQL_SUCCEEDED(retcode))
++		ODBC_REPORT_ERROR("SQLExecDirect");
++
++	do {
++		SQLSMALLINT cols;
++
++		retcode = SQLNumResultCols(Statement, &cols);
++		if (retcode != SQL_SUCCESS || cols != 0) {
++			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
++			exit(1);
++		}
++	} while ((retcode = SQLMoreResults(Statement)) == SQL_SUCCESS);
++	if (retcode != SQL_NO_DATA)
++		ODBC_REPORT_ERROR("SQLMoreResults");
++}
++
++/* test table name, it contains two japanese characters */
++static const char table_name[] = "mytab\xe7\x8e\x8b\xe9\xb4\xbb";
++
++static const char * const strings[] = {
++	/* ascii */
++	"aaa", "aaa",
++	/* latin 1*/
++	"abc\xc3\xa9\xc3\xa1\xc3\xb4", "abc\xc3\xa9\xc3\xae\xc3\xb4",
++	/* Japanese... */
++	"abc\xe7\x8e\x8b\xe9\xb4\xbb", "abc\xe7\x8e\x8b\xe9\xb4\xbb\xe5\x82\x91\xe7\x8e\x8b\xe9\xb4\xbb\xe5\x82\x91",
++	NULL, NULL
++};
++
++/* same strings in hex */
++static const char * const strings_hex[] = {
++	/* ascii */
++	"0x610061006100", "0x610061006100",
++	/* latin 1*/
++	"0x610062006300e900e100f400", "0x610062006300e900ee00f400",
++	/* Japanese... */
++	"0x6100620063008b733b9d", "0x6100620063008b733b9d91508b733b9d9150",
++	NULL, NULL
++};
++
++int
++main(int argc, char *argv[])
++{
++	int res;
++	char tmp[2048];
++	SQLSMALLINT len;
++	const char **p;
++	SQLINTEGER n;
++	SQLLEN n_len;
++
++	if (read_login_info())
++		exit(1);
++
++	/* connect string using DSN */
++	init_connect();
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
++	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
++	if (!SQL_SUCCEEDED(res)) {
++		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
++		CheckReturn();
++		return 1;
++	}
++	if (!driver_is_freetds()) {
++		Disconnect();
++		printf("Driver is not FreeTDS, exiting\n");
++		return 0;
++	}
++
++        memset(tmp, 0, sizeof(tmp));
++        SQLGetInfo(Connection, SQL_DBMS_VER, tmp, sizeof(tmp), &len);
++	if (!db_is_microsoft() || (strncmp(tmp, "08.00.", 6) != 0 && strncmp(tmp, "09.00.", 6) != 0)) {
++		Disconnect();
++		printf("Test for MSSQL only\n");
++		return 0;
++	}
++
++	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS) {
++		printf("Unable to allocate statement\n");
++		CheckReturn();
++	}
++
++	/* create test table */
++	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
++	Command(Statement, tmp);
++	sprintf(tmp, "CREATE TABLE %s (k int, c NCHAR(10), vc NVARCHAR(10))", table_name);
++	Command(Statement, tmp);
++
++	/* insert with INSERT statements */
++	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
++		sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, n, p[0], p[1]);
++		Command(Statement, tmp);
++	}
++
++	/* check rows */
++	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
++		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, n, p[0], p[1]);
++		CheckNoRow(tmp);
++	}
++	sprintf(tmp, "DELETE FROM %s", table_name);
++	Command(Statement, tmp);
++
++	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
++	sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) tmp, SQL_NTS));
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG,
++		SQL_INTEGER, 0, 0, &n, 0, &n_len));
++	n_len = sizeof(n);
++	
++	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
++		SQLLEN s1_len, s2_len;
++
++		CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
++			SQL_WCHAR, 40, 0, p[0], 0, &s1_len));
++		/* FIXME this with SQL_VARCHAR produce wrong protocol data */
++		CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
++			SQL_WVARCHAR, 40, 0, p[1], 0, &s2_len));
++		s1_len = strlen(p[0]);
++		s2_len = strlen(p[1]);
++		printf("insert #%d\n", n);
++		CHK(SQLExecute, (Statement));
++	}
++
++	/* check rows */
++	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
++		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, n, p[0], p[1]);
++		CheckNoRow(tmp);
++	}
++
++	/* cleanup */
++	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
++	Command(Statement, tmp);
++
++	Disconnect();
++	printf("Done.\n");
++	return 0;
++}
++
+
+commit ceb563444afa8c5a57d5305c8849d554c1112dc3
+Author: freddy77 <freddy77>
+Date:   Sat Aug 16 18:08:22 2008 +0000
+
+    do not loose sync on conversion errors
+
+diff --git a/ChangeLog b/ChangeLog
+index 1c9d6a7..2a71736 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Aug 16 20:08:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: do not loose sync on conversion errors
++
+ Sat Aug 16 16:47:21 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/odbc_util.c src/odbc/sql2tds.c:
+ 	- allow SQL_WCHAR/SQL_WVARCHAR
+@@ -545,4 +548,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2585 2008/08/16 14:48:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2586 2008/08/16 18:08:22 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 128a441..d435f73 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.222 2008/07/16 13:58:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.223 2008/08/16 18:08:22 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -388,6 +388,7 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 			param = params->columns[i];
+ 			/* TODO check error */
+ 			tds_put_data_info(tds, param, 0);
++			/* FIXME handle error */
+ 			tds_put_data(tds, param);
+ 		}
+ 		tds->internal_sp_called = TDS_SP_EXECUTESQL;
+@@ -1197,6 +1198,7 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ 			param = params->columns[i];
+ 			/* TODO check error */
+ 			tds_put_data_info(tds, param, 0);
++			/* FIXME handle error */
+ 			tds_put_data(tds, param);
+ 		}
+ 
+@@ -1468,13 +1470,14 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ #endif
+ 			/* we need to convert data before */
+ 			/* TODO this can be a waste of memory... */
++			converted = 1;
+ 			s = tds_convert_string(tds, curcol->char_conv, s, colsize, &colsize);
+ 			if (!s) {
+-				/* FIXME this is a bad place to return error... */
++				/* on conversion error put a empty string */
+ 				/* TODO on memory failure we should compute converted size and use chunks */
+-				return TDS_FAIL;
++				colsize = 0;
++				converted = -1;
+ 			}
+-			converted = 1;
+ 		}
+ 			
+ 		switch (curcol->column_varint_size) {
+@@ -1500,6 +1503,10 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			break;
+ 		}
+ 
++		/* conversion error, exit with an error */
++		if (converted < 0)
++			return TDS_FAIL;
++
+ 		/* put real data */
+ 		if (is_numeric_type(curcol->on_server.column_type)) {
+ 			TDS_NUMERIC buf;
+@@ -1607,6 +1614,7 @@ tds7_send_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn)
+ 			param = info->columns[i];
+ 			/* TODO check error */
+ 			tds_put_data_info(tds, param, 0);
++			/* FIXME handle error */
+ 			tds_put_data(tds, param);
+ 		}
+ 
+@@ -1706,7 +1714,7 @@ tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags)
+ 	/* row data */
+ 	tds_put_byte(tds, TDS5_PARAMS_TOKEN);
+ 	for (i = 0; i < info->num_cols; i++) {
+-		/* TODO check error */
++		/* FIXME handle error */
+ 		tds_put_data(tds, info->columns[i]);
+ 	}
+ }
+@@ -1879,6 +1887,7 @@ tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params)
+ 			param = params->columns[i];
+ 			/* TODO check error */
+ 			tds_put_data_info(tds, param, TDS_PUT_DATA_USE_NAME);
++			/* FIXME handle error */
+ 			tds_put_data(tds, param);
+ 		}
+ 
+@@ -2222,6 +2231,7 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 				TDSCOLUMN *param = params->columns[i];
+ 				/* TODO check error */
+ 				tds_put_data_info(tds, param, 0);
++				/* FIXME handle error */
+ 				tds_put_data(tds, param);
+ 			}
+ 		}
+@@ -2776,6 +2786,7 @@ tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op,
+ 				param = params->columns[n];
+ 				/* TODO check error */
+ 				tds_put_data_info(tds, param, TDS_PUT_DATA_USE_NAME|TDS_PUT_DATA_PREFIX_NAME);
++				/* FIXME handle error */
+ 				tds_put_data(tds, param);
+ 			}
+ 		}
+
+commit d6a03ddd63ca49029934fb25625f83108383d4c9
+Author: freddy77 <freddy77>
+Date:   Sun Aug 17 07:27:16 2008 +0000
+
+    rollback change to make blob1 test work again
+
+diff --git a/ChangeLog b/ChangeLog
+index 2a71736..3f4a831 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Aug 17 09:26:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: rollback change to make blob1 test work again
++
+ Sat Aug 16 20:08:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c: do not loose sync on conversion errors
+ 
+@@ -548,4 +551,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2586 2008/08/16 18:08:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2587 2008/08/17 07:27:16 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 1de1ae5..f721acc 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.489 2008/08/16 14:48:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.490 2008/08/17 07:27:16 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -6022,7 +6022,7 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 		SQLRETURN ret;
+ 		const TDSCOLUMN *curcol = stmt->params->columns[stmt->param_num - (stmt->prepared_query_is_func ? 2 : 1)];
+ 		/* TODO do some more tests before setting this flag */
+-		stmt->param_data_called = curcol->column_size == curcol->column_cur_size;
++		stmt->param_data_called = 1;
+ 		ret = continue_parse_prepared_query(stmt, rgbValue, cbValue);
+ 		tdsdump_log(TDS_DBG_FUNC, "SQLPutData returns %s, %d bytes left\n", 
+ 					  odbc_prret(ret), curcol->column_size - curcol->column_cur_size);
+
+commit b973c9f4b9013d56e1210445bc6a75074ecd41e3
+Author: freddy77 <freddy77>
+Date:   Sun Aug 17 07:44:45 2008 +0000
+
+    remove some warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index 3f4a831..61ab07a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Aug 17 09:44:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ctutil.c src/dblib/dbutil.c src/odbc/unittests/utf8.c:
++	- remove some warnings
++
+ Sun Aug 17 09:26:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: rollback change to make blob1 test work again
+ 
+@@ -551,4 +555,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2587 2008/08/17 07:27:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2588 2008/08/17 07:44:45 freddy77 Exp $
+diff --git a/src/ctlib/ctutil.c b/src/ctlib/ctutil.c
+index daeb1b5..c2bf5f5 100644
+--- a/src/ctlib/ctutil.c
++++ b/src/ctlib/ctutil.c
+@@ -32,7 +32,7 @@
+ /* #include "fortify.h" */
+ 
+ 
+-TDS_RCSID(var, "$Id: ctutil.c,v 1.28 2007/01/07 16:13:17 jklowden Exp $");
++TDS_RCSID(var, "$Id: ctutil.c,v 1.29 2008/08/17 07:44:45 freddy77 Exp $");
+ 
+ /*
+  * test include consistency 
+@@ -67,7 +67,7 @@ TEST_EQUAL(t14,CS_MSG_RESULT,TDS_MSG_RESULT);
+ TEST_EQUAL(t15,CS_DESCRIBE_RESULT,TDS_DESCRIBE_RESULT);
+ 
+ #define TEST_ATTRIBUTE(t,sa,fa,sb,fb) \
+-	COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && (int)(&((sa*)0)->fa) == (int)(&((sb*)0)->fb))
++	COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && (TDS_INTPTR)(&((sa*)0)->fa) == (TDS_INTPTR)(&((sb*)0)->fb))
+ 
+ TEST_ATTRIBUTE(t21,TDS_MONEY4,mny4,CS_MONEY4,mny4);
+ TEST_ATTRIBUTE(t22,TDS_OLD_MONEY,mnyhigh,CS_MONEY,mnyhigh);
+diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c
+index d41a717..92ad3f5 100644
+--- a/src/dblib/dbutil.c
++++ b/src/dblib/dbutil.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbutil.c,v 1.42 2007/12/07 05:27:55 jklowden Exp $");
++TDS_RCSID(var, "$Id: dbutil.c,v 1.43 2008/08/17 07:44:45 freddy77 Exp $");
+ 
+ /*
+  * test include consistency 
+@@ -58,7 +58,7 @@ TDS_RCSID(var, "$Id: dbutil.c,v 1.42 2007/12/07 05:27:55 jklowden Exp $");
+ /* TODO test SYBxxx consistency */
+ 
+ #define TEST_ATTRIBUTE(t,sa,fa,sb,fb) \
+-	COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && (int)(&((sa*)0)->fa) == (int)(&((sb*)0)->fb))
++	COMPILE_CHECK(t,sizeof(((sa*)0)->fa) == sizeof(((sb*)0)->fb) && (TDS_INTPTR)(&((sa*)0)->fa) == (TDS_INTPTR)(&((sb*)0)->fb))
+ 
+ TEST_ATTRIBUTE(t21,TDS_MONEY4,mny4,DBMONEY4,mny4);
+ TEST_ATTRIBUTE(t22,TDS_OLD_MONEY,mnyhigh,DBMONEY,mnyhigh);
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 479dac9..0db2f78 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.1 2008/08/16 14:48:57 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.2 2008/08/17 07:44:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -76,7 +76,7 @@ main(int argc, char *argv[])
+ 	int res;
+ 	char tmp[2048];
+ 	SQLSMALLINT len;
+-	const char **p;
++	const char * const*p;
+ 	SQLINTEGER n;
+ 	SQLLEN n_len;
+ 
+@@ -142,10 +142,10 @@ main(int argc, char *argv[])
+ 		SQLLEN s1_len, s2_len;
+ 
+ 		CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
+-			SQL_WCHAR, 40, 0, p[0], 0, &s1_len));
++			SQL_WCHAR, 40, 0, (void *) p[0], 0, &s1_len));
+ 		/* FIXME this with SQL_VARCHAR produce wrong protocol data */
+ 		CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
+-			SQL_WVARCHAR, 40, 0, p[1], 0, &s2_len));
++			SQL_WVARCHAR, 40, 0, (void *) p[1], 0, &s2_len));
+ 		s1_len = strlen(p[0]);
+ 		s2_len = strlen(p[1]);
+ 		printf("insert #%d\n", n);
+
+commit a73badf4465e5322fb8303e65b836b5b8c062d6b
+Author: freddy77 <freddy77>
+Date:   Sun Aug 17 08:08:06 2008 +0000
+
+    remove some warnings
+
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 0db2f78..721aabc 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.2 2008/08/17 07:44:45 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.3 2008/08/17 08:08:06 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -119,13 +119,13 @@ main(int argc, char *argv[])
+ 
+ 	/* insert with INSERT statements */
+ 	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
+-		sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, n, p[0], p[1]);
++		sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, (int) n, p[0], p[1]);
+ 		Command(Statement, tmp);
+ 	}
+ 
+ 	/* check rows */
+ 	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
+-		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, n, p[0], p[1]);
++		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
+ 		CheckNoRow(tmp);
+ 	}
+ 	sprintf(tmp, "DELETE FROM %s", table_name);
+@@ -148,13 +148,13 @@ main(int argc, char *argv[])
+ 			SQL_WVARCHAR, 40, 0, (void *) p[1], 0, &s2_len));
+ 		s1_len = strlen(p[0]);
+ 		s2_len = strlen(p[1]);
+-		printf("insert #%d\n", n);
++		printf("insert #%d\n", (int) n);
+ 		CHK(SQLExecute, (Statement));
+ 	}
+ 
+ 	/* check rows */
+ 	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
+-		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, n, p[0], p[1]);
++		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
+ 		CheckNoRow(tmp);
+ 	}
+ 
+
+commit f22f6ae33879150b20bccc39b2f7033510af163c
+Author: freddy77 <freddy77>
+Date:   Sun Aug 17 20:46:24 2008 +0000
+
+    skip empty options in SQLDriverConnect
+
+diff --git a/ChangeLog b/ChangeLog
+index 61ab07a..f32c052 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Aug 17 22:45:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c:
++	- skip empty options in SQLDriverConnect to make DBD::ODBC happy
++
+ Sun Aug 17 09:44:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ctutil.c src/dblib/dbutil.c src/odbc/unittests/utf8.c:
+ 	- remove some warnings
+@@ -555,4 +559,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2588 2008/08/17 07:44:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2589 2008/08/17 20:46:24 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index d16e218..0601176 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.74 2008/01/20 16:36:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.75 2008/08/17 20:46:24 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -226,9 +226,13 @@ odbc_parse_connect_string(const char *connect_string, const char *connect_string
+ 	char option[16];
+ 
+ 	tds_dstr_init(&value);
+-	for (p = connect_string; p && *p;) {
++	for (p = connect_string; p < connect_string_end && *p;) {
+ 		dest_s = NULL;
+ 
++		/* handle empty options */
++		while (p < connect_string_end && *p == ';')
++			++p;
++
+ 		/* parse option */
+ 		end = (const char *) memchr(p, '=', connect_string_end - p);
+ 		if (!end)
+
+commit 305f498a8ce8f7ec3ffa8daff2d7f44dd597ceef
+Author: freddy77 <freddy77>
+Date:   Mon Aug 18 07:17:43 2008 +0000
+
+    update DBD::ODBC
+
+diff --git a/ChangeLog b/ChangeLog
+index f32c052..452db82 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Aug 18 09:17:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: update DBD::ODBC
++
+ Sun Aug 17 22:45:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c:
+ 	- skip empty options in SQLDriverConnect to make DBD::ODBC happy
+@@ -559,4 +562,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2589 2008/08/17 20:46:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2590 2008/08/18 07:17:43 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 96bd004..b076072 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -116,7 +116,7 @@ find . \( -name \*.bb -o -name \*.bbg -o -name \*.da -o -name \*.gc\* \) -exec r
+ rm -rf autom4te.cache doc/doc covtmp coverage DBD-*
+ cvsclean || true
+ if test "$(uname -m)" = "x86_64"; then
+-	cp ../DBD-ODBC-1.15_2.tar.gz .
++	cp ../DBD-ODBC-1.16.tar.gz .
+ else
+ 	cp ../DBD-ODBC-1.13.tar.gz .
+ fi
+
+commit 8d6699f2f6108bcc9b90d008c90493ee81963d00
+Author: freddy77 <freddy77>
+Date:   Mon Aug 18 13:31:26 2008 +0000
+
+    update copyright
+
+diff --git a/ChangeLog b/ChangeLog
+index 452db82..0474ce3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,15 @@
++Mon Aug 18 15:30:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsbytes.h include/tdsodbc.h src/apps/tsql.c:
++	* src/dblib/dblib.c src/odbc/connectparams.c:
++	* src/odbc/convert_tds2sql.c src/odbc/error.c:
++	* src/odbc/odbc.c src/odbc/odbc_checks.c:
++	* src/odbc/odbc_util.c src/odbc/prepare_query.c:
++	* src/odbc/sql2tds.c src/tds/challenge.c:
++	* src/tds/config.c src/tds/log.c src/tds/login.c:
++	* src/tds/mem.c src/tds/net.c src/tds/numeric.c:
++	* src/tds/query.c src/tds/token.c:
++	- update copyright
++
+ Mon Aug 18 09:17:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild: update DBD::ODBC
+ 
+@@ -562,4 +574,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2590 2008/08/18 07:17:43 freddy77 Exp $
++$Id: ChangeLog,v 1.2591 2008/08/18 13:31:26 freddy77 Exp $
+diff --git a/include/tdsbytes.h b/include/tdsbytes.h
+index baf4a79..d0a3b87 100644
+--- a/include/tdsbytes.h
++++ b/include/tdsbytes.h
+@@ -1,5 +1,5 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 2005 Frediano Ziglio
++ * Copyright (C) 2005-2008 Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -20,7 +20,7 @@
+ #ifndef _tdsbytes_h_
+ #define _tdsbytes_h_
+ 
+-/* $Id: tdsbytes.h,v 1.3 2008/05/26 13:56:49 freddy77 Exp $ */
++/* $Id: tdsbytes.h,v 1.4 2008/08/18 13:31:26 freddy77 Exp $ */
+ 
+ #ifndef _tds_h_
+ #error tds.h must be included before tdsbytes.h
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index e52c366..2cfc74f 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2004, 2005, 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2004, 2005, 2006, 2007, 2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.106 2008/07/07 11:27:12 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.107 2008/08/18 13:31:26 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 874fa4f..ab3594d 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns
+- * Copyright (C) 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.120 2008/07/07 18:40:44 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.121 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index e43c290..e485a29 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.328 2008/08/13 19:08:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.329 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 0601176..5383cf5 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005 Frediano Ziglio
++ * Copyright (C) 2005-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.75 2008/08/17 20:46:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.76 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index f29df5b..62cfa48 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2003-2005  Frediano Ziglio
++ * Copyright (C) 2003-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.50 2008/01/29 09:35:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.51 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ TDS_INT
+ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 29cb953..cdae3fc 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2003, 2004, 2005, 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2003-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.56 2008/07/28 20:58:19 jklowden Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.57 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index f721acc..7a1d15f 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001  Brian Bruns
+- * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2002-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.490 2008/08/17 07:27:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.491 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+diff --git a/src/odbc/odbc_checks.c b/src/odbc/odbc_checks.c
+index 713bdcc..ec66ecc 100644
+--- a/src/odbc/odbc_checks.c
++++ b/src/odbc/odbc_checks.c
+@@ -1,5 +1,5 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 2003, 2004, 2005 Frediano Ziglio
++ * Copyright (C) 2003-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -40,7 +40,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_checks.c,v 1.20 2008/03/13 13:23:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_checks.c,v 1.21 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 7ba3145..f87948b 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005, 2006 Frediano Ziglio
++ * Copyright (C) 2005, 2006, 2007, 2008 Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.99 2008/08/16 14:48:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.100 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 02200d9..095aa4c 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
+- * Copyright (C) 2005  Frediano Ziglio
++ * Copyright (C) 2005-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.68 2008/07/24 22:04:50 jklowden Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.69 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index f9f118b..f3c0317 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005 Frediano Ziglio
++ * Copyright (C) 2005-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.69 2008/08/16 14:48:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.70 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index a053d94..f9be822 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2005  Frediano Ziglio
++ * Copyright (C) 2005-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.34 2008/08/07 07:18:53 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.35 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 9dcaf05..22356ff 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.135 2008/08/14 08:49:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.136 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 377d63d..bb40ee4 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006 Frediano Ziglio
++ * Copyright (C) 2006-2008 Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.6 2008/05/02 10:04:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.7 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALLLVL | TDS_DBGFLAG_SOURCE;
+diff --git a/src/tds/login.c b/src/tds/login.c
+index bf22c20..1c12428 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005, 2006, 2007  Ziglio Frediano
++ * Copyright (C) 2005, 2006, 2007, 2008  Ziglio Frediano
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.175 2008/08/06 07:40:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.176 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 14ec4f9..42d9866 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005 Frediano Ziglio
++ * Copyright (C) 2005-2008 Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.177 2008/08/06 07:40:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.178 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 3cd4b49..72399b5 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Brian Bruns
+- * Copyright (C) 2004, 2005, 2006, 2007  Ziglio Frediano
++ * Copyright (C) 2004, 2005, 2006, 2007, 2008  Ziglio Frediano
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.77 2008/08/07 10:06:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.78 2008/08/18 13:31:27 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+diff --git a/src/tds/numeric.c b/src/tds/numeric.c
+index 9d8cff2..0c20c76 100644
+--- a/src/tds/numeric.c
++++ b/src/tds/numeric.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2005  Frediano Ziglio
++ * Copyright (C) 2005-2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: numeric.c,v 1.43 2008/05/27 08:25:05 freddy77 Exp $");
++TDS_RCSID(var, "$Id: numeric.c,v 1.44 2008/08/18 13:31:28 freddy77 Exp $");
+ 
+ /* 
+  * these routines use arrays of unsigned char to handle arbitrary
+diff --git a/src/tds/query.c b/src/tds/query.c
+index d435f73..818c86d 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.223 2008/08/16 18:08:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.224 2008/08/18 13:31:28 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+diff --git a/src/tds/token.c b/src/tds/token.c
+index e91c316..d8321f5 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005, 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2005, 2006, 2007, 2008  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.350 2008/08/06 07:40:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.351 2008/08/18 13:31:28 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+
+commit 01a3a54368652edb3d45e21f7cd60b0f103acae9
+Author: jklowden <jklowden>
+Date:   Thu Aug 21 03:52:22 2008 +0000
+
+    added PHP question
+
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index 29e8c1b..83f51c6 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,7 +3,7 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.21 2008/05/13 14:11:54 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.22 2008/08/21 03:52:22 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+@@ -143,6 +143,8 @@
+ 
+         <li><a href="#dateformat">My dates aren't formatted
+         right!</a></li>
++        <li>My PHP script works from the command line but 
++		<a href="#php">fails in the browser!</a></li>
+       </ul>
+     </li>
+   </ol>
+@@ -859,12 +861,25 @@
+ 
+   <p>As of version 0.60, the default datetime-&gt;string conversion
+   is controlled by the <code>locale.conf</code> file. See the User
+-  Guide for details.</p><!-- footer -->
++  Guide for details.</p>
++  
++
++  <h3 id="php">My PHP script fails in the browser!</h3>
++  
++  <p> This is usually a webserver configuration issue, typically
++  permissions reading <kbd>freetds.conf</kbd> or similar.  
++  Remember that the account running the e.g. Apache server is 
++  normally not the one you use to log in, or to test your script
++  with on the command line.  
++
++
++  
++  <!-- footer -->
+   <hr size="1" />
+   <font size="-1">Updates and comments <a href=
+   "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
+   <br/>
+-    <i>$Id: faq.html,v 1.21 2008/05/13 14:11:54 jklowden Exp $</i>
++    <i>$Id: faq.html,v 1.22 2008/08/21 03:52:22 jklowden Exp $</i>
+ 	</font>
+ <hr/>
+   <p>
+
+commit 80cec97fd42907fa3cac3313972cf4ac6b3db7c7
+Author: jklowden <jklowden>
+Date:   Thu Aug 21 03:58:14 2008 +0000
+
+    passes validation again
+
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index 83f51c6..1ee35e4 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,7 +3,7 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.22 2008/08/21 03:52:22 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.23 2008/08/21 03:58:14 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+@@ -493,17 +493,17 @@
+   as a shared object.  There is a static library <kbd>libtds.a</kbd>, 
+   although it's not installed by <b><kbd>make install</kbd></b>.  
+   <kbd>libtds</kbd> is statically linked to the "official" client 
+-  libraries, <kbd>ct-lib</kbd>, <kbd>db-lib</kbd>, and <kbd>ODBC</kbd>.  
++  libraries, <kbd>ct-lib</kbd>, <kbd>db-lib</kbd>, and <kbd>ODBC</kbd>.  </p>
+   
+   <p>Distributing <kbd>libtds</kbd> as a shared object did more harm
+   than good.  Proper versioning and support was a burden on the 
+   developers, and it was just one more thing for a client application
+   to link in.  The only benefit was to programs that use more than
+-  one client library. 
++  one client library. </p>
+   
+   <p>Of course, it's still free software, and you're free to build a 
+   shared object of it if you want to.  It's just not done "out of the box"
+-  by the distributed makefiles.  
++  by the distributed makefiles.  </p>
+ 
+   <h3>Which Perl library should I use?</h3>
+ 	<a name="Which.Perl.library.should.I.use" 
+@@ -870,7 +870,7 @@
+   permissions reading <kbd>freetds.conf</kbd> or similar.  
+   Remember that the account running the e.g. Apache server is 
+   normally not the one you use to log in, or to test your script
+-  with on the command line.  
++  with on the command line.  </p>
+ 
+ 
+   
+@@ -879,7 +879,7 @@
+   <font size="-1">Updates and comments <a href=
+   "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
+   <br/>
+-    <i>$Id: faq.html,v 1.22 2008/08/21 03:52:22 jklowden Exp $</i>
++    <i>$Id: faq.html,v 1.23 2008/08/21 03:58:14 jklowden Exp $</i>
+ 	</font>
+ <hr/>
+   <p>
+
+commit 3f744d10dcfe3caa9ae787eb673df00b293ce841
+Author: freddy77 <freddy77>
+Date:   Fri Aug 22 05:27:21 2008 +0000
+
+    fix tds_send_emulated_execute if no parameters
+
+diff --git a/ChangeLog b/ChangeLog
+index 0474ce3..6c1744f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Aug 22 07:25:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c:
++	- applied modified patch from Chris Reeves for fix
++	  tds_send_emulated_execute if no parameters
++
+ Mon Aug 18 15:30:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsbytes.h include/tdsodbc.h src/apps/tsql.c:
+ 	* src/dblib/dblib.c src/odbc/connectparams.c:
+@@ -574,4 +579,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2591 2008/08/18 13:31:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2592 2008/08/22 05:27:21 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 818c86d..134b7ca 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.224 2008/08/18 13:31:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.225 2008/08/22 05:27:22 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -2970,7 +2970,7 @@ tds_send_emulated_execute(TDSSOCKET * tds, const char *query, TDSPARAMINFO * par
+ 	START_QUERY;
+ 	if (!num_placeholders) {
+ 		tds_put_string(tds, query, -1);
+-		return tds_flush_packet(tds);
++		return TDS_SUCCEED;
+ 	}
+ 
+ 	s = query;
+
+commit 4083085d018b7b470620f4dc82372645060cbade
+Author: freddy77 <freddy77>
+Date:   Tue Aug 26 14:14:33 2008 +0000
+
+    applied Andrew Victor patch for unused gmtime result
+
+diff --git a/ChangeLog b/ChangeLog
+index 6c1744f..fd2804d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Aug 26 16:11:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/cs.c:
++	- applied Andrew Victor patch for unused gmtime result
++
+ Fri Aug 22 07:25:58 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c:
+ 	- applied modified patch from Chris Reeves for fix
+@@ -579,4 +583,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2592 2008/08/22 05:27:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2593 2008/08/26 14:14:33 freddy77 Exp $
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index 036aab2..a759a52 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.66 2008/07/05 22:57:54 jklowden Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.67 2008/08/26 14:14:33 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -847,11 +847,9 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ CS_RETCODE
+ cs_dt_crack(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC * daterec)
+ {
+-TDS_DATETIME *dt;
+-TDS_DATETIME4 *dt4;
+-time_t tmp_secs_from_epoch;
+-struct tm *t;
+-TDSDATEREC dr;
++	TDS_DATETIME *dt;
++	TDS_DATETIME4 *dt4;
++	TDSDATEREC dr;
+ 
+ 	if (datetype == CS_DATETIME_TYPE) {
+ 		dt = (TDS_DATETIME *) dateval;
+@@ -862,7 +860,6 @@ TDSDATEREC dr;
+ 	} else {
+ 		return CS_FAIL;
+ 	}
+-	t = (struct tm *) gmtime(&tmp_secs_from_epoch);
+ 	daterec->dateyear = dr.year;
+ 	daterec->datemonth = dr.month;
+ 	daterec->datedmonth = dr.day;
+
+commit ad8c6c5604337cf97d7ec2c32b7d870ad7d58ce4
+Author: freddy77 <freddy77>
+Date:   Wed Aug 27 07:28:45 2008 +0000
+
+    allow empty password on tests
+
+diff --git a/ChangeLog b/ChangeLog
+index fd2804d..d673370 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Aug 27 09:27:49 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/common.c: allow empty password on tests
++
+ Tue Aug 26 16:11:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/cs.c:
+ 	- applied Andrew Victor patch for unused gmtime result
+@@ -583,4 +586,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2593 2008/08/26 14:14:33 freddy77 Exp $
++$Id: ChangeLog,v 1.2594 2008/08/27 07:28:45 freddy77 Exp $
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index 20e5e21..6e19774 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -24,7 +24,7 @@
+ #include "common.h"
+ #include "ctlib.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.18 2008/07/07 11:09:42 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.19 2008/08/27 07:28:46 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -169,7 +169,7 @@ establish_login(int argc, char **argv)
+ 	if (*options.DATABASE)
+ 		strcpy(DATABASE, options.DATABASE);
+ 	
+-	return (*USER && *PASSWORD && *SERVER && *DATABASE)? CS_SUCCEED : CS_FAIL;
++	return (*USER && *SERVER && *DATABASE)? CS_SUCCEED : CS_FAIL;
+ }
+ 
+ extern const char STD_DATETIME_FMT[];
+
+commit e460324f205ee4a73e95d54c6915e1e6eeef9bbc
+Author: freddy77 <freddy77>
+Date:   Wed Aug 27 07:44:38 2008 +0000
+
+    don't test nvarchar if Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index d673370..568c467 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Aug 27 09:43:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c:
++	- don't test nvarchar if Sybase
++
+ Wed Aug 27 09:27:49 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/common.c: allow empty password on tests
+ 
+@@ -586,4 +590,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2594 2008/08/27 07:28:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2595 2008/08/27 07:44:38 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 5f97a73..5361db9 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test various bind type */
+ 
+-static char software_version[] = "$Id: data.c,v 1.16 2008/07/14 13:07:43 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.17 2008/08/27 07:44:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -114,7 +114,9 @@ main(int argc, char *argv[])
+ 			if (!old_result)
+ 				result = 0;
+ 		}
++	}
+ 
++	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
+ 		/* nvarchar without extended characters */
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+ 		/* nvarchar with extended characters */
+
+commit eaac7ac98641240311670dae3cc18e66bb488995
+Author: freddy77 <freddy77>
+Date:   Wed Aug 27 07:59:25 2008 +0000
+
+    don't test for cursors if not implemented
+
+diff --git a/ChangeLog b/ChangeLog
+index 568c467..4315723 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Aug 27 09:57:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/rowset.c:
++	- don't test for cursors if not implemented
++
+ Wed Aug 27 09:43:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c:
+ 	- don't test nvarchar if Sybase
+@@ -590,4 +594,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2595 2008/08/27 07:44:38 freddy77 Exp $
++$Id: ChangeLog,v 1.2596 2008/08/27 07:59:25 freddy77 Exp $
+diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c
+index 93a0b2f..ad4b9fa 100644
+--- a/src/odbc/unittests/rowset.c
++++ b/src/odbc/unittests/rowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rowset.c,v 1.2 2008/02/29 10:54:53 freddy77 Exp $";
++static char software_version[] = "$Id: rowset.c,v 1.3 2008/08/27 07:59:25 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -67,6 +67,8 @@ main(int argc, char *argv[])
+ 	test_err(-1);
+ 	test_err(0);
+ 
++	CheckCursor();
++
+ 	/* set some correct values */
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0));
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0));
+
+commit 81eb0f11df25e1a04ec8d1e01898f600d4af5e13
+Author: freddy77 <freddy77>
+Date:   Thu Aug 28 09:34:46 2008 +0000
+
+    sort coverage pages
+
+diff --git a/misc/order_coverage.pl b/misc/order_coverage.pl
+new file mode 100755
+index 0000000..4afa2e3
+--- /dev/null
++++ b/misc/order_coverage.pl
+@@ -0,0 +1,76 @@
++#!/usr/bin/perl
++
++# $Id: order_coverage.pl,v 1.1 2008/08/28 09:34:46 freddy77 Exp $
++
++%processed = ();
++@to_process = ();
++
++$sorted = 'index.sort.html';
++
++sub perc($)
++{
++	my $row = shift;
++	my ($perc) = ($row =~ m/<td class="coverPer.*?">([0-9\.]+)/);
++	return $perc;
++}
++
++sub read_file($)
++{
++	open(FILE, '<', shift) or die('error opening');
++	my @all = <FILE>;
++	my $all = "@all";
++	undef @all;
++	close(FILE);
++	return $all;
++}
++sub order_file($)
++{
++	my $fn = shift;
++
++	my $all = read_file($fn);
++
++	# mark as processed
++	$processed{$fn} = 1;
++
++	# discover other files
++	while ($all =~ m{<td class="coverFile"><a href="(.*?index.html)">.*</a></td>}g) {
++		push(@to_process, $1) if !exists($processed{$1});
++	}
++
++	# extract parts (before, table, after)
++	die ('format error') if $all !~ m{(.*<table.*?<td class="tableHead" colspan=3>(?:<a href="$sorted">)?Coverage(?:</a>)?</td>.*?</tr>)(.*?)(\n\s*</table.*)}is;
++	my ($before, $table, $after) = ($1, $2, $3);
++
++	# extract rows
++	my @rows = ();
++	while ($table =~ m{([ \t]*<tr>.*?<td class="coverFile">.*?<td class="coverNum.*?">.*?line.*?</tr>\s*)}sg) {
++		push @rows, $1;
++	}
++
++	# make sorted index
++	my $ofn = $fn;
++	$ofn =~ s/index\.html/$sorted/;
++	my $output = $before . join('', sort { perc($a) <=> perc($b) } @rows) . $after;
++	$output =~ s{(<td class="tableHead">)(Directory\&nbsp;name|Filename)(</td>)}{$1<a href="index.html">$2</a>$3};
++	$output =~ s{(<td class="tableHead" colspan=3>)<a href="$sorted">(Coverage)</a>(</td>)}{$1$2$3};
++	$output =~ s{(<td class="coverFile"><a href=".*?)index\.html(">.*</a></td>)}{$1$sorted$2}g;
++	open(OUT, '>', $ofn) or die('opening output');
++	print OUT $output;
++	close(OUT);
++
++	# add link to normal index to sorted version
++	$output = $all;
++	$output =~ s{(<td class="tableHead" colspan=3>)(Coverage)(</td>)}{$1<a href="$sorted">$2</a>$3};
++	open(OUT, '>', $fn) or die('opening output');
++	print OUT $output;
++	close(OUT);
++}
++
++# process all files starting from index.html
++push @to_process, 'index.html';
++while (@to_process) {
++	my $fn = pop(@to_process);
++	print "processing $fn\n";
++	order_file($fn);
++}
++
+
+commit 5a54f2d979631d586f1c9a7b82364e526b29980c
+Author: freddy77 <freddy77>
+Date:   Fri Aug 29 14:19:17 2008 +0000
+
+    update test
+
+diff --git a/ChangeLog b/ChangeLog
+index 4315723..913beed 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Aug 29 16:18:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: update test
++
+ Wed Aug 27 09:57:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/rowset.c:
+ 	- don't test for cursors if not implemented
+@@ -594,4 +597,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2596 2008/08/27 07:59:25 freddy77 Exp $
++$Id: ChangeLog,v 1.2597 2008/08/29 14:19:17 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index ca15a94..bc97698 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.27 2008/07/15 15:14:12 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.28 2008/08/29 14:19:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -284,8 +284,10 @@ AllTests(void)
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
+ 
+-		precision = 12;
++		precision = 6;
+ 		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
++		precision = 12;
++		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "8 foo test");
+ 		/* TODO use collate in sintax if available */
+ 		Test("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");
+ 	}
+
+commit c45e90df98d43094d458446cb9583338a11d1a3e
+Author: freddy77 <freddy77>
+Date:   Mon Sep 1 13:27:41 2008 +0000
+
+    change path order
+
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index b076072..8b6c790 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -4,8 +4,8 @@ export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/
+ 
+ . $HOME/.bashrc
+ 
+-# do not use ccache, not work well woth profile informations
+-export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:$HOME/bin:$HOME/install/bin"
++# do not use ccache, not work well with profile informations
++export PATH="/usr/kerberos/bin:/usr/local/bin:$HOME/bin:/bin:/usr/bin:/usr/X11R6/bin:$HOME/install/bin"
+ 
+ GROUPDIR=/home/groups/f/fr/freetds/htdocs
+ # directory to compile
+
+commit 9573f94def63d18823cfc66fdaf1a1a1c0f47971
+Author: freddy77 <freddy77>
+Date:   Mon Sep 1 15:17:57 2008 +0000
+
+    check bug on column size computation for NVARCHAR
+
+diff --git a/ChangeLog b/ChangeLog
+index 913beed..8a93416 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Sep 01 17:16:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c:
++	- reproduce bug detected by Sebastien Flaesch on column size
++	  computation for NVARCHAR
++
+ Fri Aug 29 16:18:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c: update test
+ 
+@@ -597,4 +602,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2597 2008/08/29 14:19:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2598 2008/09/01 15:17:57 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index bc97698..4ee3ec9 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.28 2008/08/29 14:19:17 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.29 2008/09/01 15:17:57 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -281,6 +281,9 @@ AllTests(void)
+ 		Test("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
++		/* test for invalid stream due to truncation*/
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "01234567890");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "012345678901234567890");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
+ 
+
+commit 1423979b276d0e1804fd27526dfc5cfcd83944c7
+Author: freddy77 <freddy77>
+Date:   Thu Sep 4 06:43:48 2008 +0000
+
+    improve on_server.column_size handling
+
+diff --git a/ChangeLog b/ChangeLog
+index 8a93416..b7860eb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Thu Sep 04 08:42:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- fill on_server.column_size
++	* src/odbc/unittests/genparams.c: test for truncation
++	* src/tds/query.c: do not send invalid sizes
++
+ Mon Sep 01 17:16:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c:
+ 	- reproduce bug detected by Sebastien Flaesch on column size
+@@ -602,4 +608,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2598 2008/09/01 15:17:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2599 2008/09/04 06:43:48 freddy77 Exp $
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 095aa4c..9e2be47 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.69 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.70 2008/09/04 06:43:48 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -112,6 +112,7 @@ prepared_rpc(struct _hstmt *stmt, int compute_row)
+ 				curcol->column_cur_size = curcol->column_size;
+ 				break;
+ 			}
++			curcol->on_server.column_size = curcol->column_size;
+ 			/* TODO support other type other than VARCHAR, do not strip escape in prepare_call */
+ 			if (compute_row) {
+ 				char *dest;
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index f3c0317..23b216e 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.70 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.71 2008/09/04 06:43:48 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -178,8 +178,14 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 		if (dest_type != SYBUNIQUE && dest_type != SYBBITN && !is_fixed_type(dest_type)) {
+ 			curcol->column_cur_size = 0;
+ 			curcol->column_size = drec_ipd->sql_desc_length;
+-			if (curcol->column_size < 0)
+-				curcol->column_size = 0x7FFFFFFFl;
++			if (curcol->column_size < 0) {
++				curcol->on_server.column_size = curcol->column_size = 0x7FFFFFFFl;
++			} else {
++				if (is_unicode_type(dest_type))
++					curcol->on_server.column_size = curcol->column_size * 2;
++				else
++					curcol->on_server.column_size = curcol->column_size;
++			}
+ 		}
+ 	} else if (dest_type != SYBBIT) {
+ 		/* TODO only a trick... */
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 4ee3ec9..4aaa63d 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.29 2008/09/01 15:17:57 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.30 2008/09/04 06:43:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -97,6 +97,8 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQL
+ 	Command(Statement, "drop proc spTestProc");
+ }
+ 
++static int check_truncation = 0;
++
+ static void
+ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, const char *param_type, const char *value_to_convert)
+ {
+@@ -146,7 +148,10 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
+ 
+ 		rc = SQLExecDirect(Statement, (SQLCHAR *) sbuf, SQL_NTS);
+-		if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
++		if (check_truncation) {
++			if (rc != SQL_ERROR)
++				ODBC_REPORT_ERROR("SQLExecDirect should return error!");
++		} else if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("SQLExecDirect() failure!");
+ 	} else {
+ 		SQLRETURN rc;
+@@ -160,23 +165,29 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 			CHK(SQLPrepare, (Statement, (SQLCHAR *) sbuf, SQL_NTS));
+ 
+ 		rc = SQLExecute(Statement);
+-		if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
++		if (check_truncation) {
++			if (rc != SQL_ERROR)
++				ODBC_REPORT_ERROR("SQLExecute should return error!");
++		} else if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("SQLExecute() failure!");
+ 	}
+ 
+ 	/* check is row is present */
+-	ResetStatement();
+-	sep = "'";
+-	if (strncmp(expected, "0x", 2) == 0)
+-		sep = "";
+-	sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+-	Command(Statement, sbuf);
+-
+-	CHK(SQLFetch, (Statement));
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Row not expected");
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Recordset not expected");
++	if (!check_truncation) {
++		ResetStatement();
++		sep = "'";
++		if (strncmp(expected, "0x", 2) == 0)
++			sep = "";
++		sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
++		Command(Statement, sbuf);
++
++		CHK(SQLFetch, (Statement));
++		if (SQLFetch(Statement) != SQL_NO_DATA)
++			ODBC_REPORT_ERROR("Row not expected");
++		if (SQLMoreResults(Statement) != SQL_NO_DATA)
++			ODBC_REPORT_ERROR("Recordset not expected");
++	}
++	check_truncation = 0;
+ 	Command(Statement, "DROP TABLE #tmp_insert");
+ }
+ 
+@@ -283,6 +294,7 @@ AllTests(void)
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
+ 		/* test for invalid stream due to truncation*/
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "01234567890");
++		check_truncation = 1;
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "012345678901234567890");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 134b7ca..583ae88 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.225 2008/08/22 05:27:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.226 2008/09/04 06:43:49 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -1273,6 +1273,44 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ 	return tds_flush_packet(tds);
+ }
+ 
++/**
++ * Get column size for wire
++ */
++static int
++tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol)
++{
++	int size = curcol->on_server.column_size, min;
++
++	if (!size) {
++		size = curcol->column_size;
++		if (is_unicode_type(curcol->on_server.column_type))
++			size *= 2;
++	}
++
++	switch (curcol->column_varint_size) {
++	default:
++	case 0:
++		return size;
++	case 1:
++		size = MAX(MIN(size, 255), 1);
++		break;
++	case 2:
++		if (curcol->on_server.column_type == XSYBNVARCHAR || curcol->on_server.column_type == XSYBNCHAR)
++			min = 2;
++		else
++			min = 1;
++		size = MAX(MIN(size, 8000), min);
++		break;
++	case 4:
++		if (curcol->on_server.column_type == SYBNTEXT)
++			size = MAX(MIN(size, 0x7ffffffe), 2);
++		else
++			size = MAX(MIN(size, 0x7fffffff), 1);
++		break;
++	}
++/*	return curcol->on_server.column_size = size; */
++	return size;
++}
+ 
+ /**
+  * Put data information to wire
+@@ -1343,17 +1381,18 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 		tds_put_byte(tds, num->scale);
+ #endif
+ 	} else {
++		int size = tds_fix_column_size(tds, curcol);
+ 		switch (curcol->column_varint_size) {
+ 		case 0:
+ 			break;
+ 		case 1:
+-			tds_put_byte(tds, MAX(MIN(curcol->column_size, 255), 1));
++			tds_put_byte(tds, size);
+ 			break;
+ 		case 2:
+-			tds_put_smallint(tds, MAX(MIN(curcol->column_size, 8000), 1));
++			tds_put_smallint(tds, size);
+ 			break;
+ 		case 4:
+-			tds_put_int(tds, MAX(MIN(curcol->column_size, 0x7fffffff), 1));
++			tds_put_int(tds, size);
+ 			break;
+ 		}
+ 	}
+@@ -1411,7 +1450,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	unsigned char *src;
+ 	TDS_NUMERIC *num;
+ 	TDSBLOB *blob = NULL;
+-	TDS_INT colsize;
++	TDS_INT colsize, size;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+@@ -1439,6 +1478,8 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		return TDS_SUCCEED;
+ 	}
+ 
++	size = tds_fix_column_size(tds, curcol);
++
+ 	/*
+ 	 * TODO here we limit data sent with MIN, should mark somewhere
+ 	 * and inform client ??
+@@ -1483,18 +1524,18 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		switch (curcol->column_varint_size) {
+ 		case 4:	/* It's a BLOB... */
+ 			blob = (TDSBLOB *) curcol->column_data;
+-			colsize = MIN(colsize, 0x7fffffff);
++			colsize = MIN(colsize, size);
+ 			/* mssql require only size */
+ 			tds_put_int(tds, colsize);
+ 			break;
+ 		case 2:
+-			colsize = MIN(colsize, 8000);
++			colsize = MIN(colsize, size);
+ 			tds_put_smallint(tds, colsize);
+ 			break;
+ 		case 1:
++			colsize = MIN(colsize, size);
+ 			if (is_numeric_type(curcol->on_server.column_type))
+ 				colsize = tds_numeric_bytes_per_prec[((TDS_NUMERIC *) src)->precision];
+-			colsize = MIN(colsize, 255);
+ 			tds_put_byte(tds, colsize);
+ 			break;
+ 		case 0:
+
+commit 40b9294c43171959433c167a5ab90ce9072bd821
+Author: jklowden <jklowden>
+Date:   Mon Sep 8 17:50:25 2008 +0000
+
+    fix #define of BLK_VERSION_110
+
+diff --git a/ChangeLog b/ChangeLog
+index b7860eb..4790b15 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Sep  8 13:49:19 EDT 2008	JK Lowden <jklowden@freetds.org>
++	* include/cspublic.h fix #define of BLK_VERSION_110 
++
+ Thu Sep 04 08:42:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
+ 	- fill on_server.column_size
+@@ -608,4 +611,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2599 2008/09/04 06:43:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2600 2008/09/08 17:50:25 jklowden Exp $
+diff --git a/include/cspublic.h b/include/cspublic.h
+index eb90d3d..e2cc7e6 100644
+--- a/include/cspublic.h
++++ b/include/cspublic.h
+@@ -34,7 +34,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.60 2008/07/05 22:57:54 jklowden Exp $";
++static const char rcsid_cspublic_h[] = "$Id: cspublic.h,v 1.61 2008/09/08 17:50:25 jklowden Exp $";
+ static const void *const no_unused_cspublic_h_warn[] = { rcsid_cspublic_h, no_unused_cspublic_h_warn };
+ 
+ #define CS_PUBLIC
+@@ -446,7 +446,7 @@ enum
+ #define CS_VERSION_150	15000
+ 
+ #define BLK_VERSION_100 CS_VERSION_100
+-#define BLK_VERSION_110 CS_VERSION_100
++#define BLK_VERSION_110 CS_VERSION_110
+ #define BLK_VERSION_120 CS_VERSION_120
+ #define BLK_VERSION_125 CS_VERSION_125
+ #define BLK_VERSION_150 CS_VERSION_150
+
+commit 83ab415333d8e09bc75fc2c14fc9772131bd3e86
+Author: freddy77 <freddy77>
+Date:   Mon Sep 8 19:22:44 2008 +0000
+
+    more fixes for utf8 and odbc
+
+diff --git a/ChangeLog b/ChangeLog
+index 4790b15..2905009 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Sep 08 21:21:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/utf8.c: test with small column sizes
++	* src/tds/query.c: fix column size preparing
++
+ Mon Sep  8 13:49:19 EDT 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/cspublic.h fix #define of BLK_VERSION_110 
+ 
+@@ -611,4 +615,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2600 2008/09/08 17:50:25 jklowden Exp $
++$Id: ChangeLog,v 1.2601 2008/09/08 19:22:44 freddy77 Exp $
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 721aabc..c353021 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.3 2008/08/17 08:08:06 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.4 2008/09/08 19:22:44 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -70,15 +70,58 @@ static const char * const strings_hex[] = {
+ 	NULL, NULL
+ };
+ 
++static char tmp[2048];
++
++static void
++TestBinding(int minimun)
++{
++	const char * const*p;
++	SQLINTEGER n;
++	SQLLEN n_len;
++
++	sprintf(tmp, "DELETE FROM %s", table_name);
++	Command(Statement, tmp);
++
++	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
++	sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) tmp, SQL_NTS));
++	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG,
++		SQL_INTEGER, 0, 0, &n, 0, &n_len));
++	n_len = sizeof(n);
++	
++	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
++		SQLLEN s1_len, s2_len;
++		int len;
++
++		len = minimun ? (strlen(strings_hex[p-strings]) - 2) /4 : 40;
++		CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
++			SQL_WCHAR, len, 0, (void *) p[0], 0, &s1_len));
++		len = minimun ? (strlen(strings_hex[p+1-strings]) - 2) /4 : 40;
++		/* FIXME this with SQL_VARCHAR produce wrong protocol data */
++		CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
++			SQL_WVARCHAR, len, 0, (void *) p[1], 0, &s2_len));
++		s1_len = strlen(p[0]);
++		s2_len = strlen(p[1]);
++		printf("insert #%d\n", (int) n);
++		CHK(SQLExecute, (Statement));
++	}
++
++	/* check rows */
++	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
++		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
++		CheckNoRow(tmp);
++	}
++
++	ResetStatement();
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+ 	int res;
+-	char tmp[2048];
+ 	SQLSMALLINT len;
+ 	const char * const*p;
+ 	SQLINTEGER n;
+-	SQLLEN n_len;
+ 
+ 	if (read_login_info())
+ 		exit(1);
+@@ -128,35 +171,10 @@ main(int argc, char *argv[])
+ 		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
+ 		CheckNoRow(tmp);
+ 	}
+-	sprintf(tmp, "DELETE FROM %s", table_name);
+-	Command(Statement, tmp);
+ 
+-	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+-	sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) tmp, SQL_NTS));
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG,
+-		SQL_INTEGER, 0, 0, &n, 0, &n_len));
+-	n_len = sizeof(n);
+-	
+-	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
+-		SQLLEN s1_len, s2_len;
++	TestBinding(0);
+ 
+-		CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
+-			SQL_WCHAR, 40, 0, (void *) p[0], 0, &s1_len));
+-		/* FIXME this with SQL_VARCHAR produce wrong protocol data */
+-		CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
+-			SQL_WVARCHAR, 40, 0, (void *) p[1], 0, &s2_len));
+-		s1_len = strlen(p[0]);
+-		s2_len = strlen(p[1]);
+-		printf("insert #%d\n", (int) n);
+-		CHK(SQLExecute, (Statement));
+-	}
+-
+-	/* check rows */
+-	for (n = 1, p = strings_hex; p[0] && p[1]; p += 2, ++n) {
+-		sprintf(tmp, "IF NOT EXISTS(SELECT * FROM %s WHERE k = %d AND c = %s AND vc = %s) SELECT 1", table_name, (int) n, p[0], p[1]);
+-		CheckNoRow(tmp);
+-	}
++	TestBinding(1);
+ 
+ 	/* cleanup */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 583ae88..b62fe5c 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.226 2008/09/04 06:43:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.227 2008/09/08 19:22:44 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -55,6 +55,7 @@ static int tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags);
+ static int tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ static char *tds7_build_param_def_from_query(TDSSOCKET * tds, const char* converted_query, int converted_query_len, TDSPARAMINFO * params, size_t *out_len);
+ static char *tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t query_len, TDSPARAMINFO * params, size_t *out_len);
++static int tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ 
+ static int tds_send_emulated_execute(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
+ static const char *tds_skip_comment(const char *s);
+@@ -613,10 +614,13 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ {
+ 	const char *fmt = NULL;
+ 	int max_len = IS_TDS7_PLUS(tds) ? 8000 : 255;
++	int size;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
++	size = tds_fix_column_size(tds, curcol);
++
+ 	switch (tds_get_conversion_type(curcol->on_server.column_type, curcol->on_server.column_size)) {
+ 	case XSYBCHAR:
+ 	case SYBCHAR:
+@@ -697,12 +701,14 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 		if (IS_TDS7_PLUS(tds)) {
+ 			fmt = "NVARCHAR(%d)";
+ 			max_len = 4000;
++			size /= 2;
+ 		}
+ 		break;
+ 	case XSYBNCHAR:
+ 		if (IS_TDS7_PLUS(tds)) {
+ 			fmt = "NCHAR(%d)";
+ 			max_len = 4000;
++			size /= 2;
+ 		}
+ 		break;
+ 		/* nullable types should not occur here... */
+@@ -723,9 +729,6 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 	}
+ 
+ 	if (fmt) {
+-		TDS_INT size = curcol->on_server.column_size;
+-		if (!size)
+-			size = curcol->column_size;
+ 		/* fill out */
+ 		sprintf(out, fmt, size > 0 ? (size > max_len ? max_len : size) : 1);
+ 		return TDS_SUCCEED;
+
+commit 433a2653bd3f3241be4f0855174c01a04547b59f
+Author: freddy77 <freddy77>
+Date:   Tue Sep 9 14:48:02 2008 +0000
+
+    allow to override PWD file path using TDSPWDFILE environment
+
+diff --git a/ChangeLog b/ChangeLog
+index 2905009..3fc6720 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Sep 09 16:41:08 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/common.c src/dblib/unittests/common.c:
++	* src/odbc/unittests/common.c src/tds/unittests/common.c:
++	- allow to override PWD file path using TDSPWDFILE environment
++
+ Mon Sep 08 21:21:57 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/utf8.c: test with small column sizes
+ 	* src/tds/query.c: fix column size preparing
+@@ -615,4 +620,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2601 2008/09/08 19:22:44 freddy77 Exp $
++$Id: ChangeLog,v 1.2602 2008/09/09 14:48:02 freddy77 Exp $
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index 6e19774..2b917e2 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -24,7 +24,7 @@
+ #include "common.h"
+ #include "ctlib.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.19 2008/08/27 07:28:46 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.20 2008/09/09 14:48:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -71,7 +71,7 @@ tds_dirname(char* path)
+ CS_RETCODE
+ read_login_info(void)
+ {
+-	FILE *in;
++	FILE *in = NULL;
+ 	char line[512];
+ 	char *s1, *s2;
+ 	
+@@ -83,7 +83,11 @@ read_login_info(void)
+ 		return CS_SUCCEED;
+ 	}
+ 
+-	in = fopen(PWD, "r");
++	s1 = getenv("TDSPWDFILE");
++	if (s1 && s1[0])
++		in = fopen(s1, "r");
++	if (!in)
++		in = fopen(PWD, "r");
+ 	if (!in) {
+ 		fprintf(stderr, "Can not open PWD file \"%s\"\n\n", PWD);
+ 		return CS_FAIL;
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 74c3d7c..37961a0 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -16,7 +16,7 @@
+ #include "replacements.h"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.23 2007/11/30 08:55:13 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.24 2008/09/09 14:48:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -90,7 +90,7 @@ read_login_info(int argc, char **argv)
+ 	extern char *optarg;
+ 	extern int optind;
+ 	
+-	FILE *in;
++	FILE *in = NULL;
+ #if !defined(__MINGW32__) && !defined(_MSC_VER)
+ 	int ch;
+ #endif
+@@ -140,8 +140,12 @@ read_login_info(int argc, char **argv)
+ 	}
+ #endif
+ 	strcpy(filename, PWD);
+-	
+-	in = fopen(filename, "r");
++
++	s1 = getenv("TDSPWDFILE");
++	if (s1 && s1[0])
++		in = fopen(s1, "r");
++	if (!in)
++		in = fopen(filename, "r");
+ 	if (!in)
+ 		in = fopen("PWD", "r");
+ 	if (!in) {
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 4d65095..82215d5 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.45 2008/05/22 03:53:17 jklowden Exp $";
++static char software_version[] = "$Id: common.c,v 1.46 2008/09/09 14:48:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -63,7 +63,7 @@ int
+ read_login_info(void)
+ {
+ 	static const char *PWD = "../../../PWD";
+-	FILE *in;
++	FILE *in = NULL;
+ 	char line[512];
+ 	char *s1, *s2;
+ #ifndef WIN32
+@@ -71,11 +71,11 @@ read_login_info(void)
+ 	int len;
+ #endif
+ 
+-#if 0
+-	in = fopen(".." TDS_SDIR_SEPARATOR ".." TDS_SDIR_SEPARATOR ".." TDS_SDIR_SEPARATOR "PWD", "r");
+-#else
+-	in = fopen(PWD, "r");
+-#endif
++	s1 = getenv("TDSPWDFILE");
++	if (s1 && s1[0])
++		in = fopen(s1, "r");
++	if (!in)
++		in = fopen(PWD, "r");
+ 	if (!in)
+ 		in = fopen("PWD", "r");
+ 
+diff --git a/src/tds/unittests/common.c b/src/tds/unittests/common.c
+index 99dcafc..fc9d2b0 100644
+--- a/src/tds/unittests/common.c
++++ b/src/tds/unittests/common.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.26 2005/04/15 20:30:18 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.27 2008/09/09 14:48:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -15,11 +15,15 @@ int read_login_info(void);
+ int
+ read_login_info(void)
+ {
+-	FILE *in;
++	FILE *in = NULL;
+ 	char line[512];
+ 	char *s1, *s2;
+ 
+-	in = fopen("../../../PWD", "r");
++	s1 = getenv("TDSPWDFILE");
++	if (s1 && s1[0])
++		in = fopen(s1, "r");
++	if (!in)
++		in = fopen("../../../PWD", "r");
+ 	if (!in) {
+ 		fprintf(stderr, "Can not open PWD file\n\n");
+ 		return TDS_FAIL;
+
+commit 91137228f83965df4c1465c4ad7bd2f4b28b029c
+Author: freddy77 <freddy77>
+Date:   Tue Sep 9 14:54:10 2008 +0000
+
+    be coherent about constants
+
+diff --git a/ChangeLog b/ChangeLog
+index 3fc6720..61376aa 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Sep 09 16:53:54 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c: be coherent about constants
++
+ Tue Sep 09 16:41:08 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/common.c src/dblib/unittests/common.c:
+ 	* src/odbc/unittests/common.c src/tds/unittests/common.c:
+@@ -620,4 +623,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2602 2008/09/09 14:48:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2603 2008/09/09 14:54:10 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 23b216e..af04ae2 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.71 2008/09/04 06:43:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.72 2008/09/09 14:54:12 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -205,7 +205,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 
+ 	/* we have no data to convert, just return */
+ 	if (!compute_row)
+-		return TDS_SUCCEED;
++		return SQL_SUCCESS;
+ 
+ 	src = drec_apd->sql_desc_data_ptr;
+ 	if (src && n_row) {
+@@ -297,7 +297,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 	assert(drec_ipd->sql_desc_parameter_type != SQL_PARAM_OUTPUT || sql_len == SQL_NULL_DATA);
+ 	if (sql_len == SQL_NULL_DATA) {
+ 		curcol->column_cur_size = -1;
+-		return TDS_SUCCEED;
++		return SQL_SUCCESS;
+ 	}
+ 
+ 	if (!src) {
+
+commit 8658a2d35527fa2090ca66f34facd15873755dd3
+Author: freddy77 <freddy77>
+Date:   Wed Sep 10 11:22:24 2008 +0000
+
+    improve error handling in ODBC
+
+diff --git a/ChangeLog b/ChangeLog
+index 61376aa..1a10362 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Sep 10 13:19:53 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- move odbc_convert_err_set in odbc_util and reuse it
++	- improve sql2tds error handling
++
+ Tue Sep 09 16:53:54 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c: be coherent about constants
+ 
+@@ -623,4 +629,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2603 2008/09/09 14:54:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2604 2008/09/10 11:22:24 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 2cfc74f..e9175ba 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.107 2008/08/18 13:31:26 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.108 2008/09/10 11:22:33 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -505,6 +505,7 @@ SQLSMALLINT odbc_get_concise_c_type(SQLSMALLINT type, SQLSMALLINT interval);
+ SQLRETURN odbc_set_concise_c_type(SQLSMALLINT concise_type, struct _drecord *drec, int check_only);
+ 
+ SQLLEN odbc_get_octet_len(int c_type, const struct _drecord *drec);
++void odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err);
+ 
+ /*
+  * prepare_query.c
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 7a1d15f..05a52c2 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.491 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.492 2008/09/10 11:22:34 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -988,10 +988,10 @@ odbc_build_update_params(TDS_STMT * stmt, unsigned int n_row)
+ 		curcol->table_namelen = strlen(curcol->table_name);
+ 
+ 		switch (sql2tds(stmt, drec_ird, &stmt->ard->records[n], curcol, 1, stmt->ard, n_row)) {
+-		case SQL_ERROR:
+ 		case SQL_NEED_DATA:
+-			tds_free_param_results(params);
+ 			odbc_errs_add(&stmt->errs, "HY001", NULL);
++		case SQL_ERROR:
++			tds_free_param_results(params);
+ 			return NULL;
+ 		}
+ 	}
+@@ -3438,32 +3438,6 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ 	}
+ }
+ 
+-static void
+-odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err)
+-{
+-	/*
+-	 * TODO we really need a column offset in the _sql_error structure so that caller can 
+-	 * invoke SQLGetDiagField to learn which column is failing
+-	 */
+-	switch (err) {
+-	case TDS_CONVERT_NOAVAIL:
+-		odbc_errs_add(errs, "HY003", NULL);
+-		break;
+-	case TDS_CONVERT_SYNTAX:
+-		odbc_errs_add(errs, "22018", NULL);
+-		break;
+-	case TDS_CONVERT_OVERFLOW:
+-		odbc_errs_add(errs, "22003", NULL);
+-		break;
+-	case TDS_CONVERT_FAIL:
+-		odbc_errs_add(errs, "07006", NULL);
+-		break;
+-	case TDS_CONVERT_NOMEM:
+-		odbc_errs_add(errs, "HY001", NULL);
+-		break;
+-	}
+-}
+-
+ /*
+  * - handle correctly SQLGetData (for forward cursors accept only row_size == 1
+  *   for other types application must use SQLSetPos)
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index f87948b..e29ab6e 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -33,12 +33,13 @@
+ #include <assert.h>
+ 
+ #include "tdsodbc.h"
++#include "tdsconvert.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.100 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.101 2008/09/10 11:22:35 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -1107,4 +1108,30 @@ odbc_get_octet_len(int c_type, const struct _drecord *drec)
+ 	return len;
+ }
+ 
++void
++odbc_convert_err_set(struct _sql_errors *errs, TDS_INT err)
++{
++	/*
++	 * TODO we really need a column offset in the _sql_error structure so that caller can
++	 * invoke SQLGetDiagField to learn which column is failing
++	 */
++	switch (err) {
++	case TDS_CONVERT_NOAVAIL:
++		odbc_errs_add(errs, "HY003", NULL);
++		break;
++	case TDS_CONVERT_SYNTAX:
++		odbc_errs_add(errs, "22018", NULL);
++		break;
++	case TDS_CONVERT_OVERFLOW:
++		odbc_errs_add(errs, "22003", NULL);
++		break;
++	case TDS_CONVERT_FAIL:
++		odbc_errs_add(errs, "07006", NULL);
++		break;
++	case TDS_CONVERT_NOMEM:
++		odbc_errs_add(errs, "HY001", NULL);
++		break;
++	}
++}
++
+ /** @} */
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 9e2be47..da2e8f3 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.70 2008/09/04 06:43:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.71 2008/09/10 11:22:36 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -366,17 +366,8 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 					data[1] = *(char*)DataPtr;
+ 				    
+ 					res = tds_convert(dbc->env->tds_ctx, src_type, data, 2, dest_type, &ores);
+-					switch(res) {
+-					case TDS_CONVERT_FAIL:
+-					case TDS_CONVERT_NOAVAIL:
+-					case TDS_CONVERT_SYNTAX:
+-						odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
+-						return SQL_ERROR;
+-					case TDS_CONVERT_NOMEM:
+-						odbc_errs_add(&dbc->errs, "HY001", NULL); /* Memory allocation error */
+-						return SQL_ERROR;
+-					case TDS_CONVERT_OVERFLOW:
+-						odbc_errs_add(&dbc->errs, "22003", NULL); /* Numeric value out of range */
++					if (res < 0) {
++						odbc_convert_err_set(&dbc->errs, res);
+ 						return SQL_ERROR;
+ 					}
+ 				    
+@@ -394,19 +385,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 
+ 				res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr+start, len, dest_type, &ores);
+ 				if (res < 0) {
+-					switch(res) {
+-					case TDS_CONVERT_FAIL:
+-					case TDS_CONVERT_NOAVAIL:
+-					case TDS_CONVERT_SYNTAX:
+-						odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
+-						break;
+-					case TDS_CONVERT_NOMEM:
+-						odbc_errs_add(&dbc->errs, "HY001", NULL); /* Memory allocation error */
+-						break;
+-					case TDS_CONVERT_OVERFLOW:
+-						odbc_errs_add(&dbc->errs, "22003", NULL); /* Numeric value out of range */
+-						break;
+-					}
++					odbc_convert_err_set(&dbc->errs, res);
+ 					free(extradata);
+ 					return SQL_ERROR;
+ 				}
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index af04ae2..82fc484 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.72 2008/09/09 14:54:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.73 2008/09/10 11:22:36 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -152,6 +152,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 	/* what type to convert ? */
+ 	dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type);
+ 	if (dest_type == TDS_FAIL)
++		/* TODO fill error */
+ 		return SQL_ERROR;
+ 	tdsdump_log(TDS_DBG_INFO2, "trace\n");
+ 
+@@ -201,6 +202,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 	/* TODO test intervals */
+ 	src_type = odbc_c_to_server_type(sql_src_type);
+ 	if (src_type == TDS_FAIL)
++		/* TODO fill error */
+ 		return SQL_ERROR;
+ 
+ 	/* we have no data to convert, just return */
+@@ -218,6 +220,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			len = odbc_get_octet_len(sql_src_type, drec_apd);
+ 			if (len < 0)
+ 				/* TODO sure ? what happen to upper layer ?? */
++				/* TODO fill error */
+ 				return SQL_ERROR;
+ 		}
+ 		src += len * n_row;
+@@ -254,7 +257,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 		break;
+ 	case SQL_DEFAULT_PARAM:
+ 	case SQL_DATA_AT_EXEC:
+-		/* TODO */
++		/* TODO fill error */
+ 		return SQL_ERROR;
+ 		break;
+ 	default:
+@@ -267,6 +270,7 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			case SQL_C_BINARY:
+ 				break;
+ 			default:
++				/* TODO fill error */
+ 				return SQL_ERROR;
+ 			}
+ 			len = SQL_LEN_DATA_AT_EXEC(sql_len);
+@@ -279,14 +283,17 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 			case SQL_LONGVARBINARY:
+ 				break;
+ 			default:
++				/* TODO fill error */
+ 				return SQL_ERROR;
+ 			}
+ 		}
+ 	}
+ 
+ 	/* allocate given space */
+-	if (!tds_alloc_param_data(curcol))
++	if (!tds_alloc_param_data(curcol)) {
++		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		return SQL_ERROR;
++	}
+ 
+ 	if (need_data) {
+ 		curcol->column_cur_size = 0;
+@@ -403,8 +410,10 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 		break;
+ 	}
+ 
+-	if (res < 0)
++	if (res < 0) {
++		odbc_convert_err_set(&stmt->errs, res);
+ 		return SQL_ERROR;
++	}
+ 
+ 	curcol->column_cur_size = res;
+ 
+
+commit 44e3cee5d12238feae07d809f7affe7a730ddfb1
+Author: freddy77 <freddy77>
+Date:   Wed Sep 10 11:37:05 2008 +0000
+
+    avoid useless buffer allocations
+
+diff --git a/ChangeLog b/ChangeLog
+index 1a10362..35488f2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Sep 10 13:36:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/sql2tds.c:
++	- avoid useless buffer allocations
++
+ Wed Sep 10 13:19:53 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
+@@ -629,4 +633,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2604 2008/09/10 11:22:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2605 2008/09/10 11:37:05 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 05a52c2..e4bce55 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.492 2008/09/10 11:22:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.493 2008/09/10 11:37:06 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -975,11 +975,6 @@ odbc_build_update_params(TDS_STMT * stmt, unsigned int n_row)
+                 params = temp_params;
+ 
+ 		curcol = params->columns[params->num_cols - 1];
+-		if (!tds_alloc_param_data(curcol)) {
+-			tds_free_param_results(params);
+-			odbc_errs_add(&stmt->errs, "HY001", NULL);
+-			return NULL;
+-		}
+ 		tds_strlcpy(curcol->column_name, tds_dstr_cstr(&drec_ird->sql_desc_name), sizeof(curcol->column_name));
+ 		curcol->column_namelen = strlen(curcol->column_name);
+ 
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 82fc484..9fbcb84 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.73 2008/09/10 11:22:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.74 2008/09/10 11:37:08 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -289,6 +289,15 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 		}
+ 	}
+ 
++	/* set NULL. For NULLs we don't need to allocate row buffer so avoid it */
++	if (!need_data) {
++		assert(drec_ipd->sql_desc_parameter_type != SQL_PARAM_OUTPUT || sql_len == SQL_NULL_DATA);
++		if (sql_len == SQL_NULL_DATA) {
++			curcol->column_cur_size = -1;
++			return SQL_SUCCESS;
++		}
++	}
++
+ 	/* allocate given space */
+ 	if (!tds_alloc_param_data(curcol)) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+@@ -300,13 +309,6 @@ sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord
+ 		return SQL_NEED_DATA;
+ 	}
+ 
+-	/* set null */
+-	assert(drec_ipd->sql_desc_parameter_type != SQL_PARAM_OUTPUT || sql_len == SQL_NULL_DATA);
+-	if (sql_len == SQL_NULL_DATA) {
+-		curcol->column_cur_size = -1;
+-		return SQL_SUCCESS;
+-	}
+-
+ 	if (!src) {
+ 		odbc_errs_add(&stmt->errs, "HY090", NULL);
+ 		return SQL_ERROR;
+
+commit d6f72342a71a6fbabda745d348801c5b42efc932
+Author: freddy77 <freddy77>
+Date:   Thu Sep 11 15:09:48 2008 +0000
+
+    renamed sql2tds -> odbc_sql2tds and convert_tds2sql -> odbc_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index 35488f2..00c6825 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Sep 11 17:07:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- renamed sql2tds -> odbc_sql2tds and convert_tds2sql -> odbc_tds2sql
++
+ Wed Sep 10 13:36:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/sql2tds.c:
+ 	- avoid useless buffer allocations
+@@ -633,4 +638,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2605 2008/09/10 11:37:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2606 2008/09/11 15:09:48 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index e9175ba..c0a3597 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.108 2008/09/10 11:22:33 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.109 2008/09/11 15:09:49 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -439,7 +439,7 @@ int odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection);
+ /*
+  * convert_tds2sql.c
+  */
+-TDS_INT convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
++TDS_INT odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
+ 
+ /*
+  * descriptor.c
+@@ -520,7 +520,7 @@ const char *parse_const_param(const char * s, TDS_SERVER_TYPE *type);
+ /*
+  * sql2tds.c
+  */
+-SQLRETURN sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _drecord *drec_axd, TDSCOLUMN *curcol, int compute_row, const TDS_DESC* axd, unsigned int n_row);
++SQLRETURN odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ixd, const struct _drecord *drec_axd, TDSCOLUMN *curcol, int compute_row, const TDS_DESC* axd, unsigned int n_row);
+ 
+ /*
+  * sqlwchar.c
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 62cfa48..50e8afb 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -39,11 +39,11 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.51 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.52 2008/09/11 15:09:49 freddy77 Exp $");
+ 
+ TDS_INT
+-convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+-		const struct _drecord *drec_ixd)
++odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
++	     const struct _drecord *drec_ixd)
+ {
+ 	TDS_INT nDestSybType;
+ 	TDS_INT nRetVal = TDS_FAIL;
+@@ -59,7 +59,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 	int ret = TDS_CONVERT_FAIL;
+ 	int i, cplen;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "convert_tds2sql: src is %d dest = %d\n", srctype, desttype);
++	tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: src is %d dest = %d\n", srctype, desttype);
+ 
+ 	assert(desttype != SQL_C_DEFAULT);
+ 
+@@ -69,7 +69,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 
+ 	/* special case for binary type */
+ 	if (desttype == SQL_C_BINARY) {
+-		tdsdump_log(TDS_DBG_FUNC, "convert_tds2sql: outputting binary data destlen = %lu \n", (unsigned long) destlen);
++		tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: outputting binary data destlen = %lu \n", (unsigned long) destlen);
+ 
+ 		if (is_numeric_type(srctype)) {
+ 			desttype = SQL_C_NUMERIC;
+@@ -128,7 +128,7 @@ convert_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srcl
+ 	switch (desttype) {
+ 
+ 	case SQL_C_CHAR:
+-		tdsdump_log(TDS_DBG_FUNC, "convert_tds2sql: outputting character data destlen = %lu \n", (unsigned long) destlen);
++		tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: outputting character data destlen = %lu \n", (unsigned long) destlen);
+ 
+ 		ret = nRetVal;
+ 		/* TODO handle not terminated configuration */
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index e4bce55..bc6032a 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.493 2008/09/10 11:37:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.494 2008/09/11 15:09:49 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -982,7 +982,7 @@ odbc_build_update_params(TDS_STMT * stmt, unsigned int n_row)
+ 		tds_strlcpy(curcol->table_name, tds_dstr_cstr(&drec_ird->sql_desc_base_table_name), sizeof(curcol->table_name));
+ 		curcol->table_namelen = strlen(curcol->table_name);
+ 
+-		switch (sql2tds(stmt, drec_ird, &stmt->ard->records[n], curcol, 1, stmt->ard, n_row)) {
++		switch (odbc_sql2tds(stmt, drec_ird, &stmt->ard->records[n], curcol, 1, stmt->ard, n_row)) {
+ 		case SQL_NEED_DATA:
+ 			odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		case SQL_ERROR:
+@@ -3664,7 +3664,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				} else {
+ 					data_ptr += odbc_get_octet_len(c_type, drec_ard) * curr_row;
+ 				}
+-				len = convert_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
++				len = odbc_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+ 				if (len < 0) {
+ 					odbc_convert_err_set(&stmt->errs, len);
+@@ -4738,7 +4738,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 							ODBC_RETURN(stmt, SQL_NO_DATA);
+ 						
+ 						if (cbValueMax > 2) {
+-							len = convert_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
++							len = odbc_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
+ 							if (len < 2) {
+ 								if (len < 0) 
+ 									odbc_convert_err_set(&stmt->errs, len);
+@@ -4797,7 +4797,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			srclen = colinfo->column_cur_size;
+ 		}
+ 
+-		*pcbValue = convert_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
++		*pcbValue = odbc_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ 		if (*pcbValue < 0) {
+ 			odbc_convert_err_set(&stmt->errs, *pcbValue);
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index e29ab6e..2122d0e 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.101 2008/09/10 11:22:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.102 2008/09/11 15:09:49 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -139,8 +139,8 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ 		}
+ #define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))
+ 
+-		len = convert_tds2sql(context, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
+-				      drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
++		len = odbc_tds2sql(context, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
++				   drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
+ 		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+ 		if (drec->sql_desc_indicator_ptr)
+@@ -221,8 +221,8 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 		 * TODO why IPD ?? perhaps SQLBindParameter it's not correct ??
+ 		 * Or tests are wrong ??
+ 		 */
+-		len = convert_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size), src, srclen,
+-				      c_type, (void *) data_ptr, drec_apd->sql_desc_octet_length, drec_ipd);
++		len = odbc_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size), src, srclen,
++				   c_type, (void *) data_ptr, drec_apd->sql_desc_octet_length, drec_ipd);
+ 		/* TODO error handling */
+ 		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index da2e8f3..f2f642f 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.71 2008/09/10 11:22:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.72 2008/09/11 15:09:49 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -170,7 +170,7 @@ prepared_rpc(struct _hstmt *stmt, int compute_row)
+ 				return SQL_ERROR;
+ 			}
+ 
+-			switch (sql2tds
++			switch (odbc_sql2tds
+ 				(stmt, &stmt->ipd->records[stmt->param_num - 1], &stmt->apd->records[stmt->param_num - 1],
+ 				 curcol, compute_row, stmt->apd, stmt->curr_param_row)) {
+ 			case SQL_ERROR:
+@@ -219,7 +219,7 @@ parse_prepared_query(struct _hstmt *stmt, int compute_row)
+ 		}
+ 		stmt->params = temp_params;
+ 
+-		switch (sql2tds
++		switch (odbc_sql2tds
+ 			(stmt, &stmt->ipd->records[stmt->param_num - 1], &stmt->apd->records[stmt->param_num - 1],
+ 			 stmt->params->columns[nparam], compute_row, stmt->apd, stmt->curr_param_row)) {
+ 		case SQL_ERROR:
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 9fbcb84..53ade07 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -52,7 +52,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.74 2008/09/10 11:37:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.75 2008/09/11 15:09:50 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -130,7 +130,7 @@ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+  * @return SQL_SUCCESS, SQL_ERROR or SQL_NEED_DATA
+  */
+ SQLRETURN
+-sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord *drec_apd, TDSCOLUMN *curcol,
++odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _drecord *drec_apd, TDSCOLUMN *curcol,
+ 	int compute_row, const TDS_DESC* axd, unsigned int n_row)
+ {
+ 	TDS_DBC * dbc = stmt->dbc;
+
+commit 118cdbe2c678521ac6b69587b49c15520a6727b0
+Author: freddy77 <freddy77>
+Date:   Fri Sep 12 15:12:23 2008 +0000
+
+    remove broken_money setting, remove is_binary_type macro, add no_data_conv option
+
+diff --git a/ChangeLog b/ChangeLog
+index 00c6825..c0f769f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Fri Sep 12 17:05:54 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/config.c src/tds/token.c:
++	- removed is_binary_type macro, not used anymore
++	- removed broken_money setting, not used
++	- added no_data_conv to disable data conversions
++	* src/odbc/odbc.c src/odbc/unittests/data.c:
++	- updated to support no_data_conv
++
+ Thu Sep 11 17:07:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
+ 	* src/odbc/odbc_util.c src/odbc/prepare_query.c src/odbc/sql2tds.c:
+@@ -638,4 +646,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2606 2008/09/11 15:09:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2607 2008/09/12 15:12:23 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index bdce7a6..a59f9ae 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.293 2008/08/14 08:49:22 freddy77 Exp $ */
++/* $Id: tds.h,v 1.294 2008/09/12 15:12:23 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -749,7 +749,6 @@ typedef enum tds_encryption_level {
+ #define is_unicode_type(x) (x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
+ #define is_collate_type(x) (x==XSYBVARCHAR || x==XSYBCHAR || x==SYBTEXT || x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
+ #define is_ascii_type(x) ( x==XSYBCHAR || x==XSYBVARCHAR || x==SYBTEXT || x==SYBCHAR || x==SYBVARCHAR)
+-#define is_binary_type(x) (x==SYBLONGBINARY)
+ #define is_char_type(x) (is_unicode_type(x) || is_ascii_type(x))
+ #define is_similar_type(x, y) ((is_char_type(x) && is_char_type(y)) || ((is_unicode_type(x) && is_unicode_type(y))))
+ 
+@@ -790,7 +789,6 @@ typedef enum tds_encryption_level {
+ #define TDS_STR_VERSION  "tds version"
+ #define TDS_STR_BLKSZ    "initial block size"
+ #define TDS_STR_SWAPDT   "swap broken dates"
+-#define TDS_STR_SWAPMNY  "swap broken money"
+ #define TDS_STR_DUMPFILE "dump file"
+ #define TDS_STR_DEBUGLVL "debug level"
+ #define TDS_STR_DEBUGFLAGS "debug flags"
+@@ -884,9 +882,8 @@ typedef struct tds_connection
+ 	DSTR dump_file;
+ 	int debug_flags;
+ 	int text_size;
+-	int broken_dates;
+-	int broken_money;
+-	int emul_little_endian;
++	unsigned int broken_dates:1;
++	unsigned int emul_little_endian:1;
+ } TDSCONNECTION;
+ 
+ typedef struct tds_locale
+@@ -1291,8 +1288,12 @@ struct tds_socket
+ 	char *product_name;
+ 
+ 	unsigned char capabilities[TDS_MAX_CAPABILITY];
+-	unsigned char broken_dates;
+ 	unsigned char option_flag2;
++	unsigned int broken_dates:1;
++	unsigned int emul_little_endian:1;
++#ifdef ENABLE_DEVELOPING
++	unsigned int no_data_conv:1;
++#endif
+ 
+ 	unsigned char *in_buf;		/**< input buffer */
+ 	unsigned char *out_buf;		/**< output buffer */
+@@ -1332,7 +1333,6 @@ struct tds_socket
+ 	TDSDYNAMIC *cur_dyn;		/**< dynamic structure in use */
+ 	TDSDYNAMIC *dyns;		/**< list of dynamic allocate for this connection */
+ 
+-	int emul_little_endian;
+ 	char *date_fmt;
+ 	const TDSCONTEXT *tds_ctx;
+ 	int char_conv_count;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index bc6032a..edf4895 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.494 2008/09/11 15:09:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.495 2008/09/12 15:12:23 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -371,6 +371,9 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
++#ifdef ENABLE_DEVELOPING
++	dbc->tds_socket->no_data_conv = 1;
++#endif
+ 	tds_set_parent(dbc->tds_socket, (void *) dbc);
+ 
+ 	/* Set up our environment change hook */
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 5361db9..e76805a 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test various bind type */
+ 
+-static char software_version[] = "$Id: data.c,v 1.17 2008/08/27 07:44:39 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.18 2008/09/12 15:12:24 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -133,7 +133,7 @@ main(int argc, char *argv[])
+ 	Test("MONEY", "4321234.5678", SQL_C_BINARY, big_endian ? "0000000A0FA8114E" : "0A0000004E11A80F");
+ 
+ 	/* behavior is different from MS ODBC */
+-	if (db_is_microsoft() && !driver_is_freetds()) {
++	if (db_is_microsoft()) {
+ 		Test("NCHAR(7)", "donald", SQL_C_BINARY, "64006F006E0061006C0064002000");
+ 		Test("NTEXT", "duck", SQL_C_BINARY, "6400750063006B00");
+ 		Test("NVARCHAR(20)", "daffy", SQL_C_BINARY, "64006100660066007900");
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 22356ff..3b8f6e7 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.136 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.137 2008/09/12 15:12:23 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -220,7 +220,6 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %x\n", "debug_flags", connection->debug_flags);
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "text_size", connection->text_size);
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "broken_dates", connection->broken_dates);
+-		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "broken_money", connection->broken_money);
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "emul_little_endian", connection->emul_little_endian);
+ 
+ 		tdsdump_close();
+@@ -500,8 +499,6 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ 			connection->block_size = val;
+ 	} else if (!strcmp(option, TDS_STR_SWAPDT)) {
+ 		connection->broken_dates = tds_config_boolean(value);
+-	} else if (!strcmp(option, TDS_STR_SWAPMNY)) {
+-		connection->broken_money = tds_config_boolean(value);
+ 	} else if (!strcmp(option, TDS_STR_DUMPFILE)) {
+ 		tds_dstr_copy(&connection->dump_file, value);
+ 	} else if (!strcmp(option, TDS_STR_DEBUGFLAGS)) {
+diff --git a/src/tds/token.c b/src/tds/token.c
+index d8321f5..210834f 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.351 2008/08/18 13:31:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.352 2008/09/12 15:12:23 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2099,7 +2099,14 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		 * Here we allocate memory, if need be.  
+ 		 */
+ 		/* TODO this can lead to a big waste of memory */
++#ifdef ENABLE_DEVELOPING
++		if (!tds->no_data_conv)
++			new_blob_size = determine_adjusted_size(curcol->char_conv, colsize);
++		else
++			new_blob_size = colsize;
++#else
+ 		new_blob_size = determine_adjusted_size(curcol->char_conv, colsize);
++#endif
+ 		if (new_blob_size == 0) {
+ 			curcol->column_cur_size = 0;
+ 			if (blob->textvalue)
+@@ -2123,7 +2130,11 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		curcol->column_cur_size = new_blob_size;
+ 		
+ 		/* read the data */
+-		if (is_char_type(curcol->column_type)) {
++#ifdef ENABLE_DEVELOPING
++		if (!tds->no_data_conv && curcol->char_conv) {
++#else
++		if (curcol->char_conv) {
++#endif
+ 			if (tds_get_char_data(tds, (char *) blob, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
+ 		} else {
+@@ -2133,7 +2144,11 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	} else {		/* non-numeric and non-blob */
+ 		curcol->column_cur_size = colsize;
+ 
++#ifdef ENABLE_DEVELOPING
++		if (!tds->no_data_conv && curcol->char_conv) {
++#else
+ 		if (curcol->char_conv) {
++#endif
+ 			if (tds_get_char_data(tds, (char *) dest, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
+ 		} else {	
+@@ -3365,7 +3380,7 @@ adjust_character_column_size(const TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	if (!curcol->char_conv && IS_TDS7_PLUS(tds) && is_ascii_type(curcol->on_server.column_type))
+ 		curcol->char_conv = tds->char_convs[client2server_chardata];
+ 
+-	if (!curcol->char_conv)
++	if (tds->no_data_conv || !curcol->char_conv)
+ 		return;
+ 
+ 	curcol->on_server.column_size = curcol->column_size;
+
+commit 48a86712d7d57651feca3abdf8e2da470d42773a
+Author: freddy77 <freddy77>
+Date:   Sat Sep 13 07:18:46 2008 +0000
+
+    fix compile if no --enable-development
+
+diff --git a/ChangeLog b/ChangeLog
+index c0f769f..63f27a5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Sep 13 09:18:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix compile if no --enable-development
++
+ Fri Sep 12 17:05:54 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/config.c src/tds/token.c:
+ 	- removed is_binary_type macro, not used anymore
+@@ -646,4 +649,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2607 2008/09/12 15:12:23 freddy77 Exp $
++$Id: ChangeLog,v 1.2608 2008/09/13 07:18:46 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 210834f..85e60dd 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.352 2008/09/12 15:12:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.353 2008/09/13 07:18:46 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -3380,7 +3380,11 @@ adjust_character_column_size(const TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	if (!curcol->char_conv && IS_TDS7_PLUS(tds) && is_ascii_type(curcol->on_server.column_type))
+ 		curcol->char_conv = tds->char_convs[client2server_chardata];
+ 
++#ifdef ENABLE_DEVELOPING
+ 	if (tds->no_data_conv || !curcol->char_conv)
++#else
++	if (!curcol->char_conv)
++#endif
+ 		return;
+ 
+ 	curcol->on_server.column_size = curcol->column_size;
+
+commit a81760ebe720e276a9ce3dda1a54db4f591fd6f9
+Author: freddy77 <freddy77>
+Date:   Sun Sep 14 07:45:24 2008 +0000
+
+    renamed TDSSOCKET->no_data_conv to TDSSOCKET->use_iconv
+
+diff --git a/ChangeLog b/ChangeLog
+index 63f27a5..1cfef99 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Sep 14 09:44:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/odbc.c src/tds/mem.c src/tds/token.c:
++	- renamed TDSSOCKET->no_data_conv to TDSSOCKET->use_iconv
++
+ Sat Sep 13 09:18:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: fix compile if no --enable-development
+ 
+@@ -649,4 +653,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2608 2008/09/13 07:18:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2609 2008/09/14 07:45:24 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index a59f9ae..38dc14f 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.294 2008/09/12 15:12:23 freddy77 Exp $ */
++/* $Id: tds.h,v 1.295 2008/09/14 07:45:24 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1292,7 +1292,7 @@ struct tds_socket
+ 	unsigned int broken_dates:1;
+ 	unsigned int emul_little_endian:1;
+ #ifdef ENABLE_DEVELOPING
+-	unsigned int no_data_conv:1;
++	unsigned int use_iconv:1;
+ #endif
+ 
+ 	unsigned char *in_buf;		/**< input buffer */
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index edf4895..5778351 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.495 2008/09/12 15:12:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.496 2008/09/14 07:45:24 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -372,7 +372,7 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+ #ifdef ENABLE_DEVELOPING
+-	dbc->tds_socket->no_data_conv = 1;
++	dbc->tds_socket->use_iconv = 0;
+ #endif
+ 	tds_set_parent(dbc->tds_socket, (void *) dbc);
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 42d9866..e90e919 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.178 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.179 2008/09/14 07:45:25 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -966,6 +966,9 @@ tds_alloc_socket(TDSCONTEXT * context, int bufsize)
+ 	tds_socket->option_flag2 = 0x03;
+ 	tds_socket->env.block_size = bufsize;
+ 
++#ifdef ENABLE_DEVELOPING
++	tds_socket->use_iconv = 1;
++#endif
+ 	if (tds_iconv_alloc(tds_socket))
+ 		goto Cleanup;
+ 
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 85e60dd..bb009f3 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.353 2008/09/13 07:18:46 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.354 2008/09/14 07:45:25 freddy77 Exp $");
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2100,7 +2100,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		 */
+ 		/* TODO this can lead to a big waste of memory */
+ #ifdef ENABLE_DEVELOPING
+-		if (!tds->no_data_conv)
++		if (tds->use_iconv)
+ 			new_blob_size = determine_adjusted_size(curcol->char_conv, colsize);
+ 		else
+ 			new_blob_size = colsize;
+@@ -2131,7 +2131,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		
+ 		/* read the data */
+ #ifdef ENABLE_DEVELOPING
+-		if (!tds->no_data_conv && curcol->char_conv) {
++		if (tds->use_iconv && curcol->char_conv) {
+ #else
+ 		if (curcol->char_conv) {
+ #endif
+@@ -2145,7 +2145,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		curcol->column_cur_size = colsize;
+ 
+ #ifdef ENABLE_DEVELOPING
+-		if (!tds->no_data_conv && curcol->char_conv) {
++		if (tds->use_iconv && curcol->char_conv) {
+ #else
+ 		if (curcol->char_conv) {
+ #endif
+@@ -3381,7 +3381,7 @@ adjust_character_column_size(const TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		curcol->char_conv = tds->char_convs[client2server_chardata];
+ 
+ #ifdef ENABLE_DEVELOPING
+-	if (tds->no_data_conv || !curcol->char_conv)
++	if (!tds->use_iconv || !curcol->char_conv)
+ #else
+ 	if (!curcol->char_conv)
+ #endif
+
+commit 53332fe3efea9441229db4b0b430e524edc46d42
+Author: freddy77 <freddy77>
+Date:   Wed Sep 17 07:28:34 2008 +0000
+
+    add types.txt file
+
+diff --git a/misc/.cvsignore b/misc/.cvsignore
+new file mode 100644
+index 0000000..854892b
+--- /dev/null
++++ b/misc/.cvsignore
+@@ -0,0 +1 @@
++types.csv
+diff --git a/misc/types.sh b/misc/types.sh
+new file mode 100755
+index 0000000..cb8ae64
+--- /dev/null
++++ b/misc/types.sh
+@@ -0,0 +1,4 @@
++#!/bin/sh
++perl -p -i.orig -e "s/\r//g; s/\t+$//" types.txt
++perl -pe 's/\t/;/g; s/\n/\r\n/s' < types.txt > types.csv
++
+diff --git a/misc/types.txt b/misc/types.txt
+new file mode 100644
+index 0000000..79db411
+--- /dev/null
++++ b/misc/types.txt
+@@ -0,0 +1,67 @@
++Name	vendor	varint	fixed	nullable	variable	blob	numeric	unicode	ascii	size	nullable type
++SYB5INT8	SYB	0	0	0	0	0	0	0	0	8	SYBINTN
++SYBBINARY	ALL	1	0	1	1	0	0	0	0	-1	0
++SYBBIT	ALL	0	1	0	0	0	0	0	0	1	SYBBITN
++SYBBITN	MS	1	0	1	0	0	0	0	0	1	0	# Sybase bit is not nullable
++SYBBLOB	SYB	??	0	1	1	1	0	Depend	Depend	-1	0
++SYBBOUNDARY	SYB	1	0	1	1	0	0	0	1	-1	0
++SYBCHAR	ALL	1	0	1	1	0	0	0	1	-1	0
++SYBDATE	SYB	0	1	0	0	0	0	0	0	4	SYBDATEN
++SYBDATEN	SYB	1	0	1	0	0	0	0	0	4	0
++SYBDATETIME	ALL	0	1	0	0	0	0	0	0	8	SYBDATETIMN
++SYBDATETIME4	ALL	0	1	0	0	0	0	0	0	4	SYBDATETIMN
++SYBDATETIMN	ALL	1	0	1	0	0	0	0	0	-1	0
++SYBDECIMAL	ALL	1	0	1	0	0	1	0	0	-1	0
++SYBFLT8	ALL	0	1	0	0	0	0	0	0	8	SYBFLTN
++SYBFLTN	ALL	1	0	1	0	0	0	0	0	-1	0
++SYBIMAGE	ALL	4	0	1	1	1	0	0	0	-1	0
++SYBINT1	ALL	0	1	0	0	0	0	0	0	1	SYBINTN
++SYBINT2	ALL	0	1	0	0	0	0	0	0	2	SYBINTN
++SYBINT4	ALL	0	1	0	0	0	0	0	0	4	SYBINTN
++SYBINT8	MS	0	1	0	0	0	0	0	0	8	SYBINTN
++SYBINTERVAL	SYB	0	1	0	0	0	0	0	0	8	0
++SYBINTN	ALL	1	0	1	0	0	0	0	0	-1	0
++SYBLONGBINARY	SYB	5	0	1	1	1	0	Depend	Depend	-1	0
++SYBLONGCHAR	SYB	5	0	1	1	1	0	??	??	-1	0
++SYBMONEY	ALL	0	1	0	0	0	0	0	0	8	SYBMONEYN
++SYBMONEY4	ALL	0	1	0	0	0	0	0	0	4	SYBMONEYN
++SYBMONEYN	ALL	1	0	1	0	0	0	0	0	-1	0
++SYBMSUDT	MS	??	0	1	1	??	0	??	??	-1	0
++SYBMSXML	MS	??	0	1	1	??	0	??	??	-1	0
++SYBNTEXT	MS	4	0	1	1	1	0	1	0	-1	0
++SYBNUMERIC	ALL	1	0	1	0	0	1	0	0	-1	0
++SYBNVARCHAR	MS	??	0	1	1	0	0	1	0	-1	0	# Same as XSYBNVARCHAR ??
++SYBREAL	ALL	0	1	0	0	0	0	0	0	4	SYBFLTN
++SYBSENSITIVITY	SYB	1	0	1	1	0	0	0	1	-1	0
++SYBSINT1	SYB	0	1	0	0	0	0	0	0	1	0
++SYBTEXT	ALL	4	0	1	1	1	0	0	1	-1	0
++SYBTIME	SYB	0	1	0	0	0	0	0	0	4	SYBTIMEN
++SYBTIMEN	SYB	1	0	1	0	0	0	0	0	4	0
++SYBUINT1	SYB	0	1	0	0	0	0	0	0	1	SYBUINTN
++SYBUINT2	SYB	0	1	0	0	0	0	0	0	2	SYBUINTN
++SYBUINT4	SYB	0	1	0	0	0	0	0	0	4	SYBUINTN
++SYBUINT8	SYB	0	1	0	0	0	0	0	0	8	SYBUINTN
++SYBUINTN	SYB	1	0	1	0	0	0	0	0	-1	0
++SYBUNIQUE	MS	1	0	1	0	0	0	0	0	16	0	# have size but is nullable
++SYBUNITEXT	SYB	4	0	1	1	1	0	1	0	-1	0	# UTF-16
++SYBVARBINARY	ALL	1	0	1	1	0	0	0	0	-1	0
++SYBVARCHAR	ALL	1	0	1	1	0	0	0	1	-1	0
++SYBVARIANT	MS	4	0	1	1	0	0	Depend	Depend	-1	0	# varint ok ?
++SYBVOID	MS ??	0	1	0	0	0	0	0	0	0	0
++SYBXML	SYB	4	0	1	1	1	0	??	??	-1	0
++XSYBBINARY	MS	2	0	1	1	0	0	0	0	-1	0
++XSYBCHAR	MS	2	0	1	1	0	0	0	1	-1	0
++XSYBNCHAR	MS	2	0	1	1	0	0	1	0	-1	0
++XSYBNVARCHAR	MS	2	0	1	1	0	0	1	0	-1	0
++XSYBVARBINARY	MS	2	0	1	1	0	0	0	0	-1	0
++XSYBVARCHAR	MS	2	0	1	1	0	0	0	1	-1	0
++
++# XSYBVARCHAR blob se TDS9 ??
++# char if ascii or unicode
++# there are some type that allow size 0 or a constants (SYBDATEN, SYBUNIQUE)
++# some type (BITN, DATEN, UNIQUE) have size but are nullable
++# tds_get_conversion_type from nullable to not nullable
++# tds_get_cardinal_type ??
++
++# $Id: types.txt,v 1.1 2008/09/17 07:28:36 freddy77 Exp $
++
+
+commit a56b7f4f286ff46c4f2cf8465a87d55ce6d55167
+Author: freddy77 <freddy77>
+Date:   Wed Sep 17 12:16:06 2008 +0000
+
+    autogenerate some functions based on types.txt
+
+diff --git a/ChangeLog b/ChangeLog
+index 1cfef99..97c2027 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Sep 17 14:14:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/.cvsignore src/tds/Makefile.am src/tds/convert.c:
++	* src/tds/data.c src/tds/read.c src/tds/types.pl(added):
++	- autogenerate some functions based on types.txt
++
+ Sun Sep 14 09:44:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/odbc.c src/tds/mem.c src/tds/token.c:
+ 	- renamed TDSSOCKET->no_data_conv to TDSSOCKET->use_iconv
+@@ -653,4 +658,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2609 2008/09/14 07:45:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2610 2008/09/17 12:16:06 freddy77 Exp $
+diff --git a/src/tds/.cvsignore b/src/tds/.cvsignore
+index f9b4f83..1460e60 100644
+--- a/src/tds/.cvsignore
++++ b/src/tds/.cvsignore
+@@ -8,4 +8,5 @@ num_limits.h
+ sybase_character_sets.h
+ tds_willconvert.h
+ encodings.h
++types.h
+ 
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index be636b9..eba44e8 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.64 2008/07/30 08:02:55 freddy77 Exp $
++# $Id: Makefile.am,v 1.65 2008/09/17 12:16:07 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -13,8 +13,8 @@ libtds_la_SOURCES=	mem.c token.c util.c login.c read.c \
+ libtds_la_LDFLAGS=
+ libtds_la_LIBADD=
+ 
+-noinst_HEADERS		= tds_willconvert.h encodings.h num_limits.h
+-EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h
++noinst_HEADERS		= tds_willconvert.h encodings.h num_limits.h types.h
++EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h types.h
+ 
+ if HAVE_DOXYGEN
+ doxyfile: $(srcdir)/tds.dox
+@@ -52,4 +52,8 @@ encodings.h: encodings.pl alternative_character_sets.h Makefile
+ num_limits.h: num_limits.pl Makefile
+ 	perl $(srcdir)/num_limits.pl > $@.tmp
+ 	mv $@.tmp $@
++
++types.h: types.pl Makefile ../../misc/types.txt
++	perl $(srcdir)/types.pl < $(srcdir)/../../misc/types.txt > $@.tmp
++	mv $@.tmp $@
+ endif
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 606f3fc..89b4e32 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.183 2008/06/12 01:00:48 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.184 2008/09/17 12:16:08 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -142,64 +142,6 @@ static const char *tds_prtype(int token);
+ const char tds_hex_digits[16] = "0123456789abcdef";
+ 
+ /**
+- * Return type suitable for conversions (convert all nullable types to 
+- * fixed type)
+- * @param srctype type to convert
+- * @param colsize size of type
+- * @result type for conversion
+- */
+-int
+-tds_get_conversion_type(int srctype, int colsize)
+-{
+-	switch (srctype) {
+-	case SYBINTN:
+-		switch (colsize) {
+-		case 8:
+-			return SYBINT8;
+-		case 4:
+-			return SYBINT4;
+-		case 2:
+-			return SYBINT2;
+-		case 1:
+-			return SYBINT1;
+-		}
+-		break;
+-	case SYBFLTN:
+-		switch (colsize) {
+-		case 8:
+-			return SYBFLT8;
+-		case 4:
+-			return SYBREAL;
+-		}
+-		break;
+-	case SYBDATETIMN:
+-		switch (colsize) {
+-		case 8:
+-			return SYBDATETIME;
+-		case 4:
+-			return SYBDATETIME4;
+-		}
+-		break;
+-	case SYBMONEYN:
+-		switch (colsize) {
+-		case 8:
+-			return SYBMONEY;
+-		case 4:
+-			return SYBMONEY4;
+-		}
+-		break;
+-		/*
+-		 * altough tds_convert handle SYBBITN other routine use this
+-		 * function to retrieve not variant type
+-		 */
+-	case SYBBITN:
+-		return SYBBIT;
+-		break;
+-	}
+-	return srctype;
+-}
+-
+-/**
+  * Copy a terminated string to result and return len or TDS_CONVERT_NOMEM
+  */
+ static TDS_INT
+diff --git a/src/tds/data.c b/src/tds/data.c
+index 96ab068..3c81ff5 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,7 +35,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.18 2007/06/21 07:21:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: data.c,v 1.19 2008/09/17 12:16:08 freddy77 Exp $");
+ 
+ #if !ENABLE_EXTRA_CHECKS
+ static int tds_get_cardinal_type(int datatype);
+@@ -163,61 +163,4 @@ tds_get_cardinal_type(int datatype)
+ 	return datatype;
+ }
+ 
+-/**
+- * tds_get_varint_size() returns the size of a variable length integer
+- * returned in a TDS 7.0 result string
+- */
+-#if !ENABLE_EXTRA_CHECKS
+-static
+-#endif
+-int
+-tds_get_varint_size(TDSSOCKET * tds, int datatype)
+-{
+-	switch (datatype) {
+-	case SYBTEXT:
+-	case SYBNTEXT:
+-	case SYBIMAGE:
+-		return 4;
+-	case SYBVOID:
+-	case SYBINT1:
+-	case SYBBIT:
+-	case SYBINT2:
+-	case SYBINT4:
+-	case SYBINT8:
+-	case SYBDATETIME4:
+-	case SYBREAL:
+-	case SYBMONEY:
+-	case SYBDATETIME:
+-	case SYBFLT8:
+-	case SYBMONEY4:
+-	case SYBSINT1:
+-	case SYBUINT2:
+-	case SYBUINT4:
+-	case SYBUINT8:
+-		return 0;
+-	}
+-
+-	if (IS_TDS7_PLUS(tds)) {
+-		switch (datatype) {
+-		/* TODO support this strange type */
+-		case SYBVARIANT:
+-			return 4;
+-		case XSYBCHAR:
+-		case XSYBNCHAR:
+-		case XSYBNVARCHAR:
+-		case XSYBVARCHAR:
+-		case XSYBBINARY:
+-		case XSYBVARBINARY:
+-			return 2;
+-		}
+-	} else if (IS_TDS50(tds)) {
+-		switch (datatype) {
+-		case SYBLONGBINARY:
+-		case SYBLONGCHAR:
+-			return 5;
+-		case SYB5INT8:
+-			return 0;
+-		}
+-	}
+-	return 1;
+-}
++#include "types.h"
+diff --git a/src/tds/read.c b/src/tds/read.c
+index 4abfe7b..76a8b48 100644
+--- a/src/tds/read.c
++++ b/src/tds/read.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: read.c,v 1.106 2007/12/27 13:45:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: read.c,v 1.107 2008/09/17 12:16:08 freddy77 Exp $");
+ 
+ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ 			    size_t * wire_size, char **outbuf, size_t * outbytesleft);
+@@ -315,63 +315,6 @@ tds_get_n(TDSSOCKET * tds, void *dest, int need)
+ 	return dest;
+ }
+ 
+-/**
+- * Return the number of bytes needed by specified type.
+- */
+-int
+-tds_get_size_by_type(int servertype)
+-{
+-	switch (servertype) {
+-	case SYBINT1:
+-		return 1;
+-		break;
+-	case SYBINT2:
+-		return 2;
+-		break;
+-	case SYBINT4:
+-		return 4;
+-		break;
+-	case SYB5INT8:
+-	case SYBINT8:
+-		return 8;
+-		break;
+-	case SYBREAL:
+-		return 4;
+-		break;
+-	case SYBFLT8:
+-		return 8;
+-		break;
+-	case SYBDATETIME:
+-		return 8;
+-		break;
+-	case SYBDATETIME4:
+-		return 4;
+-		break;
+-	case SYBBIT:
+-		return 1;
+-		break;
+-	case SYBBITN:
+-		return 1;
+-		break;
+-	case SYBMONEY:
+-		return 8;
+-		break;
+-	case SYBMONEY4:
+-		return 4;
+-		break;
+-	case SYBUNIQUE:
+-		return 16;
+-		break;
+-	/* this strange type is used just for null placeholder in rpc */
+-	case SYBVOID:
+-		return 0;
+-		break;
+-	default:
+-		return -1;
+-		break;
+-	}
+-}
+-
+ /*
+  * For UTF-8 and similar, tds_iconv() may encounter a partial sequence when the chunk boundary
+  * is not aligned with the character boundary.  In that event, it will return an error, and
+diff --git a/src/tds/types.pl b/src/tds/types.pl
+new file mode 100755
+index 0000000..a4cd760
+--- /dev/null
++++ b/src/tds/types.pl
+@@ -0,0 +1,151 @@
++#!/usr/bin/perl
++
++use strict;
++
++sub readLine()
++{
++	my $line;
++	while ($line = <>) {
++		chomp $line;
++		# remove comments
++		$line =~ s/#.*//;
++		# removed unused spaces at the end
++		$line =~ s/\s+$//;
++		# if not empty return it
++		return $line if $line;
++	}
++	return $line;
++}
++
++# read header
++my $hdr = lc(readLine());
++$hdr =~ s/ /_/g;
++my @fields = split("\t", $hdr);
++
++# read all files
++my %types;
++my $line;
++while ($line = readLine()) {
++	my %type;
++	@type{@fields} = split("\t", $line);
++	$types{$type{'name'}} = \%type;
++}
++
++my $id = '$Id: types.pl,v 1.1 2008/09/17 12:16:09 freddy77 Exp $';
++$id =~ s/\$Id/CVS Id/;
++$id =~ s/\$\s*$//;
++print qq|/*
++ * This file produced from $0
++ * $id
++ */
++
++|;
++
++sub unique($)
++{
++	return keys %{{ map { $_ => 1 } @_ }};
++}
++
++sub switchValues()
++{
++	my ($indent, $column, @list) = @_;
++	foreach my $value (sort { $a <=> $b } &unique(map { $_->{$column} } @list)) {
++		print $indent.qq|case $_:\n| for (sort map { $_->{'name'} } grep { $_->{$column} eq $value } @list);
++		print $indent.qq|	return $value;\n|;
++	}
++}
++
++# generate tds_get_size_by_type function
++print q|/**
++ * Return the number of bytes needed by specified type.
++ */
++int
++tds_get_size_by_type(int servertype)
++{
++	switch (servertype) {
++|;
++my @list = grep { $_->{'size'} != -1 } values %types;
++&switchValues("\t", 'size', @list);
++print q|	default:
++		return -1;
++	}
++}
++
++|;
++
++# generate tds_get_varint_size
++print q|/**
++ * tds_get_varint_size() returns the size of a variable length integer
++ * returned in a TDS 7.0 result string
++ */
++#if !ENABLE_EXTRA_CHECKS
++static
++#endif
++int
++tds_get_varint_size(TDSSOCKET * tds, int datatype)
++{
++	switch (datatype) {
++|;
++@list = grep { $_->{'varint'} != 1 && $_->{'varint'} ne '??' && uc($_->{'vendor'}) ne 'MS' && uc($_->{'vendor'}) ne 'SYB' } values %types;
++&switchValues("\t", 'varint', @list);
++print q|	}
++
++	if (IS_TDS7_PLUS(tds)) {
++		switch (datatype) {
++|;
++@list = grep { $_->{'varint'} != 1 && $_->{'varint'} ne '??' && uc($_->{'vendor'}) eq 'MS' } values %types;
++&switchValues("\t\t", 'varint', @list);
++print q|		}
++	} else if (IS_TDS50(tds)) {
++		switch (datatype) {
++|;
++@list = grep { $_->{'varint'} != 1 && $_->{'varint'} ne '??' && uc($_->{'vendor'}) eq 'SYB' } values %types;
++&switchValues("\t\t", 'varint', @list);
++print q|		}
++	}
++	return 1;
++}
++
++|;
++
++#generate
++
++print q|/**
++ * Return type suitable for conversions (convert all nullable types to fixed type)
++ * @param srctype type to convert
++ * @param colsize size of type
++ * @result type for conversion
++ */
++int
++tds_get_conversion_type(int srctype, int colsize)
++{
++	switch (srctype) {
++|;
++# extract all types that have nullable representation
++# exclude SYB5INT8 cause it collide with SYBINT8
++@list = grep { $_->{'nullable_type'} ne "0" && $_->{name} ne 'SYB5INT8' } values %types;
++foreach my $type (@list)
++{
++	die("$type->{name} should be not nullable") if $type->{nullable};
++	die("$type->{name} has invalid nullable type") if !exists($types{$type->{nullable_type}});
++}
++foreach my $type (sort &unique(map { $_->{nullable_type} } @list)) {
++	my @list2 = grep { $_->{nullable_type} eq $type } @list;
++	print qq|	case $type:\n|;
++	if ($#list2 == 0) {
++		print qq|		return $list2[0]->{name};\n|;
++	} else {
++		print qq|		switch (colsize) {\n|;
++		foreach my $item (sort { $b->{size} <=> $a->{size} } @list2) {
++			print qq|		case $item->{size}:
++			return $item->{name};\n|;
++		}
++		print qq|		}
++		break;\n|;
++	}
++}
++print q|	}
++	return srctype;
++}
++
++|;
+
+commit 296451546669fc9d8529b3f2cb95a223bd9521d5
+Author: freddy77 <freddy77>
+Date:   Wed Sep 17 21:26:21 2008 +0000
+
+    typo error
+
+diff --git a/ChangeLog b/ChangeLog
+index 97c2027..ff1aac1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Sep 17 13:25:51 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: typo error
++
+ Wed Sep 17 14:14:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/.cvsignore src/tds/Makefile.am src/tds/convert.c:
+ 	* src/tds/data.c src/tds/read.c src/tds/types.pl(added):
+@@ -658,4 +661,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2610 2008/09/17 12:16:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2611 2008/09/17 21:26:21 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 5778351..408faf0 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.496 2008/09/14 07:45:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.497 2008/09/17 21:26:23 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -5889,7 +5889,7 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 
+ 	/*
+ 	 * Sybase return first nvarchar for char... and without length !!!
+-	 * Some program use first entry so we discard all entry bfore varchar
++	 * Some program use first entry so we discard all entry before varchar
+ 	 */
+ 	n = 0;
+ 	while (tds->current_results) {
+
+commit 2738db1c896a6d60c50c433cf43e6380bdc6915f
+Author: freddy77 <freddy77>
+Date:   Thu Sep 18 08:17:59 2008 +0000
+
+    reduce #if use
+
+diff --git a/ChangeLog b/ChangeLog
+index ff1aac1..c408cb8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Sep 18 10:17:49 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: reduce use of #if
++
+ Wed Sep 17 13:25:51 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: typo error
+ 
+@@ -661,4 +664,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2611 2008/09/17 21:26:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2612 2008/09/18 08:17:59 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index bb009f3..c678d16 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,13 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.354 2008/09/14 07:45:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.355 2008/09/18 08:18:02 freddy77 Exp $");
++
++#ifdef ENABLE_DEVELOPING
++# define USE_ICONV tds->use_iconv
++#else
++# define USE_ICONV 1
++#endif
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+@@ -2099,14 +2105,10 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		 * Here we allocate memory, if need be.  
+ 		 */
+ 		/* TODO this can lead to a big waste of memory */
+-#ifdef ENABLE_DEVELOPING
+-		if (tds->use_iconv)
++		if (USE_ICONV)
+ 			new_blob_size = determine_adjusted_size(curcol->char_conv, colsize);
+ 		else
+ 			new_blob_size = colsize;
+-#else
+-		new_blob_size = determine_adjusted_size(curcol->char_conv, colsize);
+-#endif
+ 		if (new_blob_size == 0) {
+ 			curcol->column_cur_size = 0;
+ 			if (blob->textvalue)
+@@ -2130,11 +2132,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		curcol->column_cur_size = new_blob_size;
+ 		
+ 		/* read the data */
+-#ifdef ENABLE_DEVELOPING
+-		if (tds->use_iconv && curcol->char_conv) {
+-#else
+-		if (curcol->char_conv) {
+-#endif
++		if (USE_ICONV && curcol->char_conv) {
+ 			if (tds_get_char_data(tds, (char *) blob, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
+ 		} else {
+@@ -2144,11 +2142,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	} else {		/* non-numeric and non-blob */
+ 		curcol->column_cur_size = colsize;
+ 
+-#ifdef ENABLE_DEVELOPING
+-		if (tds->use_iconv && curcol->char_conv) {
+-#else
+-		if (curcol->char_conv) {
+-#endif
++		if (USE_ICONV && curcol->char_conv) {
+ 			if (tds_get_char_data(tds, (char *) dest, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
+ 		} else {	
+@@ -3380,11 +3374,7 @@ adjust_character_column_size(const TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	if (!curcol->char_conv && IS_TDS7_PLUS(tds) && is_ascii_type(curcol->on_server.column_type))
+ 		curcol->char_conv = tds->char_convs[client2server_chardata];
+ 
+-#ifdef ENABLE_DEVELOPING
+-	if (!tds->use_iconv || !curcol->char_conv)
+-#else
+-	if (!curcol->char_conv)
+-#endif
++	if (!USE_ICONV || !curcol->char_conv)
+ 		return;
+ 
+ 	curcol->on_server.column_size = curcol->column_size;
+
+commit 844f6bc8ca9d1d3dabd1efe8ef495a29825ad5b9
+Author: freddy77 <freddy77>
+Date:   Thu Sep 18 08:51:19 2008 +0000
+
+    more error set in odbc_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index c408cb8..2c30c24 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Sep 18 10:50:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c:
++	- more error set in odbc_tds2sql
++
+ Thu Sep 18 10:17:49 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: reduce use of #if
+ 
+@@ -664,4 +669,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2612 2008/09/18 08:17:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2613 2008/09/18 08:51:19 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index c0a3597..28f100c 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.109 2008/09/11 15:09:49 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.110 2008/09/18 08:51:21 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -439,7 +439,7 @@ int odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection);
+ /*
+  * convert_tds2sql.c
+  */
+-TDS_INT odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
++TDS_INT odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
+ 
+ /*
+  * descriptor.c
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 50e8afb..2c4e218 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -39,14 +39,15 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.52 2008/09/11 15:09:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.53 2008/09/18 08:51:21 freddy77 Exp $");
+ 
+ TDS_INT
+-odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
++odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+ 	     const struct _drecord *drec_ixd)
+ {
+ 	TDS_INT nDestSybType;
+ 	TDS_INT nRetVal = TDS_FAIL;
++	TDSCONTEXT *context = stmt->dbc->env->tds_ctx;
+ 
+ 	CONV_RESULT ores;
+ 
+@@ -64,8 +65,10 @@ odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen,
+ 	assert(desttype != SQL_C_DEFAULT);
+ 
+ 	nDestSybType = odbc_c_to_server_type(desttype);
+-	if (nDestSybType == TDS_FAIL)
++	if (nDestSybType == TDS_FAIL) {
++		odbc_errs_add(&stmt->errs, "HY003", NULL);
+ 		return TDS_CONVERT_NOAVAIL;
++	}
+ 
+ 	/* special case for binary type */
+ 	if (desttype == SQL_C_BINARY) {
+@@ -75,8 +78,10 @@ odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen,
+ 			desttype = SQL_C_NUMERIC;
+ 			nDestSybType = SYBNUMERIC;
+ 			/* prevent buffer overflow */
+-			if (destlen < sizeof(SQL_NUMERIC_STRUCT))
++			if (destlen < sizeof(SQL_NUMERIC_STRUCT)) {
++				odbc_errs_add(&stmt->errs, "07006", NULL);
+ 				return TDS_CONVERT_FAIL;
++			}
+ 			ores.n.precision = ((TDS_NUMERIC *) src)->precision;
+ 			ores.n.scale = ((TDS_NUMERIC *) src)->scale;
+ 		} else {
+@@ -88,8 +93,10 @@ odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen,
+ 				memcpy(dest, src, cplen);
+ 			} else {
+ 				/* if destlen == 0 we return only length */
+-				if (destlen != 0)
+-					ret = TDS_CONVERT_FAIL;
++				if (destlen != 0) {
++					odbc_errs_add(&stmt->errs, "07006", NULL);
++					return TDS_CONVERT_FAIL;
++				}
+ 			}
+ 			return ret;
+ 		}
+@@ -122,8 +129,10 @@ odbc_tds2sql(TDSCONTEXT * context, int srctype, TDS_CHAR * src, TDS_UINT srclen,
+ 	} else {
+ 		nRetVal = tds_convert(context, srctype, src, srclen, nDestSybType, &ores);
+ 	}
+-	if (nRetVal < 0)
++	if (nRetVal < 0) {
++		odbc_convert_err_set(&stmt->errs, nRetVal);
+ 		return nRetVal;
++	}
+ 
+ 	switch (desttype) {
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 408faf0..b7e7b85 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.497 2008/09/17 21:26:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.498 2008/09/18 08:51:21 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3667,10 +3667,9 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				} else {
+ 					data_ptr += odbc_get_octet_len(c_type, drec_ard) * curr_row;
+ 				}
+-				len = odbc_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
++				len = odbc_tds2sql(stmt, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+ 				if (len < 0) {
+-					odbc_convert_err_set(&stmt->errs, len);
+ 					row_status = SQL_ROW_ERROR;
+ 					break;
+ 				}
+@@ -4741,12 +4740,9 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 							ODBC_RETURN(stmt, SQL_NO_DATA);
+ 						
+ 						if (cbValueMax > 2) {
+-							len = odbc_tds2sql(context, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
+-							if (len < 2) {
+-								if (len < 0) 
+-									odbc_convert_err_set(&stmt->errs, len);
++							len = odbc_tds2sql(stmt, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
++							if (len < 2)
+ 								ODBC_RETURN(stmt, SQL_ERROR);
+-							}
+ 							*(TDS_CHAR *) rgbValue = buf[1];
+ 							*((TDS_CHAR *) rgbValue + 1) = 0;
+ 						
+@@ -4800,11 +4796,9 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			srclen = colinfo->column_cur_size;
+ 		}
+ 
+-		*pcbValue = odbc_tds2sql(context, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+-		if (*pcbValue < 0) {
+-			odbc_convert_err_set(&stmt->errs, *pcbValue);
++		*pcbValue = odbc_tds2sql(stmt, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
++		if (*pcbValue < 0)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+-		}
+ 		
+ 		if (extra_bytes) {
+ 			colinfo->column_text_sqlgetdatapos += extra_bytes;
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 2122d0e..f13098b 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.102 2008/09/11 15:09:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.103 2008/09/18 08:51:22 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -113,7 +113,6 @@ void
+ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ {
+ 	TDSSOCKET *tds = stmt->dbc->tds_socket;
+-	TDSCONTEXT *context = stmt->dbc->env->tds_ctx;
+ 
+ 	/* TODO handle different type results (functions) on mssql2k */
+ 	if (stmt->prepared_query_is_func && tds->has_status) {
+@@ -139,7 +138,7 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ 		}
+ #define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))
+ 
+-		len = odbc_tds2sql(context, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
++		len = odbc_tds2sql(stmt, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
+ 				   drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
+ 		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+@@ -156,7 +155,6 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ {
+ 	TDSSOCKET *tds = stmt->dbc->tds_socket;
+ 	TDSPARAMINFO *info = tds->current_results;
+-	TDSCONTEXT *context = stmt->dbc->env->tds_ctx;
+ 
+ 	int i_begin = stmt->prepared_query_is_func ? 1 : 0;
+ 	int i;
+@@ -221,9 +219,8 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 		 * TODO why IPD ?? perhaps SQLBindParameter it's not correct ??
+ 		 * Or tests are wrong ??
+ 		 */
+-		len = odbc_tds2sql(context, tds_get_conversion_type(colinfo->column_type, colinfo->column_size), src, srclen,
++		len = odbc_tds2sql(stmt, tds_get_conversion_type(colinfo->column_type, colinfo->column_size), src, srclen,
+ 				   c_type, (void *) data_ptr, drec_apd->sql_desc_octet_length, drec_ipd);
+-		/* TODO error handling */
+ 		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+ 		if (drec_apd->sql_desc_indicator_ptr)
+
+commit 069f30a5c50577cab362c658c79e0610adb4b911
+Author: freddy77 <freddy77>
+Date:   Fri Sep 19 13:38:05 2008 +0000
+
+    fix compile
+
+diff --git a/ChangeLog b/ChangeLog
+index 2c30c24..5104391 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Sep 19 15:37:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am: fix compile
++
+ Thu Sep 18 10:50:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
+ 	* src/odbc/odbc_util.c:
+@@ -669,4 +672,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2613 2008/09/18 08:51:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2614 2008/09/19 13:38:05 freddy77 Exp $
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index eba44e8..28f8f31 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.65 2008/09/17 12:16:07 freddy77 Exp $
++# $Id: Makefile.am,v 1.66 2008/09/19 13:38:07 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -35,6 +35,8 @@ endif
+ ## We have to build num_limits.h because automake can't infer the
+ ## dependency (on num_limits.pl).  
+ 
++data.c:	types.h
++
+ if HAVE_PERL_SOURCES
+ BUILT_SOURCES = tds_willconvert.h encodings.h num_limits.h
+ 
+
+commit 26e63539b9794c80035f1b713f00ca4f4253db1d
+Author: freddy77 <freddy77>
+Date:   Thu Sep 25 08:06:32 2008 +0000
+
+    rollback changes, MS behavior is wrong
+
+diff --git a/ChangeLog b/ChangeLog
+index 5104391..bbc6462 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Sep 25 10:05:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c:
++	- rollback changes, our version, was correct
++
+ Fri Sep 19 15:37:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/Makefile.am: fix compile
+ 
+@@ -672,4 +676,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2614 2008/09/19 13:38:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2615 2008/09/25 08:06:32 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 6536aaf..b22cece 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.6 2008/07/07 13:17:51 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.7 2008/09/25 08:06:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -76,7 +76,7 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ 	char symbol[3];
+ 
+ 	for (n = 0; n < len; ++n) {
+-		sprintf(symbol, "%2X", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
++		sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
+ 		if (buf[n] != symbol[(start+n) % 2])
+ 			return 0;
+ 	}
+@@ -139,7 +139,6 @@ readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
+ 			break;
+ 		if (len > (SQLLEN) bufsize)
+ 			len = (SQLLEN) bufsize - 1;
+-		len -= len % 2;
+ 		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+ 		
+ 		check =	check_hex(buf, len, 2*987 + total, 25);
+@@ -236,7 +235,7 @@ main(int argc, char **argv)
+ 					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
+ 					
+-					rcode = SQLPutData(m_hstmt, p + NBYTES - 2 * (i&1), NBYTES + 2 * (i&1));
++					rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1));
+ 
+ 					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
+
+commit 82e4d10cb7f00db630789921cc67b1337d3a406f
+Author: freddy77 <freddy77>
+Date:   Thu Oct 2 08:08:00 2008 +0000
+
+    remove wrong comments
+
+diff --git a/ChangeLog b/ChangeLog
+index bbc6462..ae55fa5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Oct 01 10:06:13 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/basename.c src/replacements/gettimeofday.c:
++	- remove wrong comments
++
+ Thu Sep 25 10:05:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c:
+ 	- rollback changes, our version, was correct
+@@ -676,4 +680,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2615 2008/09/25 08:06:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2616 2008/10/02 08:08:00 freddy77 Exp $
+diff --git a/src/replacements/basename.c b/src/replacements/basename.c
+index befda0d..a36088d 100644
+--- a/src/replacements/basename.c
++++ b/src/replacements/basename.c
+@@ -17,19 +17,6 @@
+  * Boston, MA 02111-1307, USA.
+  */
+ 
+-/*
+- * This file implements a very simple iconv.
+- * Its purpose is to allow ASCII clients to communicate with Microsoft servers
+- * that encode their metadata in Unicode (UCS-2).
+- *
+- * The conversion algorithm relies on the fact that UCS-2 shares codepoints
+- * between 0 and 255 with ISO-8859-1.  To create UCS-2, we add a high byte
+- * whose value is zero.  To create ISO-8859-1, we strip the high byte.
+- *
+- * If we receive an input character whose value is greater than 255, we return an
+- * out-of-range error.  The caller (tds_iconv) should emit an error message.
+- */
+-
+ #if HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+@@ -43,7 +30,7 @@
+ 
+ #if ! HAVE_BASENAME
+ 
+-TDS_RCSID(var, "$Id: basename.c,v 1.2 2005/07/15 11:52:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: basename.c,v 1.3 2008/10/02 08:08:00 freddy77 Exp $");
+ 
+ char *tds_basename(char *path)
+ {
+diff --git a/src/replacements/gettimeofday.c b/src/replacements/gettimeofday.c
+index 8af088b..4a06ea9 100644
+--- a/src/replacements/gettimeofday.c
++++ b/src/replacements/gettimeofday.c
+@@ -17,19 +17,6 @@
+  * Boston, MA 02111-1307, USA.
+  */
+ 
+-/*
+- * This file implements a very simple iconv.  
+- * Its purpose is to allow ASCII clients to communicate with Microsoft servers
+- * that encode their metadata in Unicode (UCS-2).  
+- *
+- * The conversion algorithm relies on the fact that UCS-2 shares codepoints
+- * between 0 and 255 with ISO-8859-1.  To create UCS-2, we add a high byte
+- * whose value is zero.  To create ISO-8859-1, we strip the high byte.  
+- *
+- * If we receive an input character whose value is greater than 255, we return an 
+- * out-of-range error.  The caller (tds_iconv) should emit an error message.  
+- */
+-
+ #if HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+@@ -43,7 +30,7 @@
+ #include "tds.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: gettimeofday.c,v 1.3 2007/03/20 15:25:29 freddy77 Exp $");
++TDS_RCSID(var, "$Id: gettimeofday.c,v 1.4 2008/10/02 08:08:00 freddy77 Exp $");
+ /*
+  * Number of micro-seconds between the beginning of the Windows epoch
+  * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
+
+commit f7524078f9a1ef6ddcedb147fb464ec3c4af4391
+Author: freddy77 <freddy77>
+Date:   Mon Oct 6 13:45:15 2008 +0000
+
+    fixed string truncation with charset with shift state
+
+diff --git a/ChangeLog b/ChangeLog
+index ae55fa5..437ee92 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Oct 06 15:43:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
++	* src/tds/iconv.c src/odbc/unittests/utf8_2.c(added):
++	- fixed string truncation with charset with shift state
++
+ Thu Oct 01 10:06:13 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/basename.c src/replacements/gettimeofday.c:
+ 	- remove wrong comments
+@@ -680,4 +685,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2616 2008/10/02 08:08:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2617 2008/10/06 13:45:15 freddy77 Exp $
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index af134ad..fb2e37e 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -72,4 +72,5 @@ test64
+ wchar
+ transaction2
+ utf8
++utf8_2
+ 
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 9afecee..f04a6ab 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.77 2008/08/16 14:48:57 freddy77 Exp $
++# $Id: Makefile.am,v 1.78 2008/10/06 13:45:15 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -22,7 +22,7 @@ TESTS		=	\
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+ 			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT) \
+-			cursor6$(EXEEXT) cursor7$(EXEEXT) utf8$(EXEEXT)
++			cursor6$(EXEEXT) cursor7$(EXEEXT) utf8$(EXEEXT) utf8_2$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -88,6 +88,7 @@ transaction2_SOURCES = transaction2.c common.c common.h
+ cursor6_SOURCES	= cursor6.c common.c common.h
+ cursor7_SOURCES	= cursor7.c common.c common.h
+ utf8_SOURCES	= utf8.c common.c common.h
++utf8_2_SOURCES	= utf8_2.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+new file mode 100755
+index 0000000..e2c3290
+--- /dev/null
++++ b/src/odbc/unittests/utf8_2.c
+@@ -0,0 +1,110 @@
++#include "common.h"
++
++/* test conversion of Hebrew characters (which have shift sequences) */
++static char software_version[] = "$Id: utf8_2.c,v 1.1 2008/10/06 13:45:15 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static void init_connect(void);
++
++static void
++init_connect(void)
++{
++	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
++		printf("Unable to allocate env\n");
++		exit(1);
++	}
++	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
++		printf("Unable to allocate connection\n");
++		SQLFreeEnv(Environment);
++		exit(1);
++	}
++}
++
++static const char * const strings[] = {
++	"\xd7\x9e\xd7\x99\xd7\x93\xd7\xa2",
++	"info",
++	"\xd7\x98\xd7\xa7\xd7\xa1\xd7\x98",
++	"\xd7\x90\xd7\x91\xd7\x9b",
++	NULL
++};
++
++/* same strings in hex */
++static const char * const strings_hex[] = {
++	"0xde05d905d305e205",
++	"0x69006e0066006f00",
++	"0xd805e705e105d805",
++	"0xd005d105db05",
++	NULL
++};
++
++int
++main(int argc, char *argv[])
++{
++	char tmp[128];
++	char out[32];
++	SQLLEN n_len;
++	int res;
++	SQLSMALLINT len;
++	const char * const*p;
++	int n;
++
++	if (read_login_info())
++		exit(1);
++
++	/* connect string using DSN */
++	init_connect();
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
++	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
++	if (!SQL_SUCCEEDED(res)) {
++		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
++		CheckReturn();
++		return 1;
++	}
++	if (!driver_is_freetds()) {
++		Disconnect();
++		printf("Driver is not FreeTDS, exiting\n");
++		return 0;
++	}
++
++	memset(tmp, 0, sizeof(tmp));
++	SQLGetInfo(Connection, SQL_DBMS_VER, tmp, sizeof(tmp), &len);
++	if (!db_is_microsoft() || (strncmp(tmp, "08.00.", 6) != 0 && strncmp(tmp, "09.00.", 6) != 0)) {
++		Disconnect();
++		printf("Test for MSSQL only\n");
++		return 0;
++	}
++
++	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS) {
++		printf("Unable to allocate statement\n");
++		CheckReturn();
++	}
++
++	/* create test table */
++	Command(Statement, "CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
++
++	/* insert with INSERT statements */
++	for (n = 0, p = strings_hex; p[n]; ++n) {
++		sprintf(tmp, "INSERT INTO #tmpHebrew VALUES(%d, CAST(%s AS NVARCHAR(10)))", n+1, p[n]);
++		Command(Statement, tmp);
++	}
++
++	/* test conversions in libTDS */
++	Command(Statement, "SELECT v FROM #tmpHebrew");
++
++	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
++	CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, out, sizeof(out), &n_len));
++	for (n = 0, p = strings; p[n]; ++n) {
++		CHK(SQLFetch, (Statement));
++		if (n_len != strlen(p[n]) || strcmp(p[n], out) != 0) {
++			fprintf(stderr, "Wrong row %s\n", out);
++			Disconnect();
++			return 1;
++		}
++	}
++
++	Disconnect();
++	printf("Done.\n");
++	return 0;
++}
++
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 6f0c4ae..014fd57 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.133 2008/08/13 04:09:32 jklowden Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.134 2008/10/06 13:45:15 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -691,7 +691,7 @@ tds_iconv(TDSSOCKET * tds, const TDSICONV * conv, TDS_ICONV_DIRECTION io,
+ 				errno = 0;
+ 				irreversible = tds_sys_iconv(cd2, (ICONV_CONST char **) &pb, &l, outbuf, outbytesleft);
+ 				if (irreversible != (size_t) - 1) {
+-					if (*inbytesleft)
++					if (inbytesleft && *inbytesleft)
+ 						break;
+ 					goto end_loop;
+ 				}
+@@ -721,7 +721,7 @@ tds_iconv(TDSSOCKET * tds, const TDSICONV * conv, TDS_ICONV_DIRECTION io,
+ 			errno = temp_errno;
+ 			irreversible = temp_irreversible;
+ 			break;
+-		} else if (io == to_client && conv->flags & TDS_ENCODING_SWAPBYTE) {
++		} else if (io == to_client && conv->flags & TDS_ENCODING_SWAPBYTE && inbuf) {
+ 			/* swap bytes if necessary */
+ #if ENABLE_EXTRA_CHECKS
+ 			char tmp[8];
+@@ -745,13 +745,20 @@ tds_iconv(TDSSOCKET * tds, const TDSICONV * conv, TDS_ICONV_DIRECTION io,
+ 		} else {
+ 			irreversible = tds_sys_iconv(cd, (ICONV_CONST char **) inbuf, inbytesleft, outbuf, outbytesleft);
+ 		}
+-		if (irreversible != (size_t) - 1)
++		/* iconv success, return */
++		if (irreversible != (size_t) - 1) {
++			if (inbuf) {
++				inbuf = NULL;
++				inbytesleft = 0;
++				continue;
++			}
+ 			break;
++		}
+ 
+ 		if (errno == EILSEQ)
+ 			eilseq_raised = 1;
+ 
+-		if (errno != EILSEQ || io != to_client)
++		if (errno != EILSEQ || io != to_client || !inbuf)
+ 			break;
+ 		/* 
+ 		 * Invalid input sequence encountered reading from server. 
+
+commit 8961ee5c3bd47d436f07fd9a748cadaef12146e9
+Author: freddy77 <freddy77>
+Date:   Wed Oct 15 14:53:00 2008 +0000
+
+    error message more verbose
+
+diff --git a/ChangeLog b/ChangeLog
+index 437ee92..dd7787d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Oct 15 16:51:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/utf8_2.c: error message more verbose
++
+ Mon Oct 06 15:43:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/.cvsignore src/odbc/unittests/Makefile.am:
+ 	* src/tds/iconv.c src/odbc/unittests/utf8_2.c(added):
+@@ -685,4 +688,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2617 2008/10/06 13:45:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2618 2008/10/15 14:53:00 freddy77 Exp $
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index e2c3290..756445f 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.1 2008/10/06 13:45:15 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.2 2008/10/15 14:53:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -97,7 +97,7 @@ main(int argc, char *argv[])
+ 	for (n = 0, p = strings; p[n]; ++n) {
+ 		CHK(SQLFetch, (Statement));
+ 		if (n_len != strlen(p[n]) || strcmp(p[n], out) != 0) {
+-			fprintf(stderr, "Wrong row %s\n", out);
++			fprintf(stderr, "Wrong row %d %s\n", n, out);
+ 			Disconnect();
+ 			return 1;
+ 		}
+
+commit e85195c9d33ef5e80352ea181b13414c42697811
+Author: freddy77 <freddy77>
+Date:   Thu Oct 16 11:28:06 2008 +0000
+
+    move column_text_sqlgetdatapos logic to odbc_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index dd7787d..610e575 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Oct 16 13:26:27 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c:
++	- move column_text_sqlgetdatapos logic to odbc_tds2sql
++
+ Wed Oct 15 16:51:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/utf8_2.c: error message more verbose
+ 
+@@ -688,4 +693,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2618 2008/10/15 14:53:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2619 2008/10/16 11:28:06 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 28f100c..f6a7f8d 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.110 2008/09/18 08:51:21 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.111 2008/10/16 11:28:07 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -439,7 +439,7 @@ int odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection);
+ /*
+  * convert_tds2sql.c
+  */
+-TDS_INT odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
++TDS_INT odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
+ 
+ /*
+  * descriptor.c
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 2c4e218..a717f88 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -39,10 +39,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.53 2008/09/18 08:51:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.54 2008/10/16 11:28:07 freddy77 Exp $");
+ 
+ TDS_INT
+-odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
++odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+ 	     const struct _drecord *drec_ixd)
+ {
+ 	TDS_INT nDestSybType;
+@@ -59,6 +59,7 @@ odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int
+ 
+ 	int ret = TDS_CONVERT_FAIL;
+ 	int i, cplen;
++	int binary_conversion = 0;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: src is %d dest = %d\n", srctype, desttype);
+ 
+@@ -91,6 +92,8 @@ odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int
+ 				assert(cplen >= 0);
+ 				/* do not NULL terminate binary buffer */
+ 				memcpy(dest, src, cplen);
++				if (curcol)
++					curcol->column_text_sqlgetdatapos += cplen;
+ 			} else {
+ 				/* if destlen == 0 we return only length */
+ 				if (destlen != 0) {
+@@ -110,6 +113,18 @@ odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int
+ 	}
+ 
+ 	if (desttype == SQL_C_CHAR) {
++		switch (srctype) {
++		case SYBLONGBINARY:
++		case SYBBINARY:
++		case SYBVARBINARY:
++		case SYBIMAGE:
++		case XSYBBINARY:
++		case XSYBVARBINARY:
++			binary_conversion = 1;
++			if (destlen && !(destlen % 2))
++				--destlen;
++		}
++
+ 		nDestSybType = TDS_CONVERT_CHAR;
+ 		ores.cc.len = destlen >= 0 ? destlen : 0;
+ 		ores.cc.c = dest;
+@@ -148,6 +163,8 @@ odbc_tds2sql(TDS_STMT * stmt, int srctype, TDS_CHAR * src, TDS_UINT srclen, int
+ 			 * odbc always terminate but do not overwrite 
+ 			 * destination buffer more than needed
+ 			 */
++			if (curcol)
++				curcol->column_text_sqlgetdatapos += binary_conversion ? cplen / 2 : cplen;
+ 			dest[cplen] = 0;
+ 		} else {
+ 			/* if destlen == 0 we return only length */
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index b7e7b85..62a610c 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.498 2008/09/18 08:51:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.499 2008/10/16 11:28:07 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3667,7 +3667,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				} else {
+ 					data_ptr += odbc_get_octet_len(c_type, drec_ard) * curr_row;
+ 				}
+-				len = odbc_tds2sql(stmt, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
++				len = odbc_tds2sql(stmt, colinfo, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+ 				if (len < 0) {
+ 					row_status = SQL_ROW_ERROR;
+@@ -4657,9 +4657,6 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	SQLLEN dummy_cb;
+ 	int nSybType;
+ 
+-	TDS_INT converted_column_cur_size;
+-	int extra_bytes = 0;
+-
+ 	INIT_HSTMT;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetData(%p, %u, %d, %p, %d, %p)\n", 
+@@ -4696,7 +4693,6 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 	colinfo = tds->current_results->columns[icol - 1];
+-	converted_column_cur_size = colinfo->column_cur_size;
+ 
+ 	if (colinfo->column_cur_size < 0) {
+ 		*pcbValue = SQL_NULL_DATA;
+@@ -4715,79 +4711,17 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 
+ 		src = (TDS_CHAR *) colinfo->column_data;
+ 		if (is_variable_type(colinfo->column_type)) {
+-			int nread = 0;
+-			
+ 			/* 2003-8-29 check for an old bug -- freddy77 */
+ 			assert(colinfo->column_text_sqlgetdatapos >= 0);
+ 			if (is_blob_type(colinfo->column_type))
+ 				src = ((TDSBLOB *) src)->textvalue;
+ 
+-			if (fCType == SQL_C_CHAR) {
+-				TDS_CHAR buf[3];
+-				SQLLEN len;
+-
+-				switch (nSybType) {
+-				case SYBLONGBINARY:
+-				case SYBBINARY:
+-				case SYBVARBINARY:
+-				case SYBIMAGE:
+-				case XSYBBINARY:
+-				case XSYBVARBINARY:
+-				case TDS_CONVERT_BINARY:
+-					if (colinfo->column_text_sqlgetdatapos % 2) {
+-						nread = (colinfo->column_text_sqlgetdatapos - 1) / 2;
+-						if (nread >= colinfo->column_cur_size)
+-							ODBC_RETURN(stmt, SQL_NO_DATA);
+-						
+-						if (cbValueMax > 2) {
+-							len = odbc_tds2sql(stmt, nSybType, src + nread, 1, fCType, buf, sizeof(buf), NULL);
+-							if (len < 2)
+-								ODBC_RETURN(stmt, SQL_ERROR);
+-							*(TDS_CHAR *) rgbValue = buf[1];
+-							*((TDS_CHAR *) rgbValue + 1) = 0;
+-						
+-							rgbValue++;
+-							cbValueMax--;
+-						
+-							extra_bytes = 1;
+-							nread++;
+-
+-							if (nread >= colinfo->column_cur_size)
+-								ODBC_RETURN_(stmt);
+-						} else {
+-							if (cbValueMax) 
+-								*(TDS_CHAR *) rgbValue = 0;
+-							odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+-							ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+-						}
+-					} else {
+-						nread = colinfo->column_text_sqlgetdatapos / 2;
+-						
+-						if (colinfo->column_text_sqlgetdatapos > 0
+-						    && nread >= colinfo->column_cur_size)
+-							ODBC_RETURN(stmt, SQL_NO_DATA);
+-					}
+-					
+-					src += nread;
+-					srclen = colinfo->column_cur_size - nread;
+-					converted_column_cur_size *= 2;
+-					break;
+-				default:
+-					if (colinfo->column_text_sqlgetdatapos > 0
+-					&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-						ODBC_RETURN(stmt, SQL_NO_DATA);
+-						
+-					src += colinfo->column_text_sqlgetdatapos;
+-					srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+-				}
+-			} else {
+-				if (colinfo->column_text_sqlgetdatapos > 0
+-				&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-					ODBC_RETURN(stmt, SQL_NO_DATA);
++			if (colinfo->column_text_sqlgetdatapos > 0
++			&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++				ODBC_RETURN(stmt, SQL_NO_DATA);
+ 
+-				src += colinfo->column_text_sqlgetdatapos;
+-				srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+-			}
++			src += colinfo->column_text_sqlgetdatapos;
++			srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+ 		} else {
+ 			if (colinfo->column_text_sqlgetdatapos > 0
+ 			&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+@@ -4796,30 +4730,16 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			srclen = colinfo->column_cur_size;
+ 		}
+ 
+-		*pcbValue = odbc_tds2sql(stmt, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
++		*pcbValue = odbc_tds2sql(stmt, colinfo, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ 		if (*pcbValue < 0)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 		
+-		if (extra_bytes) {
+-			colinfo->column_text_sqlgetdatapos += extra_bytes;
+-			*pcbValue += extra_bytes;
+-		}
+-		
+ 		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+-			/* calculate how many bytes were read */
+-			int remaining = cbValueMax;
+-
+-			/* FIXME test on destination char ??? */
+-			if (stmt->dbc->env->attr.output_nts != SQL_FALSE && fCType == SQL_C_CHAR && remaining > 0)
+-				--remaining;
+-			if (remaining > *pcbValue)
+-				remaining = *pcbValue;
+-			colinfo->column_text_sqlgetdatapos += remaining;
+ 			/* avoid infinite SQL_SUCCESS on empty strings */
+ 			if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ 				++colinfo->column_text_sqlgetdatapos;
+-			
+-			if (colinfo->column_text_sqlgetdatapos < converted_column_cur_size) {	/* not all read ?? */
++
++			if (colinfo->column_text_sqlgetdatapos < colinfo->column_cur_size) {	/* not all read ?? */
+ 				odbc_errs_add(&stmt->errs, "01004", "String data, right truncated");
+ 				ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ 			}
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index f13098b..ef8b8dc 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.103 2008/09/18 08:51:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.104 2008/10/16 11:28:07 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -138,7 +138,7 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ 		}
+ #define LEN(ptr) *((SQLLEN*)(((char*)(ptr)) + len_offset))
+ 
+-		len = odbc_tds2sql(stmt, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
++		len = odbc_tds2sql(stmt, NULL, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
+ 				   drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
+ 		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+@@ -219,7 +219,7 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 		 * TODO why IPD ?? perhaps SQLBindParameter it's not correct ??
+ 		 * Or tests are wrong ??
+ 		 */
+-		len = odbc_tds2sql(stmt, tds_get_conversion_type(colinfo->column_type, colinfo->column_size), src, srclen,
++		len = odbc_tds2sql(stmt, colinfo, tds_get_conversion_type(colinfo->on_server.column_type, colinfo->on_server.column_size), src, srclen,
+ 				   c_type, (void *) data_ptr, drec_apd->sql_desc_octet_length, drec_ipd);
+ 		if (len < 0)
+ 			return /* SQL_ERROR */ ;
+
+commit 3c30704ba012090d5675dc0cbc726c46e793e13e
+Author: freddy77 <freddy77>
+Date:   Thu Oct 16 14:08:43 2008 +0000
+
+    make test works
+
+diff --git a/ChangeLog b/ChangeLog
+index 610e575..8e12606 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Oct 16 16:08:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: make it works
++
+ Thu Oct 16 13:26:27 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
+ 	* src/odbc/odbc_util.c:
+@@ -693,4 +696,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2619 2008/10/16 11:28:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2620 2008/10/16 14:08:43 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index b22cece..dbe0ece 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.7 2008/09/25 08:06:33 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.8 2008/10/16 14:08:44 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -139,6 +139,7 @@ readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
+ 			break;
+ 		if (len > (SQLLEN) bufsize)
+ 			len = (SQLLEN) bufsize - 1;
++		len -= len % 2;
+ 		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+ 		
+ 		check =	check_hex(buf, len, 2*987 + total, 25);
+
+commit 74f4b0eb3d7f48b5e9ad3b47280593a7a43a6e8d
+Author: freddy77 <freddy77>
+Date:   Thu Oct 16 14:09:57 2008 +0000
+
+    small optimization
+
+diff --git a/ChangeLog b/ChangeLog
+index 8e12606..f898a7f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Oct 16 16:09:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/prepare_query.c: small optimization
++
+ Thu Oct 16 16:08:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: make it works
+ 
+@@ -696,4 +699,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2620 2008/10/16 14:08:43 freddy77 Exp $
++$Id: ChangeLog,v 1.2621 2008/10/16 14:09:57 freddy77 Exp $
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index f2f642f..e4264d1 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.72 2008/09/11 15:09:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.73 2008/10/16 14:09:57 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -328,7 +328,6 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		CONV_RESULT ores;
+ 		TDS_DBC * dbc = stmt->dbc;
+ 		void *free_ptr = NULL;
+-		int start = 0;
+ 		SQLPOINTER extradata = NULL;
+ 		SQLLEN extralen = 0;
+ 
+@@ -374,7 +373,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 					extradata = ores.ib;
+ 					extralen = res;
+ 					
+-					start = 1;
++					DataPtr = (SQLPOINTER) (((char*)DataPtr) + 1);
+ 					--len;
+ 				}
+ 				
+@@ -383,7 +382,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 					curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
+ 				}
+ 
+-				res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr+start, len, dest_type, &ores);
++				res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr, len, dest_type, &ores);
+ 				if (res < 0) {
+ 					odbc_convert_err_set(&dbc->errs, res);
+ 					free(extradata);
+
+commit ebdf550bf987a6d9f5be4f5d1eb3d113ab5ce08a
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 08:06:23 2008 +0000
+
+    use #ifdef ENABLE_DEVELOPING for truncation test
+
+diff --git a/ChangeLog b/ChangeLog
+index f898a7f..2f13838 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Oct 17 10:05:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c:
++	- use #ifdef ENABLE_DEVELOPING for truncation test
++
+ Thu Oct 16 16:09:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/prepare_query.c: small optimization
+ 
+@@ -699,4 +703,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2621 2008/10/16 14:09:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2622 2008/10/17 08:06:23 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 4aaa63d..194d321 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.30 2008/09/04 06:43:48 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.31 2008/10/17 08:06:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -294,8 +294,10 @@ AllTests(void)
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
+ 		/* test for invalid stream due to truncation*/
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "01234567890");
++#ifdef ENABLE_DEVELOPING
+ 		check_truncation = 1;
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "012345678901234567890");
++#endif
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
+ 
+
+commit 6f24553621c384c1be98c72dba6f655f807c9ac7
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 08:15:21 2008 +0000
+
+    rollback SQLGetData changes to 1.481
+
+diff --git a/ChangeLog b/ChangeLog
+index 2f13838..93f9f4d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Oct 17 10:13:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: rollback SQLGetData changes to 1.481
++
+ Fri Oct 17 10:05:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c:
+ 	- use #ifdef ENABLE_DEVELOPING for truncation test
+@@ -703,4 +706,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2622 2008/10/17 08:06:23 freddy77 Exp $
++$Id: ChangeLog,v 1.2623 2008/10/17 08:15:21 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 62a610c..2e8bb3b 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.499 2008/10/16 11:28:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.500 2008/10/17 08:15:21 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4695,40 +4695,39 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	colinfo = tds->current_results->columns[icol - 1];
+ 
+ 	if (colinfo->column_cur_size < 0) {
++		/* TODO check what should happen if pcbValue was NULL */
+ 		*pcbValue = SQL_NULL_DATA;
+ 	} else {
+-		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
+-		if (fCType == SQL_C_DEFAULT)
+-			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+-		if (fCType == SQL_ARD_TYPE) {
+-			if (icol > stmt->ard->header.sql_desc_count) {
+-				odbc_errs_add(&stmt->errs, "07009", NULL);
+-				ODBC_RETURN(stmt, SQL_ERROR);
+-			}
+-			fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
+-		}
+-		assert(fCType);
+-
+ 		src = (TDS_CHAR *) colinfo->column_data;
+ 		if (is_variable_type(colinfo->column_type)) {
++			if (colinfo->column_text_sqlgetdatapos > 0
++			    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++				ODBC_RETURN(stmt, SQL_NO_DATA);
++
+ 			/* 2003-8-29 check for an old bug -- freddy77 */
+ 			assert(colinfo->column_text_sqlgetdatapos >= 0);
+ 			if (is_blob_type(colinfo->column_type))
+ 				src = ((TDSBLOB *) src)->textvalue;
+-
+-			if (colinfo->column_text_sqlgetdatapos > 0
+-			&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-				ODBC_RETURN(stmt, SQL_NO_DATA);
+-
+ 			src += colinfo->column_text_sqlgetdatapos;
+ 			srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+ 		} else {
+ 			if (colinfo->column_text_sqlgetdatapos > 0
+-			&&  colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++			    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+ 				ODBC_RETURN(stmt, SQL_NO_DATA);
+ 
+ 			srclen = colinfo->column_cur_size;
+ 		}
++		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++		if (fCType == SQL_C_DEFAULT)
++			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
++		if (fCType == SQL_ARD_TYPE) {
++			if (icol > stmt->ard->header.sql_desc_count) {
++				odbc_errs_add(&stmt->errs, "07009", NULL);
++				ODBC_RETURN(stmt, SQL_ERROR);
++			}
++			fCType = stmt->ard->records[icol - 1].sql_desc_concise_type;
++		}
++		assert(fCType);
+ 
+ 		*pcbValue = odbc_tds2sql(stmt, colinfo, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+ 		if (*pcbValue < 0)
+
+commit 5affbd944b1c09d57519e3402ee7cfe8a141df2f
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 08:30:03 2008 +0000
+
+    allow SQL_NO_TOTAL from odbc_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index 93f9f4d..14c7c29 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Oct 17 10:26:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c:
++	- allow SQL_NO_TOTAL from odbc_tds2sql
++
+ Fri Oct 17 10:13:19 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: rollback SQLGetData changes to 1.481
+ 
+@@ -706,4 +711,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2623 2008/10/17 08:15:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2624 2008/10/17 08:30:03 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index f6a7f8d..7c1df42 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.111 2008/10/16 11:28:07 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.112 2008/10/17 08:30:03 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -439,7 +439,7 @@ int odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection);
+ /*
+  * convert_tds2sql.c
+  */
+-TDS_INT odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
++SQLLEN odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen, const struct _drecord *drec_ixd);
+ 
+ /*
+  * descriptor.c
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index a717f88..1df2cad 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -39,9 +39,9 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.54 2008/10/16 11:28:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.55 2008/10/17 08:30:03 freddy77 Exp $");
+ 
+-TDS_INT
++SQLLEN
+ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+ 	     const struct _drecord *drec_ixd)
+ {
+@@ -57,7 +57,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 	TIMESTAMP_STRUCT *tssp;
+ 	SQL_NUMERIC_STRUCT *num;
+ 
+-	int ret = TDS_CONVERT_FAIL;
++	SQLLEN ret = SQL_NULL_DATA;
+ 	int i, cplen;
+ 	int binary_conversion = 0;
+ 
+@@ -68,7 +68,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 	nDestSybType = odbc_c_to_server_type(desttype);
+ 	if (nDestSybType == TDS_FAIL) {
+ 		odbc_errs_add(&stmt->errs, "HY003", NULL);
+-		return TDS_CONVERT_NOAVAIL;
++		return SQL_NULL_DATA;
+ 	}
+ 
+ 	/* special case for binary type */
+@@ -81,7 +81,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 			/* prevent buffer overflow */
+ 			if (destlen < sizeof(SQL_NUMERIC_STRUCT)) {
+ 				odbc_errs_add(&stmt->errs, "07006", NULL);
+-				return TDS_CONVERT_FAIL;
++				return SQL_NULL_DATA;
+ 			}
+ 			ores.n.precision = ((TDS_NUMERIC *) src)->precision;
+ 			ores.n.scale = ((TDS_NUMERIC *) src)->scale;
+@@ -98,7 +98,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 				/* if destlen == 0 we return only length */
+ 				if (destlen != 0) {
+ 					odbc_errs_add(&stmt->errs, "07006", NULL);
+-					return TDS_CONVERT_FAIL;
++					return SQL_NULL_DATA;
+ 				}
+ 			}
+ 			return ret;
+@@ -146,7 +146,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 	}
+ 	if (nRetVal < 0) {
+ 		odbc_convert_err_set(&stmt->errs, nRetVal);
+-		return nRetVal;
++		return SQL_NULL_DATA;
+ 	}
+ 
+ 	switch (desttype) {
+@@ -169,7 +169,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		} else {
+ 			/* if destlen == 0 we return only length */
+ 			if (destlen != 0)
+-				ret = TDS_CONVERT_FAIL;
++				ret = SQL_NULL_DATA;
+ 		}
+ 		break;
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 2e8bb3b..0b46fd0 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.500 2008/10/17 08:15:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.501 2008/10/17 08:30:03 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3669,7 +3669,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				}
+ 				len = odbc_tds2sql(stmt, colinfo, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+-				if (len < 0) {
++				if (len == SQL_NULL_DATA) {
+ 					row_status = SQL_ROW_ERROR;
+ 					break;
+ 				}
+@@ -4730,7 +4730,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		assert(fCType);
+ 
+ 		*pcbValue = odbc_tds2sql(stmt, colinfo, nSybType, src, srclen, fCType, (TDS_CHAR *) rgbValue, cbValueMax, NULL);
+-		if (*pcbValue < 0)
++		if (*pcbValue == SQL_NULL_DATA)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 		
+ 		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index ef8b8dc..40fb59c 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.104 2008/10/16 11:28:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.105 2008/10/17 08:30:03 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -140,7 +140,7 @@ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+ 
+ 		len = odbc_tds2sql(stmt, NULL, SYBINT4, (TDS_CHAR *) & tds->ret_status, sizeof(TDS_INT),
+ 				   drec->sql_desc_concise_type, (void *) data_ptr, drec->sql_desc_octet_length, NULL);
+-		if (len < 0)
++		if (len == SQL_NULL_DATA)
+ 			return /* SQL_ERROR */ ;
+ 		if (drec->sql_desc_indicator_ptr)
+ 			LEN(drec->sql_desc_indicator_ptr) = 0;
+@@ -221,7 +221,7 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 		 */
+ 		len = odbc_tds2sql(stmt, colinfo, tds_get_conversion_type(colinfo->on_server.column_type, colinfo->on_server.column_size), src, srclen,
+ 				   c_type, (void *) data_ptr, drec_apd->sql_desc_octet_length, drec_ipd);
+-		if (len < 0)
++		if (len == SQL_NULL_DATA)
+ 			return /* SQL_ERROR */ ;
+ 		if (drec_apd->sql_desc_indicator_ptr)
+ 			LEN(drec_apd->sql_desc_indicator_ptr) = 0;
+
+commit 87be0dfefb8aa1e0b5fb83b88577960ee6a68e52
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 08:39:15 2008 +0000
+
+    add tds_iconv_get to allow multiple client charsets
+
+diff --git a/ChangeLog b/ChangeLog
+index 14c7c29..30bfacd 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Oct 17 10:37:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsiconv.h src/tds/iconv.c:
++	- add tds_iconv_get to allow multiple client charsets
++
+ Fri Oct 17 10:26:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
+ 	* src/odbc/odbc_util.c:
+@@ -711,4 +715,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2624 2008/10/17 08:30:03 freddy77 Exp $
++$Id: ChangeLog,v 1.2625 2008/10/17 08:39:15 freddy77 Exp $
+diff --git a/include/tdsiconv.h b/include/tdsiconv.h
+index 49a91d6..3bd08fe 100644
+--- a/include/tdsiconv.h
++++ b/include/tdsiconv.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_iconv_h_
+ #define _tds_iconv_h_
+ 
+-/* $Id: tdsiconv.h,v 1.36 2007/03/12 13:28:50 freddy77 Exp $ */
++/* $Id: tdsiconv.h,v 1.37 2008/10/17 08:39:16 freddy77 Exp $ */
+ 
+ #if HAVE_ICONV
+ #include <iconv.h>
+@@ -166,6 +166,7 @@ size_t tds_iconv(TDSSOCKET * tds, const TDSICONV * char_conv, TDS_ICONV_DIRECTIO
+ 		 const char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft);
+ const char *tds_canonical_charset_name(const char *charset_name);
+ const char *tds_sybase_charset_name(const char *charset_name);
++TDSICONV *tds_iconv_get(TDSSOCKET * tds, const char *client_charset, const char *server_charset);
+ 
+ #ifdef __cplusplus
+ }
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 014fd57..89d1656 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.134 2008/10/06 13:45:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.135 2008/10/17 08:39:16 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -938,14 +938,15 @@ tds_iconv_fread(iconv_t cd, FILE * stream, size_t field_len, size_t term_len, ch
+  * Get a iconv info structure, allocate and initialize if needed
+  */
+ static TDSICONV *
+-tds_iconv_get_info(TDSSOCKET * tds, const char *canonic_charset)
++tds_iconv_get_info(TDSSOCKET * tds, const char *canonic_client_charset, const char *canonic_server_charset)
+ {
+ 	TDSICONV *info;
+ 	int i;
+ 
+ 	/* search a charset from already allocated charsets */
+ 	for (i = tds->char_conv_count; --i >= initial_char_conv_count;)
+-		if (strcmp(canonic_charset, tds->char_convs[i]->server_charset.name) == 0)
++		if (strcmp(canonic_client_charset, tds->char_convs[i]->client_charset.name) == 0
++		    && strcmp(canonic_server_charset, tds->char_convs[i]->server_charset.name) == 0)
+ 			return tds->char_convs[i];
+ 
+ 	/* allocate a new iconv structure */
+@@ -972,10 +973,28 @@ tds_iconv_get_info(TDSSOCKET * tds, const char *canonic_charset)
+ 
+ 	/* init */
+ 	/* TODO test allocation */
+-	tds_iconv_info_init(info, tds->char_convs[client2ucs2]->client_charset.name, canonic_charset);
++	tds_iconv_info_init(info, canonic_client_charset, canonic_server_charset);
+ 	return info;
+ }
+ 
++TDSICONV *
++tds_iconv_get(TDSSOCKET * tds, const char *client_charset, const char *server_charset)
++{
++	int canonic_client_charset_num = tds_canonical_charset(client_charset);
++	int canonic_server_charset_num = tds_canonical_charset(server_charset);
++
++	if (canonic_client_charset_num < 0) {
++		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_get: what is charset \"%s\"?\n", client_charset);
++		return NULL;
++	}
++	if (canonic_server_charset_num < 0) {
++		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_get: what is charset \"%s\"?\n", server_charset);
++		return NULL;
++	}
++
++	return tds_iconv_get_info(tds, canonic_charsets[canonic_client_charset_num].name, canonic_charsets[canonic_server_charset_num].name);
++}
++
+ /* change singlebyte conversions according to server */
+ void
+ tds_srv_charset_changed(TDSSOCKET * tds, const char *charset)
+@@ -1002,7 +1021,7 @@ tds_srv_charset_changed(TDSSOCKET * tds, const char *charset)
+ 		return;
+ 
+ 	/* find and set conversion */
+-	char_conv = tds_iconv_get_info(tds, canonic_charset);
++	char_conv = tds_iconv_get_info(tds, tds->char_convs[client2ucs2]->client_charset.name, canonic_charset);
+ 	if (char_conv)
+ 		tds->char_convs[client2server_chardata] = char_conv;
+ 
+@@ -1460,7 +1479,7 @@ tds_iconv_from_collate(TDSSOCKET * tds, int sql_collate, int lcid)
+ 	if (strcmp(tds->char_convs[client2server_chardata]->server_charset.name, charset) == 0)
+ 		return tds->char_convs[client2server_chardata];
+ 
+-	return tds_iconv_get_info(tds, charset);
++	return tds_iconv_get_info(tds, tds->char_convs[client2ucs2]->client_charset.name, charset);
+ }
+ 
+ /** @} */
+
+commit 1fd60ee5a7012b4a77ef8385bdc99f65b24cdf9e
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 08:56:39 2008 +0000
+
+    enable wide characters from server
+
+diff --git a/ChangeLog b/ChangeLog
+index 30bfacd..1bb4cd8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Oct 17 10:55:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/odbc.c:
++	- enable wide characters from server
++
+ Fri Oct 17 10:37:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsiconv.h src/tds/iconv.c:
+ 	- add tds_iconv_get to allow multiple client charsets
+@@ -715,4 +719,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2625 2008/10/17 08:39:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2626 2008/10/17 08:56:39 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 1df2cad..1dd8bc3 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -34,12 +34,73 @@
+ 
+ #include "tdsodbc.h"
+ #include "tdsconvert.h"
++#include "tdsiconv.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.55 2008/10/17 08:30:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.56 2008/10/17 08:56:39 freddy77 Exp $");
++
++#if SIZEOF_SQLWCHAR == 2
++# if WORDS_BIGENDIAN
++#  define ODBC_WIDE_NAME "UCS-2BE"
++# else
++#  define ODBC_WIDE_NAME "UCS-2LE"
++# endif
++#elif SIZEOF_SQLWCHAR == 4
++# if WORDS_BIGENDIAN
++#  define ODBC_WIDE_NAME "UCS-4BE"
++# else
++#  define ODBC_WIDE_NAME "UCS-4LE"
++# endif
++#else
++#error SIZEOF_SQLWCHAR not supported !!
++#endif
++
++static SQLLEN
++odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen)
++{
++	const char *ib;
++	char *ob;
++	size_t il, ol, err, char_size;
++
++	TDSSOCKET *tds = stmt->dbc->tds_socket;
++
++	const TDSICONV *conv = curcol->char_conv;
++	if (!conv)
++		conv = tds->char_convs[client2server_chardata];
++	if (desttype == SQL_C_WCHAR) {
++		/* SQL_C_WCHAR, convert to wide encode */
++		conv = tds_iconv_get(tds, ODBC_WIDE_NAME, conv->server_charset.name);
++	}
++
++	ib = src;
++	il = srclen;
++	ob = dest;
++	ol = 0;
++	char_size = desttype == SQL_C_CHAR ? 1 : SIZEOF_SQLWCHAR;
++	if (destlen >= char_size) {
++		ol = destlen - char_size;
++		memset(&conv->suppress, 0, sizeof(conv->suppress));
++		err = tds_iconv(tds, conv, to_client, &ib, &il, &ob, &ol);
++		ol = ob - dest;
++		if (curcol)
++			curcol->column_text_sqlgetdatapos += ib - src;
++		/* terminate string */
++		memset(ob, 0, char_size);
++	}
++
++	/* returned size have to take into account buffer left unconverted */
++	if (il == 0 || (conv->client_charset.min_bytes_per_char == conv->client_charset.max_bytes_per_char
++	    && conv->server_charset.min_bytes_per_char == conv->server_charset.max_bytes_per_char)) {
++		ol += il * conv->client_charset.min_bytes_per_char / conv->server_charset.min_bytes_per_char;
++	} else {
++		/* TODO convert and discard ?? or return proper SQL_NO_TOTAL values ?? */
++		return SQL_NO_TOTAL;
++	}
++	return ol;
++}
+ 
+ SQLLEN
+ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+@@ -112,6 +173,20 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		ores.n.scale = 0;
+ 	}
+ 
++	if (is_char_type(srctype)) {
++		if (desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR)
++			return odbc_convert_char(stmt, curcol, src, srclen, desttype, dest, destlen);
++		if (is_unicode_type(srctype)) {
++			/*
++			 * TODO convert to single and then process normally.
++			 * Here we processed SQL_C_BINARY and SQL_C_*CHAR so only fixed types are left
++			 */
++		}
++	}
++
++	/*
++	 * TODO support SQL_C_WCHAR converting when needed
++	 */
+ 	if (desttype == SQL_C_CHAR) {
+ 		switch (srctype) {
+ 		case SYBLONGBINARY:
+@@ -163,6 +238,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 			 * odbc always terminate but do not overwrite 
+ 			 * destination buffer more than needed
+ 			 */
++			/* TODO check for source !!! */
+ 			if (curcol)
+ 				curcol->column_text_sqlgetdatapos += binary_conversion ? cplen / 2 : cplen;
+ 			dest[cplen] = 0;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0b46fd0..1c9cfee 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.501 2008/10/17 08:30:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.502 2008/10/17 08:56:39 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -371,9 +371,7 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+-#ifdef ENABLE_DEVELOPING
+ 	dbc->tds_socket->use_iconv = 0;
+-#endif
+ 	tds_set_parent(dbc->tds_socket, (void *) dbc);
+ 
+ 	/* Set up our environment change hook */
+@@ -3667,7 +3665,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				} else {
+ 					data_ptr += odbc_get_octet_len(c_type, drec_ard) * curr_row;
+ 				}
+-				len = odbc_tds2sql(stmt, colinfo, tds_get_conversion_type(colinfo->column_type, colinfo->column_size),
++				len = odbc_tds2sql(stmt, colinfo, tds_get_conversion_type(colinfo->on_server.column_type, colinfo->on_server.column_size),
+ 						      src, srclen, c_type, data_ptr, drec_ard->sql_desc_octet_length, drec_ard);
+ 				if (len == SQL_NULL_DATA) {
+ 					row_status = SQL_ROW_ERROR;
+@@ -4717,7 +4715,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 
+ 			srclen = colinfo->column_cur_size;
+ 		}
+-		nSybType = tds_get_conversion_type(colinfo->column_type, colinfo->column_size);
++		nSybType = tds_get_conversion_type(colinfo->on_server.column_type, colinfo->on_server.column_size);
+ 		if (fCType == SQL_C_DEFAULT)
+ 			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+ 		if (fCType == SQL_ARD_TYPE) {
+
+commit 116bd8c60c44897c833b71c23f0c039dab0801b7
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 09:38:10 2008 +0000
+
+    make it compile without --enable-developing
+
+diff --git a/ChangeLog b/ChangeLog
+index 1bb4cd8..a3f9fc3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Oct 17 11:36:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/mem.c src/tds/token.c:
++	- make it compile without --enable-developing
++
+ Fri Oct 17 10:55:56 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/odbc/odbc.c:
+ 	- enable wide characters from server
+@@ -719,4 +723,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2626 2008/10/17 08:56:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2627 2008/10/17 09:38:10 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 38dc14f..8e3b812 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.295 2008/09/14 07:45:24 freddy77 Exp $ */
++/* $Id: tds.h,v 1.296 2008/10/17 09:38:10 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1291,9 +1291,7 @@ struct tds_socket
+ 	unsigned char option_flag2;
+ 	unsigned int broken_dates:1;
+ 	unsigned int emul_little_endian:1;
+-#ifdef ENABLE_DEVELOPING
+ 	unsigned int use_iconv:1;
+-#endif
+ 
+ 	unsigned char *in_buf;		/**< input buffer */
+ 	unsigned char *out_buf;		/**< output buffer */
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index e90e919..2059a66 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.179 2008/09/14 07:45:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.180 2008/10/17 09:38:10 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -966,9 +966,7 @@ tds_alloc_socket(TDSCONTEXT * context, int bufsize)
+ 	tds_socket->option_flag2 = 0x03;
+ 	tds_socket->env.block_size = bufsize;
+ 
+-#ifdef ENABLE_DEVELOPING
+ 	tds_socket->use_iconv = 1;
+-#endif
+ 	if (tds_iconv_alloc(tds_socket))
+ 		goto Cleanup;
+ 
+diff --git a/src/tds/token.c b/src/tds/token.c
+index c678d16..1885ca6 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,13 +42,9 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.355 2008/09/18 08:18:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.356 2008/10/17 09:38:10 freddy77 Exp $");
+ 
+-#ifdef ENABLE_DEVELOPING
+-# define USE_ICONV tds->use_iconv
+-#else
+-# define USE_ICONV 1
+-#endif
++#define USE_ICONV tds->use_iconv
+ 
+ static int tds_process_msg(TDSSOCKET * tds, int marker);
+ static int tds_process_compute_result(TDSSOCKET * tds);
+
+commit f94fb2a13b496e20ebb9ddeaca63eb26695bf7fe
+Author: freddy77 <freddy77>
+Date:   Fri Oct 17 12:21:09 2008 +0000
+
+    reuse CHK macro
+
+diff --git a/ChangeLog b/ChangeLog
+index a3f9fc3..39c027b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Oct 17 14:20:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c src/odbc/unittests/cancel.c:
++	* src/odbc/unittests/hidden.c:
++	- reuse CHK macro
++
+ Fri Oct 17 11:36:45 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/mem.c src/tds/token.c:
+ 	- make it compile without --enable-developing
+@@ -723,4 +728,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2627 2008/10/17 09:38:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2628 2008/10/17 12:21:09 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index dbe0ece..eccf5d4 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.8 2008/10/16 14:08:44 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.9 2008/10/17 12:21:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -183,26 +183,15 @@ main(int argc, char **argv)
+ 	for (i = 0; i < cnt; i++) {
+ 
+ 		m_hstmt = NULL;
+-		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
++		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &m_hstmt));
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
++		CHK(SQLPrepare, (m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS));
+ 
+-		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 1");
+-
+-		SQLBindParameter(m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 2");
+-
+-		SQLBindParameter(m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 3");
+-
+-		SQLBindParameter(m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 4");
+-
+-		SQLBindParameter(m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 5");
++		CHK(SQLBindParameter, (m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0));
++		CHK(SQLBindParameter, (m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1));
++		CHK(SQLBindParameter, (m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2));
++		CHK(SQLBindParameter, (m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3));
++		CHK(SQLBindParameter, (m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0));
+ 
+ 		key = i;
+ 		vind0 = 0;
+@@ -227,30 +216,25 @@ main(int argc, char **argv)
+ 			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
+ 			printf(">> SQLParamData: ptr = %p  rcode = %d\n", (void *) p, rcode);
+ 			if (rcode == SQL_NEED_DATA) {
+-				SQLRETURN rcode;
+ 				if (p == buf3) {
+ 					fill_hex(buf3, NBYTES, 987, 25);
+ 					
+-					rcode = SQLPutData(m_hstmt, p, NBYTES - (i&1));
++					CHK(SQLPutData, (m_hstmt, p, NBYTES - (i&1)));
+ 
+-					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
+ 					
+-					rcode = SQLPutData(m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1));
++					CHK(SQLPutData, (m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1)));
+ 
+-					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
+ 				} else {
+-					rcode = SQLPutData(m_hstmt, p, NBYTES);
++					CHK(SQLPutData, (m_hstmt, p, NBYTES));
+ 
+-					CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPutData StmtH");
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
+ 				}
+ 			}
+ 		}
+ 
+-		rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFreeHandle StmtH");
++		CHK(SQLFreeHandle, (SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt));
+ 
+ 	}
+ 
+@@ -259,41 +243,30 @@ main(int argc, char **argv)
+ 	for (i = 0; i < cnt; i++) {
+ 
+ 		m_hstmt = NULL;
+-		rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH");
++		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &m_hstmt));
+ 
+ 		if (db_is_microsoft()) {
+-			rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-			rcode = SQLSetStmtAttr(m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++			CHK(SQLSetStmtAttr, (m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER));
++			CHK(SQLSetStmtAttr, (m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER));
+ 		}
+ 
+-		rcode = SQLPrepare(m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLPrepare");
++		CHK(SQLPrepare, (m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS));
+ 
+-		SQLBindParameter(m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindParameter 1");
++		CHK(SQLBindParameter, (m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0));
+ 
+-		SQLBindCol(m_hstmt, 1, SQL_C_BINARY, NULL, 0, &vind1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 2");
+-		SQLBindCol(m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 3");
+-		SQLBindCol(m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 4");
+-		SQLBindCol(m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLBindCol 1");
++		CHK(SQLBindCol, (m_hstmt, 1, SQL_C_BINARY, NULL, 0, &vind1));
++		CHK(SQLBindCol, (m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2));
++		CHK(SQLBindCol, (m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3));
++		CHK(SQLBindCol, (m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0));
+ 
+ 		vind0 = 0;
+ 		vind1 = SQL_DATA_AT_EXEC;
+ 		vind2 = SQL_DATA_AT_EXEC;
+ 
+-		rcode = SQLExecute(m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLExecute StmtH");
++		CHK(SQLExecute, (m_hstmt));
+ 
+-		rcode = SQLFetchScroll(m_hstmt, SQL_FETCH_NEXT, 0);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFetchScroll StmtH");
+-		printf(">> fetch... %d  rcode = %d\n", i, rcode);
++		CHK(SQLFetchScroll, (m_hstmt, SQL_FETCH_NEXT, 0));
++		printf(">> fetch... %d\n", i);
+ 
+ 		rcode = readBlob(m_hstmt, 1);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
+@@ -302,11 +275,8 @@ main(int argc, char **argv)
+ 		rcode = readBlobAsChar(m_hstmt, 3, i);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR");
+ 
+-		rcode = SQLCloseCursor(m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLCloseCursor StmtH");
+-
+-		rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFreeHandle StmtH");
++		CHK(SQLCloseCursor, (m_hstmt));
++		CHK(SQLFreeHandle, (SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt));
+ 	}
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index a43db5b..3fa879d 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -12,16 +12,6 @@
+ 
+ #ifdef HAVE_ALARM
+ 
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_NO_DATA \
+-     && rcode != SQL_SUCCESS \
+-     && rcode != SQL_SUCCESS_WITH_INFO  \
+-     && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+ static char sqlstate[SQL_SQLSTATE_SIZE + 1];
+ 
+ static void
+@@ -58,9 +48,8 @@ sigalrm_handler(int s)
+ 	SQLRETURN rcode;
+ 
+ 	printf(">>>> SQLCancel() ...\n");
+-	rcode = SQLCancel(Statement);
++	CHK(SQLCancel, (Statement));
+ 	printf(">>>> ... SQLCancel done rcode = %d\n", rcode);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLCancel failed");
+ 
+ 	alarm(4);
+ 	signal(SIGALRM, exit_forced);
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+index b02881e..a911f10 100755
+--- a/src/odbc/unittests/hidden.c
++++ b/src/odbc/unittests/hidden.c
+@@ -3,44 +3,12 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.5 2008/10/17 12:21:10 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_NO_DATA \
+-     && rcode != SQL_SUCCESS \
+-     && rcode != SQL_SUCCESS_WITH_INFO  \
+-     && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+-static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+-{
+-	SQLRETURN rcode = 0;
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
+-
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN rcode;
+ 	SQLSMALLINT cnt = 0;
+ 	int failed = 0;
+ 
+@@ -55,8 +23,7 @@ main(int argc, char **argv)
+ 
+ 	Command(Statement, "SELECT c, b FROM #tmp1");
+ 
+-	rcode = SQLNumResultCols(Statement, &cnt);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLNumResultCols 1");
++	CHK(SQLNumResultCols, (Statement, &cnt));
+ 
+ 	if (cnt != 2) {
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+@@ -67,19 +34,14 @@ main(int argc, char **argv)
+ 	/* test hidden column with cursors*/
+ 	CheckCursor();
+ 
+-	rcode = SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLSetStmtAttr SQL_ATTR_CURSOR_SCROLLABLE");
+-	rcode = SQLSetStmtAttr(Statement, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLSetStmtAttr SQL_ATTR_CURSOR_SENSITIVITY");
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER));
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER));
+ 
+-	rcode = SQLPrepare(Statement, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLPrepare 1");
++	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS));
+ 
+-	rcode = SQLExecute(Statement);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLExecute 1");
++	CHK(SQLExecute, (Statement));
+ 
+-	rcode = SQLNumResultCols(Statement, &cnt);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLNumResultCols 1");
++	CHK(SQLNumResultCols, (Statement, &cnt));
+ 
+ 	if (cnt != 3) {
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+
+commit 21f8ff1b90938e91aba3c9fb9f484eddef9b5930
+Author: freddy77 <freddy77>
+Date:   Wed Oct 22 14:15:24 2008 +0000
+
+    improve data.c test
+
+diff --git a/ChangeLog b/ChangeLog
+index 39c027b..780ab38 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Oct 22 16:14:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c: improve
++
+ Fri Oct 17 14:20:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c src/odbc/unittests/cancel.c:
+ 	* src/odbc/unittests/hidden.c:
+@@ -728,4 +731,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2628 2008/10/17 12:21:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2629 2008/10/22 14:15:24 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index e76805a..53a01cf 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -3,7 +3,17 @@
+ 
+ /* Test various bind type */
+ 
+-static char software_version[] = "$Id: data.c,v 1.18 2008/09/12 15:12:24 freddy77 Exp $";
++/*
++ * This test is useful to test odbc_tds2sql function
++ * odbc_tds2sql have some particular cases:
++ * (1) numeric -> binary  numeric is different in ODBC
++ * (2) *       -> binary  dependent from libTDS representation and ODBC one
++ * (3) binary  -> char    TODO
++ * (4) date    -> char    different format
++ * Also we have to check normal char and wide char
++ */
++
++static char software_version[] = "$Id: data.c,v 1.19 2008/10/22 14:15:24 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -15,6 +25,7 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 	unsigned char out_buf[256];
+ 	SQLLEN out_len = 0;
+ 	SQL_NUMERIC_STRUCT *num;
++	SQLWCHAR *wp;
+ 	int i;
+ 
+ 	SQLFreeStmt(Statement, SQL_UNBIND);
+@@ -56,6 +67,16 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 		out_buf[sizeof(out_buf) - 1] = 0;
+ 		sprintf(sbuf,"%u %s", (unsigned int) strlen((char *) out_buf), out_buf);
+ 		break;
++	case SQL_C_WCHAR:
++		assert(out_len >=0 && (out_len % sizeof(SQLWCHAR)) == 0);
++		sprintf(sbuf, "%u ", (unsigned int) (out_len / sizeof(SQLWCHAR)));
++		wp = (SQLWCHAR*) out_buf;
++		for (i = 0; i < out_len; ++i)
++			if ((unsigned int) wp[i] < 256)
++				sprintf(strchr(sbuf, 0), "%c", (char) wp[i]);
++			else
++				sprintf(strchr(sbuf, 0), "\\u%04x", (unsigned int) wp[i]);
++		break;
+ 	default:
+ 		/* not supported */
+ 		assert(0);
+@@ -85,6 +106,7 @@ main(int argc, char *argv[])
+ 	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, "38 0 1 7B");
+ 
+ 	/* all binary results */
++	/* cases (2) */
+ 	Test("CHAR(7)", "pippo", SQL_C_BINARY, "706970706F2020");
+ 	Test("TEXT", "mickey", SQL_C_BINARY, "6D69636B6579");
+ 	Test("VARCHAR(20)", "foo", SQL_C_BINARY, "666F6F");
+@@ -121,8 +143,13 @@ main(int argc, char *argv[])
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+ 		/* nvarchar with extended characters */
+ 		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_CHAR, "4 \x83hi\xf2");
++
++		Test("VARCHAR(20)", "test", SQL_C_WCHAR, "4 test");
++		/* nvarchar with extended characters */
++		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_WCHAR, "4 \\u0083hi\\u00f2");
+ 	}
+ 
++	/* case (1) */
+ 	Test("DECIMAL", "1234.5678", SQL_C_BINARY, "120001D3040000000000000000000000000000");
+ 	Test("NUMERIC", "8765.4321", SQL_C_BINARY, "1200013D220000000000000000000000000000");
+ 
+@@ -143,8 +170,11 @@ main(int argc, char *argv[])
+ 		Test("UNIQUEIDENTIFIER", "0DDF3B64-E692-11D1-AB06-00AA00BDD685", SQL_C_BINARY,
+ 		     big_endian ? "0DDF3B64E69211D1AB0600AA00BDD685" : "643BDF0D92E6D111AB0600AA00BDD685");
+ 
++	/* case (4) */
+ 	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_CHAR, "23 2006-06-09 11:22:44.000");
+ 	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_CHAR, "19 2006-06-12 22:37:00");
++	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_WCHAR, "23 2006-06-09 11:22:44.000");
++	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_WCHAR, "19 2006-06-12 22:37:00");
+ 
+ 	Disconnect();
+ 
+
+commit a5d388407de4c01426558aa6908a98c79f34dd00
+Author: freddy77 <freddy77>
+Date:   Wed Oct 22 15:22:59 2008 +0000
+
+    initial SQL_C_WCHAR support
+
+diff --git a/ChangeLog b/ChangeLog
+index 780ab38..4ca610c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Oct 22 17:21:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c src/odbc/unittests/data.c:
++	- initial SQL_C_WCHAR support
++
+ Mon Oct 22 16:14:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: improve
+ 
+@@ -731,4 +735,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2629 2008/10/22 14:15:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2630 2008/10/22 15:22:59 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 40fb59c..450f391 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.105 2008/10/17 08:30:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.106 2008/10/22 15:22:59 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -371,6 +371,7 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ /**
+  * Pass this an SQL_C_* type and get a SYB* type which most closely corresponds
+  * to the SQL_C_* type.
++ * This function can return XSYBNVARCHAR even if server do not support it
+  */
+ int
+ odbc_c_to_server_type(int c_type)
+@@ -379,6 +380,10 @@ odbc_c_to_server_type(int c_type)
+ 		/* FIXME this should be dependent on size of data !!! */
+ 	case SQL_C_BINARY:
+ 		return SYBBINARY;
++#ifdef SQL_C_WCHAR
++	case SQL_C_WCHAR:
++		return XSYBNVARCHAR;
++#endif
+ 		/* TODO what happen if varchar is more than 255 characters long */
+ 	case SQL_C_CHAR:
+ 		return SYBVARCHAR;
+@@ -434,9 +439,6 @@ odbc_c_to_server_type(int c_type)
+ 	case SQL_C_INTERVAL_HOUR_TO_MINUTE:
+ 	case SQL_C_INTERVAL_HOUR_TO_SECOND:
+ 	case SQL_C_INTERVAL_MINUTE_TO_SECOND:
+-#ifdef SQL_C_WCHAR
+-	case SQL_C_WCHAR:
+-#endif
+ 		break;
+ 	}
+ 	return TDS_FAIL;
+@@ -973,6 +975,7 @@ odbc_set_concise_sql_type(SQLSMALLINT concise_type, struct _drecord * drec, int
+ 	TYPE_NORMAL(SQL_C_BINARY) \
+ \
+ 	TYPE_NORMAL(SQL_C_CHAR) \
++	TYPE_NORMAL(SQL_C_WCHAR) \
+ \
+ 	TYPE_NORMAL(SQL_C_NUMERIC) \
+ \
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 53a01cf..5aaf532 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.19 2008/10/22 14:15:24 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.20 2008/10/22 15:22:59 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -71,7 +71,7 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 		assert(out_len >=0 && (out_len % sizeof(SQLWCHAR)) == 0);
+ 		sprintf(sbuf, "%u ", (unsigned int) (out_len / sizeof(SQLWCHAR)));
+ 		wp = (SQLWCHAR*) out_buf;
+-		for (i = 0; i < out_len; ++i)
++		for (i = 0; i < out_len / sizeof(SQLWCHAR); ++i)
+ 			if ((unsigned int) wp[i] < 256)
+ 				sprintf(strchr(sbuf, 0), "%c", (char) wp[i]);
+ 			else
+@@ -146,7 +146,8 @@ main(int argc, char *argv[])
+ 
+ 		Test("VARCHAR(20)", "test", SQL_C_WCHAR, "4 test");
+ 		/* nvarchar with extended characters */
+-		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_WCHAR, "4 \\u0083hi\\u00f2");
++		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_WCHAR, "4 \x83hi\xf2");
++		Test("NVARCHAR(20)", "0xA406A5FB", SQL_C_WCHAR, "2 \\u06a4\\ufba5");
+ 	}
+ 
+ 	/* case (1) */
+
+commit 8723299ad1dac8a041656d1dcfed273dc2956daa
+Author: freddy77 <freddy77>
+Date:   Wed Oct 22 20:16:11 2008 +0000
+
+    support conversions from wire to SQL_C_WCHAR
+
+diff --git a/ChangeLog b/ChangeLog
+index 4ca610c..430e3d0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Oct 22 22:15:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/unittests/data.c:
++	- support conversions from wire to SQL_C_WCHAR
++
+ Mon Oct 22 17:21:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c src/odbc/unittests/data.c:
+ 	- initial SQL_C_WCHAR support
+@@ -735,4 +739,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2630 2008/10/22 15:22:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2631 2008/10/22 20:16:11 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 1dd8bc3..34894dd 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -40,7 +40,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.56 2008/10/17 08:56:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.57 2008/10/22 20:16:11 freddy77 Exp $");
+ 
+ #if SIZEOF_SQLWCHAR == 2
+ # if WORDS_BIGENDIAN
+@@ -184,10 +184,9 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		}
+ 	}
+ 
+-	/*
+-	 * TODO support SQL_C_WCHAR converting when needed
+-	 */
+-	if (desttype == SQL_C_CHAR) {
++	if (desttype == SQL_C_WCHAR)
++		destlen /= sizeof(SQLWCHAR);
++	if (desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR) {
+ 		switch (srctype) {
+ 		case SYBLONGBINARY:
+ 		case SYBBINARY:
+@@ -205,7 +204,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		ores.cc.c = dest;
+ 	}
+ 
+-	if (desttype == SQL_C_CHAR && (srctype == SYBDATETIME || srctype == SYBDATETIME4)) {
++	if ((desttype == SQL_C_CHAR || desttype == SQL_C_WCHAR) && (srctype == SYBDATETIME || srctype == SYBDATETIME4)) {
+ 		char buf[40];
+ 		TDSDATEREC when;
+ 
+@@ -249,6 +248,36 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		}
+ 		break;
+ 
++	case SQL_C_WCHAR:
++		tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: outputting character data destlen = %lu \n", (unsigned long) destlen);
++
++		ret = nRetVal * sizeof(SQLWCHAR);
++		/* TODO handle not terminated configuration */
++		if (destlen > 0) {
++			SQLWCHAR *wp = (SQLWCHAR *) dest;
++			SQLCHAR  *p  = (SQLCHAR *)  dest;
++
++			cplen = (destlen - 1) > nRetVal ? nRetVal : (destlen - 1);
++			assert(cplen >= 0);
++			/*
++			 * odbc always terminate but do not overwrite 
++			 * destination buffer more than needed
++			 */
++			/* TODO check for source !!! */
++			if (curcol)
++				curcol->column_text_sqlgetdatapos += binary_conversion ? cplen / 2 : cplen;
++			wp[cplen] = 0;
++			for (;cplen > 0;) {
++				--cplen;
++				wp[cplen] = p[cplen];
++			}
++		} else {
++			/* if destlen == 0 we return only length */
++			if (destlen != 0)
++				ret = SQL_NULL_DATA;
++		}
++		break;
++
+ 	case SQL_C_TYPE_DATE:
+ 	case SQL_C_DATE:
+ 
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 5aaf532..78dbd75 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.20 2008/10/22 15:22:59 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.21 2008/10/22 20:16:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -138,6 +138,8 @@ main(int argc, char *argv[])
+ 		}
+ 	}
+ 
++	Test("INT", "-123", SQL_C_CHAR, "4 -123");
++	Test("INT", "78654", SQL_C_WCHAR, "5 78654");
+ 	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
+ 		/* nvarchar without extended characters */
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+@@ -148,6 +150,7 @@ main(int argc, char *argv[])
+ 		/* nvarchar with extended characters */
+ 		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_WCHAR, "4 \x83hi\xf2");
+ 		Test("NVARCHAR(20)", "0xA406A5FB", SQL_C_WCHAR, "2 \\u06a4\\ufba5");
++		/* TODO NVARCHAR -> SQL_C_LONG */
+ 	}
+ 
+ 	/* case (1) */
+
+commit f431a8300bdb3bb28cc95b140881c329c5ee3d5a
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 06:01:37 2008 +0000
+
+    fix some small issues on odbc_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index 430e3d0..e68bcd6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,12 +1,18 @@
+-Mon Oct 22 22:15:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Thu Oct 23 08:00:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c:
++	- update correctly sqlgetdatapos
++	- add some comments
++	- destlen is always >= 0 (SQLULEN)
++
++Wed Oct 22 22:15:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/odbc/unittests/data.c:
+ 	- support conversions from wire to SQL_C_WCHAR
+ 
+-Mon Oct 22 17:21:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Wed Oct 22 17:21:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c src/odbc/unittests/data.c:
+ 	- initial SQL_C_WCHAR support
+ 
+-Mon Oct 22 16:14:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++Wed Oct 22 16:14:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: improve
+ 
+ Fri Oct 17 14:20:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+@@ -739,4 +745,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2631 2008/10/22 20:16:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2632 2008/10/23 06:01:37 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 34894dd..e1d22aa 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -40,7 +40,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.57 2008/10/22 20:16:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.58 2008/10/23 06:01:37 freddy77 Exp $");
+ 
+ #if SIZEOF_SQLWCHAR == 2
+ # if WORDS_BIGENDIAN
+@@ -200,7 +200,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		}
+ 
+ 		nDestSybType = TDS_CONVERT_CHAR;
+-		ores.cc.len = destlen >= 0 ? destlen : 0;
++		ores.cc.len = destlen;
+ 		ores.cc.c = dest;
+ 	}
+ 
+@@ -214,7 +214,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		tds_strftime(buf, sizeof(buf), srctype == SYBDATETIME ? "%Y-%m-%d %H:%M:%S.%z" : "%Y-%m-%d %H:%M:%S", &when);
+ 
+ 		nRetVal = strlen(buf);
+-		memcpy(dest, buf, destlen >= 0 ? (destlen < nRetVal ? destlen : nRetVal) : 0);
++		memcpy(dest, buf, destlen < nRetVal ? destlen : nRetVal);
+ 	} else {
+ 		nRetVal = tds_convert(context, srctype, src, srclen, nDestSybType, &ores);
+ 	}
+@@ -237,14 +237,12 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 			 * odbc always terminate but do not overwrite 
+ 			 * destination buffer more than needed
+ 			 */
+-			/* TODO check for source !!! */
+-			if (curcol)
+-				curcol->column_text_sqlgetdatapos += binary_conversion ? cplen / 2 : cplen;
++			/* update datapos only for binary source (char already handled) */
++			if (curcol && binary_conversion)
++				curcol->column_text_sqlgetdatapos += cplen / 2;
+ 			dest[cplen] = 0;
+ 		} else {
+ 			/* if destlen == 0 we return only length */
+-			if (destlen != 0)
+-				ret = SQL_NULL_DATA;
+ 		}
+ 		break;
+ 
+@@ -263,18 +261,17 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 			 * odbc always terminate but do not overwrite 
+ 			 * destination buffer more than needed
+ 			 */
+-			/* TODO check for source !!! */
+-			if (curcol)
+-				curcol->column_text_sqlgetdatapos += binary_conversion ? cplen / 2 : cplen;
++			/* update datapos only for binary source (char already handled) */
++			if (curcol && binary_conversion)
++				curcol->column_text_sqlgetdatapos += cplen / 2;
++			/* convert in place and terminate */
+ 			wp[cplen] = 0;
+-			for (;cplen > 0;) {
++			while (cplen > 0) {
+ 				--cplen;
+ 				wp[cplen] = p[cplen];
+ 			}
+ 		} else {
+ 			/* if destlen == 0 we return only length */
+-			if (destlen != 0)
+-				ret = SQL_NULL_DATA;
+ 		}
+ 		break;
+ 
+
+commit 1aeefdddaf60ec95798eaa9aa52c51c852921073
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 08:02:45 2008 +0000
+
+    improve data.c test
+
+diff --git a/ChangeLog b/ChangeLog
+index e68bcd6..3748613 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Oct 23 10:01:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c:
++	- improve test
++
+ Thu Oct 23 08:00:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c:
+ 	- update correctly sqlgetdatapos
+@@ -745,4 +749,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2632 2008/10/23 06:01:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2633 2008/10/23 08:02:45 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 78dbd75..b3ff985 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.21 2008/10/22 20:16:11 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.22 2008/10/23 08:02:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -77,6 +77,10 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 			else
+ 				sprintf(strchr(sbuf, 0), "\\u%04x", (unsigned int) wp[i]);
+ 		break;
++	case SQL_C_LONG:
++		assert(out_len == sizeof(SQLINTEGER));
++		sprintf(sbuf, "%ld", (long int) *((SQLINTEGER *) out_buf));
++		break;
+ 	default:
+ 		/* not supported */
+ 		assert(0);
+@@ -140,6 +144,7 @@ main(int argc, char *argv[])
+ 
+ 	Test("INT", "-123", SQL_C_CHAR, "4 -123");
+ 	Test("INT", "78654", SQL_C_WCHAR, "5 78654");
++	Test("VARCHAR(10)", "  51245  ", SQL_C_LONG, "51245");
+ 	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
+ 		/* nvarchar without extended characters */
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+@@ -150,7 +155,8 @@ main(int argc, char *argv[])
+ 		/* nvarchar with extended characters */
+ 		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_WCHAR, "4 \x83hi\xf2");
+ 		Test("NVARCHAR(20)", "0xA406A5FB", SQL_C_WCHAR, "2 \\u06a4\\ufba5");
+-		/* TODO NVARCHAR -> SQL_C_LONG */
++		/* NVARCHAR -> SQL_C_LONG */
++		Test("NVARCHAR(20)", "-24785  ", SQL_C_LONG, "-24785");
+ 	}
+ 
+ 	/* case (1) */
+
+commit c1ba2f93c3b08b443942a4137956c24661581972
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 12:33:59 2008 +0000
+
+    reduce some variable scope
+
+diff --git a/ChangeLog b/ChangeLog
+index 3748613..6fa97c7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Oct 23 14:32:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c: 
++	- reduce some variable scope
++
+ Thu Oct 23 10:01:23 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c:
+ 	- improve test
+@@ -749,4 +753,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2633 2008/10/23 08:02:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2634 2008/10/23 12:33:59 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index e1d22aa..23c5734 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -40,7 +40,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.58 2008/10/23 06:01:37 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.59 2008/10/23 12:33:59 freddy77 Exp $");
+ 
+ #if SIZEOF_SQLWCHAR == 2
+ # if WORDS_BIGENDIAN
+@@ -112,12 +112,6 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 
+ 	CONV_RESULT ores;
+ 
+-	TDSDATEREC dr;
+-	DATE_STRUCT *dsp;
+-	TIME_STRUCT *tsp;
+-	TIMESTAMP_STRUCT *tssp;
+-	SQL_NUMERIC_STRUCT *num;
+-
+ 	SQLLEN ret = SQL_NULL_DATA;
+ 	int i, cplen;
+ 	int binary_conversion = 0;
+@@ -277,57 +271,66 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 
+ 	case SQL_C_TYPE_DATE:
+ 	case SQL_C_DATE:
++		{
++			TDSDATEREC dr;
++			DATE_STRUCT *dsp = (DATE_STRUCT *) dest;
+ 
+-		/* we've already converted the returned value to a SYBDATETIME */
+-		/* now decompose date into constituent parts...                */
+-
+-		tds_datecrack(SYBDATETIME, &(ores.dt), &dr);
+-
+-		dsp = (DATE_STRUCT *) dest;
++			/*
++			 * we've already converted the returned value to a SYBDATETIME
++			 * now decompose date into constituent parts...
++			 */
++			tds_datecrack(SYBDATETIME, &(ores.dt), &dr);
+ 
+-		dsp->year = dr.year;
+-		dsp->month = dr.month + 1;
+-		dsp->day = dr.day;
++			dsp->year = dr.year;
++			dsp->month = dr.month + 1;
++			dsp->day = dr.day;
+ 
+-		ret = sizeof(DATE_STRUCT);
++			ret = sizeof(DATE_STRUCT);
++		}
+ 		break;
+ 
+ 	case SQL_C_TYPE_TIME:
+ 	case SQL_C_TIME:
++		{
++			TDSDATEREC dr;
++			TIME_STRUCT *tsp = (TIME_STRUCT *) dest;
+ 
+-		/* we've already converted the returned value to a SYBDATETIME */
+-		/* now decompose date into constituent parts...                */
+-
+-		tds_datecrack(SYBDATETIME, &(ores.dt), &dr);
+-
+-		tsp = (TIME_STRUCT *) dest;
++			/*
++			 * we've already converted the returned value to a SYBDATETIME
++			 * now decompose date into constituent parts...
++			 */
++			tds_datecrack(SYBDATETIME, &(ores.dt), &dr);
+ 
+-		tsp->hour = dr.hour;
+-		tsp->minute = dr.minute;
+-		tsp->second = dr.second;
++			tsp->hour = dr.hour;
++			tsp->minute = dr.minute;
++			tsp->second = dr.second;
+ 
+-		ret = sizeof(TIME_STRUCT);
++			ret = sizeof(TIME_STRUCT);
++		}
+ 		break;
+ 
+ 	case SQL_C_TYPE_TIMESTAMP:
+-	case SQL_C_TIMESTAMP:
+-
+-		/* we've already converted the returned value to a SYBDATETIME */
+-		/* now decompose date into constituent parts...                */
+-
+-		tds_datecrack(SYBDATETIME, &(ores.dt), &dr);
++	case SQL_C_TIMESTAMP: 
++		{
++			TDSDATEREC dr;
++			TIMESTAMP_STRUCT *tssp = (TIMESTAMP_STRUCT *) dest;
+ 
+-		tssp = (TIMESTAMP_STRUCT *) dest;
++			/*
++			 * we've already converted the returned value to a SYBDATETIME
++			 * now decompose date into constituent parts...
++			 */
++			tds_datecrack(SYBDATETIME, &(ores.dt), &dr);
+ 
+-		tssp->year = dr.year;
+-		tssp->month = dr.month + 1;
+-		tssp->day = dr.day;
+-		tssp->hour = dr.hour;
+-		tssp->minute = dr.minute;
+-		tssp->second = dr.second;
+-		tssp->fraction = dr.millisecond * 1000000u;
++			tssp->year = dr.year;
++			tssp->month = dr.month + 1;
++			tssp->day = dr.day;
++			tssp->hour = dr.hour;
++			tssp->minute = dr.minute;
++			tssp->second = dr.second;
++			tssp->fraction = dr.millisecond * 1000000u;
+ 
+-		ret = sizeof(TIMESTAMP_STRUCT);
++			ret = sizeof(TIMESTAMP_STRUCT);
++		}
+ 		break;
+ 
+ #ifdef SQL_C_SBIGINT
+@@ -371,22 +374,24 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 		break;
+ 
+ 	case SQL_C_NUMERIC:
+-		/* ODBC numeric is quite different from TDS one ... */
+-		num = (SQL_NUMERIC_STRUCT *) dest;
+-		num->precision = ores.n.precision;
+-		num->scale = ores.n.scale;
+-		num->sign = ores.n.array[0] ^ 1;
+-		/*
+-		 * TODO can be greater than SQL_MAX_NUMERIC_LEN ?? 
+-		 * seeing Sybase manual wire support bigger numeric but currently
+-		 * DBs so not support such precision
+-		 */
+-		i = ODBC_MIN(tds_numeric_bytes_per_prec[ores.n.precision] - 1, SQL_MAX_NUMERIC_LEN);
+-		memcpy(num->val, ores.n.array + 1, i);
+-		tds_swap_bytes(num->val, i);
+-		if (i < SQL_MAX_NUMERIC_LEN)
+-			memset(num->val + i, 0, SQL_MAX_NUMERIC_LEN - i);
+-		ret = sizeof(SQL_NUMERIC_STRUCT);
++		{
++			/* ODBC numeric is quite different from TDS one ... */
++			SQL_NUMERIC_STRUCT *num = (SQL_NUMERIC_STRUCT *) dest;
++			num->precision = ores.n.precision;
++			num->scale = ores.n.scale;
++			num->sign = ores.n.array[0] ^ 1;
++			/*
++			 * TODO can be greater than SQL_MAX_NUMERIC_LEN ?? 
++			 * seeing Sybase manual wire support bigger numeric but currently
++			 * DBs so not support such precision
++			 */
++			i = ODBC_MIN(tds_numeric_bytes_per_prec[ores.n.precision] - 1, SQL_MAX_NUMERIC_LEN);
++			memcpy(num->val, ores.n.array + 1, i);
++			tds_swap_bytes(num->val, i);
++			if (i < SQL_MAX_NUMERIC_LEN)
++				memset(num->val + i, 0, SQL_MAX_NUMERIC_LEN - i);
++			ret = sizeof(SQL_NUMERIC_STRUCT);
++		}
+ 		break;
+ 
+ #ifdef SQL_C_GUID
+
+commit 08db1b36051409e79cc8069867f02d1d6e739eb9
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 12:39:38 2008 +0000
+
+    support conversions from SQL_C_WCHAR to fixed types
+
+diff --git a/ChangeLog b/ChangeLog
+index 6fa97c7..e86d021 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Oct 23 14:38:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c:
++	- support conversions from SQL_C_WCHAR to fixed types
++
+ Thu Oct 23 14:32:15 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c: 
+ 	- reduce some variable scope
+@@ -753,4 +757,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2634 2008/10/23 12:33:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2635 2008/10/23 12:39:38 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 23c5734..9df2f02 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -32,6 +32,8 @@
+ #include <string.h>
+ #endif /* HAVE_STRING_H */
+ 
++#include <ctype.h>
++
+ #include "tdsodbc.h"
+ #include "tdsconvert.h"
+ #include "tdsiconv.h"
+@@ -40,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.59 2008/10/23 12:33:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.60 2008/10/23 12:39:38 freddy77 Exp $");
+ 
+ #if SIZEOF_SQLWCHAR == 2
+ # if WORDS_BIGENDIAN
+@@ -58,6 +60,8 @@ TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.59 2008/10/23 12:33:59 freddy77 Exp $
+ #error SIZEOF_SQLWCHAR not supported !!
+ #endif
+ 
++#define TDS_ISSPACE(c) isspace((unsigned char) (c))
++
+ static SQLLEN
+ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen)
+ {
+@@ -102,6 +106,41 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 	return ol;
+ }
+ 
++static int
++odbc_tds_convert_wide_iso(TDSCOLUMN *curcol, TDS_CHAR *src, TDS_UINT srclen, TDS_CHAR *buf, TDS_UINT buf_len)
++{
++	TDS_CHAR *p;
++	/* TODO check for endian */
++	
++	/* skip white spaces */
++	while (srclen > 1 && src[1] == 0 && TDS_ISSPACE(src[0])) {
++		srclen -= 2;
++		src += 2;
++	}
++
++	/* convert */
++	p = buf;
++	while (buf_len > 1 && srclen > 1 && src[1] == 0) {
++		*p++ = src[0];
++		--buf_len;
++		srclen -= 2;
++		src += 2;
++	}
++
++	/* skip white spaces */
++	while (srclen > 1 && src[1] == 0 && TDS_ISSPACE(src[0])) {
++		srclen -= 2;
++		src += 2;
++	}
++
++	/* still characters, wrong format */
++	if (srclen)
++		return -1;
++
++	*p = 0;
++	return p - buf;
++}
++
+ SQLLEN
+ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen,
+ 	     const struct _drecord *drec_ixd)
+@@ -115,6 +154,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 	SQLLEN ret = SQL_NULL_DATA;
+ 	int i, cplen;
+ 	int binary_conversion = 0;
++	TDS_CHAR conv_buf[256];
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "odbc_tds2sql: src is %d dest = %d\n", srctype, desttype);
+ 
+@@ -172,9 +212,15 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 			return odbc_convert_char(stmt, curcol, src, srclen, desttype, dest, destlen);
+ 		if (is_unicode_type(srctype)) {
+ 			/*
+-			 * TODO convert to single and then process normally.
++			 * convert to single and then process normally.
+ 			 * Here we processed SQL_C_BINARY and SQL_C_*CHAR so only fixed types are left
+ 			 */
++			i = odbc_tds_convert_wide_iso(curcol, src, srclen, conv_buf, sizeof(conv_buf));
++			if (i < 0)
++				return SQL_NULL_DATA;
++			src = conv_buf;
++			srclen = i;
++			srctype = SYBVARCHAR;
+ 		}
+ 	}
+ 
+
+commit fc0f2b6b55e27b541a769864ffec4ceb6534681c
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 15:07:48 2008 +0000
+
+    move ODBC_WIDE_NAME computation in include/tdsodbc.c
+
+diff --git a/ChangeLog b/ChangeLog
+index e86d021..c32bd01 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Oct 23 17:05:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy: updates
++	* include/tdsodbc.h src/odbc/convert_tds2sql.c:
++	- move ODBC_WIDE_NAME computation in include/tdsodbc.c
++
+ Thu Oct 23 14:38:40 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c:
+ 	- support conversions from SQL_C_WCHAR to fixed types
+@@ -757,4 +762,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2635 2008/10/23 12:39:38 freddy77 Exp $
++$Id: ChangeLog,v 1.2636 2008/10/23 15:07:48 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index d60b592..796d40c 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -47,11 +47,12 @@ ODBC SQL_C_CHAR with wide
+ -------------------------
+ Check iso8859-1 for single ??
+ test to review
+-- data.c (char -> sql_c_char)
++- data.c (char -> sql_c_char) DONE
+ - genparams.c
+ - getdata.c ??
+ - putdata.c ??
+ - wchar.c
++- blob1.c (SQLGetData test with binary -> char and between chars)
+ Is it possible to support direct binding for parameters using different
+ encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
+ possible changing TDSCOLUMN->char_conv. Some work should be done in 
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 7c1df42..3997a0e 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.112 2008/10/17 08:30:03 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.113 2008/10/23 15:07:48 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -531,6 +531,22 @@ size_t sqlwcslen(const SQLWCHAR * s);
+ #define sqlwcslen wcslen
+ #endif
+ 
++#if SIZEOF_SQLWCHAR == 2
++# if WORDS_BIGENDIAN
++#  define ODBC_WIDE_NAME "UCS-2BE"
++# else
++#  define ODBC_WIDE_NAME "UCS-2LE"
++# endif
++#elif SIZEOF_SQLWCHAR == 4
++# if WORDS_BIGENDIAN
++#  define ODBC_WIDE_NAME "UCS-4BE"
++# else
++#  define ODBC_WIDE_NAME "UCS-4LE"
++# endif
++#else
++#error SIZEOF_SQLWCHAR not supported !!
++#endif
++
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility pop
+ #endif
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 9df2f02..a81fc89 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,23 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.60 2008/10/23 12:39:38 freddy77 Exp $");
+-
+-#if SIZEOF_SQLWCHAR == 2
+-# if WORDS_BIGENDIAN
+-#  define ODBC_WIDE_NAME "UCS-2BE"
+-# else
+-#  define ODBC_WIDE_NAME "UCS-2LE"
+-# endif
+-#elif SIZEOF_SQLWCHAR == 4
+-# if WORDS_BIGENDIAN
+-#  define ODBC_WIDE_NAME "UCS-4BE"
+-# else
+-#  define ODBC_WIDE_NAME "UCS-4LE"
+-# endif
+-#else
+-#error SIZEOF_SQLWCHAR not supported !!
+-#endif
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.61 2008/10/23 15:07:49 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -110,7 +94,10 @@ static int
+ odbc_tds_convert_wide_iso(TDSCOLUMN *curcol, TDS_CHAR *src, TDS_UINT srclen, TDS_CHAR *buf, TDS_UINT buf_len)
+ {
+ 	TDS_CHAR *p;
+-	/* TODO check for endian */
++	/*
++	 * TODO check for endian
++	 * This affect for instance Sybase under little endian system
++	 */
+ 	
+ 	/* skip white spaces */
+ 	while (srclen > 1 && src[1] == 0 && TDS_ISSPACE(src[0])) {
+
+commit 96458d777c1826e20f6d5f082eb9928fcd7f1eb7
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 15:09:29 2008 +0000
+
+    improve some conversions from SQL_C_WCHAR
+
+diff --git a/ChangeLog b/ChangeLog
+index c32bd01..733fe6a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Oct 23 17:09:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
++	- improve some conversions from SQL_C_WCHAR
++
+ Thu Oct 23 17:05:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy: updates
+ 	* include/tdsodbc.h src/odbc/convert_tds2sql.c:
+@@ -762,4 +766,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2636 2008/10/23 15:07:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2637 2008/10/23 15:09:29 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 53ade07..e48ad3a 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -47,12 +47,13 @@
+ 
+ #include "tdsodbc.h"
+ #include "tdsconvert.h"
++#include "tdsiconv.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.75 2008/09/11 15:09:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.76 2008/10/23 15:09:29 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -156,8 +157,23 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		return SQL_ERROR;
+ 	tdsdump_log(TDS_DBG_INFO2, "trace\n");
+ 
++	/* get C type */
++	sql_src_type = drec_apd->sql_desc_concise_type;
++	if (sql_src_type == SQL_C_DEFAULT)
++		sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
++
+ 	/* TODO what happen for unicode types ?? */
+-	tds_set_param_type(dbc->tds_socket, curcol, dest_type);
++	if (is_char_type(dest_type) && sql_src_type == SQL_C_WCHAR) {
++		TDSSOCKET *tds = dbc->tds_socket;
++		TDSICONV *conv = tds->char_convs[is_unicode_type(dest_type) ? client2ucs2 : client2server_chardata];
++
++		tds_set_column_type(tds, curcol, dest_type);
++
++                curcol->char_conv = tds_iconv_get(tds, ODBC_WIDE_NAME, conv->server_charset.name);
++		memcpy(curcol->column_collation, tds->collation, sizeof(tds->collation));
++	} else {
++		tds_set_param_type(dbc->tds_socket, curcol, dest_type);
++	}
+ 	if (is_numeric_type(curcol->column_type)) {
+ 		curcol->column_prec = drec_ipd->sql_desc_precision;
+ 		curcol->column_scale = drec_ipd->sql_desc_scale;
+@@ -193,11 +209,6 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		tds_set_param_type(dbc->tds_socket, curcol, tds_get_null_type(dest_type));
+ 	}
+ 
+-	/* get C type */
+-	sql_src_type = drec_apd->sql_desc_concise_type;
+-	if (sql_src_type == SQL_C_DEFAULT)
+-		sql_src_type = odbc_sql_to_c_type_default(drec_ipd->sql_desc_concise_type);
+-
+ 	/* test source type */
+ 	/* TODO test intervals */
+ 	src_type = odbc_c_to_server_type(sql_src_type);
+@@ -298,6 +309,25 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		}
+ 	}
+ 
++	switch (dest_type) {
++	case SYBCHAR:
++	case SYBVARCHAR:
++	case XSYBCHAR:
++	case XSYBVARCHAR:
++	case XSYBNVARCHAR:
++	case XSYBNCHAR:
++	case SYBNVARCHAR:
++		if (!need_data && is_char_type(src_type)) {
++			if (curcol->column_data && curcol->column_data_free)
++				curcol->column_data_free(curcol);
++			curcol->column_data_free = NULL;
++			curcol->column_data = (TDS_UCHAR*) src;
++			curcol->column_size = len;
++			curcol->column_cur_size = len;
++			return SQL_SUCCESS;
++		}
++	}
++
+ 	/* allocate given space */
+ 	if (!tds_alloc_param_data(curcol)) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 194d321..e5580f0 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.31 2008/10/17 08:06:23 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.32 2008/10/23 15:09:29 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -278,7 +278,8 @@ AllTests(void)
+ 	TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");
+ 
+ 	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "1EasyTest");
+-	/* TODO use collate in sintax if available */
++	TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_VARCHAR, "VARCHAR(10)", "Test 12345");
++	/* TODO use collate in syntax if available */
+ 	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "me\xf4");
+ 
+ 	precision = 6;
+@@ -307,6 +308,9 @@ AllTests(void)
+ 		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "8 foo test");
+ 		/* TODO use collate in sintax if available */
+ 		Test("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");
++
++		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest2");
++		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
+ 	}
+ }
+ 
+
+commit 0f513128d29b81794b055749226528f3a4df067d
+Author: freddy77 <freddy77>
+Date:   Thu Oct 23 15:26:53 2008 +0000
+
+    new type tests
+
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index e5580f0..13951c0 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,7 +4,7 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.32 2008/10/23 15:09:29 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.33 2008/10/23 15:26:53 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -302,6 +302,8 @@ AllTests(void)
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
+ 
++		TestInput(SQL_C_LONG, "INT", SQL_WVARCHAR, "NVARCHAR(100)", "45236");
++
+ 		precision = 6;
+ 		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
+ 		precision = 12;
+@@ -311,6 +313,8 @@ AllTests(void)
+ 
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest2");
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
++
++		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");
+ 	}
+ }
+ 
+
+commit eddbc240205f53aaf9fbd3c9cbf5a910537a8850
+Author: freddy77 <freddy77>
+Date:   Fri Oct 24 05:37:19 2008 +0000
+
+    comments added
+
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index a81fc89..2ac12f8 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,10 +42,13 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.61 2008/10/23 15:07:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.62 2008/10/24 05:37:19 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
++/**
++ * Handle conversions from TDS (N)CHAR to ODBC (W)CHAR
++ */
+ static SQLLEN
+ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT srclen, int desttype, TDS_CHAR * dest, SQLULEN destlen)
+ {
+@@ -90,6 +93,9 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 	return ol;
+ }
+ 
++/**
++ * Handle conversions from TDS NCHAR to ISO8859-1 striping spaces (for fixed types)
++ */
+ static int
+ odbc_tds_convert_wide_iso(TDSCOLUMN *curcol, TDS_CHAR *src, TDS_UINT srclen, TDS_CHAR *buf, TDS_UINT buf_len)
+ {
+
+commit 0c7ed2bd961626697fb0962dce86d2141dc50d7f
+Author: freddy77 <freddy77>
+Date:   Fri Oct 24 08:29:22 2008 +0000
+
+    more SQL_C_WCHAR works
+
+diff --git a/ChangeLog b/ChangeLog
+index 733fe6a..42daf9a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,14 @@
++Fri Oct 24 10:27:54 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy: update
++	* src/odbc/sql2tds.c: fix SQL_NTS for SQL_C_WCHAR
++	* src/odbc/sqlwchar.c: optimize
++	* src/odbc/unittests/cancel.c: avoid valgrind error
++	* src/odbc/unittests/genparams.c:
++	- add check for SQL_NTS
++	- add check for NUMERIC
++	- add note
++	- rename Test function to TestOutput
++
+ Thu Oct 23 17:09:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
+ 	- improve some conversions from SQL_C_WCHAR
+@@ -766,4 +777,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2637 2008/10/23 15:09:29 freddy77 Exp $
++$Id: ChangeLog,v 1.2638 2008/10/24 08:29:22 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index 796d40c..bdb3a70 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -51,7 +51,6 @@ test to review
+ - genparams.c
+ - getdata.c ??
+ - putdata.c ??
+-- wchar.c
+ - blob1.c (SQLGetData test with binary -> char and between chars)
+ Is it possible to support direct binding for parameters using different
+ encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index e48ad3a..56595ac 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.76 2008/10/23 15:09:29 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.77 2008/10/24 08:29:22 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -262,7 +262,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 			return SQL_ERROR;
+ 		}
+ 		if (sql_src_type == SQL_C_WCHAR)
+-			len = sqlwcslen((const SQLWCHAR *) src);
++			len = sqlwcslen((const SQLWCHAR *) src) * sizeof(SQLWCHAR);
+ 		else
+ 			len = strlen(src);
+ 		break;
+diff --git a/src/odbc/sqlwchar.c b/src/odbc/sqlwchar.c
+index 61eb5a7..bcaf1c1 100644
+--- a/src/odbc/sqlwchar.c
++++ b/src/odbc/sqlwchar.c
+@@ -26,15 +26,16 @@
+ 
+ #include "tdsodbc.h"
+ 
+-TDS_RCSID(var, "$Id: sqlwchar.c,v 1.1 2008/02/05 09:46:33 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sqlwchar.c,v 1.2 2008/10/24 08:29:22 freddy77 Exp $");
+ 
+ #if SIZEOF_SQLWCHAR != SIZEOF_WCHAR_T
+ size_t sqlwcslen(const SQLWCHAR * s)
+ {
+-	size_t res = 0;
+-	while (*s)
+-		++s, ++res;
+-	return res;
++	const SQLWCHAR *p = s;
++
++	while (*p)
++		++p;
++	return p - s;
+ }
+ #endif
+ 
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 3fa879d..6de5f97 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -49,7 +49,7 @@ sigalrm_handler(int s)
+ 
+ 	printf(">>>> SQLCancel() ...\n");
+ 	CHK(SQLCancel, (Statement));
+-	printf(">>>> ... SQLCancel done rcode = %d\n", rcode);
++	printf(">>>> ... SQLCancel done\n");
+ 
+ 	alarm(4);
+ 	signal(SIGALRM, exit_forced);
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 13951c0..15e91c9 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -4,22 +4,36 @@
+ 
+ /* Test various type from odbc and to odbc */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.33 2008/10/23 15:26:53 freddy77 Exp $";
++/*
++ * This test is useful to test odbc_sql2tds function using TestInput
++ * odbc_sql2tds have some particular cases:
++ * (1) char    -> char     handled differently with encoding problems DONE
++ * (2) date    -> *        different format
++ * (3) numeric -> *        different format DONE
++ * (4) *       -> numeric  take precision and scale from ipd
++ * (5) *       -> char     test wide
++ * (6) *       -> blob     test wchar and ntext
++ * (7) *       -> binary   test also with wchar
++ * (8) binary  -> *        test aldo with wchar
++ * Also we have to check normal char and wide char
++ */
++
++static char software_version[] = "$Id: genparams.c,v 1.34 2008/10/24 08:29:22 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+-static const int tds_no_dm = 1;
++static const char tds_no_dm = 1;
+ #else
+-static const int tds_no_dm = 0;
++static const char tds_no_dm = 0;
+ #endif
+ 
+-static int precision = 18;
+-static int exec_direct = 0;
+-static int prepare_before = 0;
+-static int use_cursors = 0;
++static char precision = 18;
++static char exec_direct = 0;
++static char prepare_before = 0;
++static char use_cursors = 0;
+ 
+ static void
+-Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *expected)
++TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *expected)
+ {
+ 	char sbuf[1024];
+ 	unsigned char out_buf[256];
+@@ -97,7 +111,8 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, SQL
+ 	Command(Statement, "drop proc spTestProc");
+ }
+ 
+-static int check_truncation = 0;
++static char check_truncation = 0;
++static char use_nts = 0;
+ 
+ static void
+ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, const char *param_type, const char *value_to_convert)
+@@ -128,6 +143,10 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		ODBC_REPORT_ERROR("Row not expected");
+ 	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("Recordset not expected");
++	if (use_nts) {
++		out_len = SQL_NTS;
++		use_nts = 0;
++	}
+ 
+ 	/* create a table with a column of that type */
+ 	ResetStatement();
+@@ -208,20 +227,20 @@ AllTests(void)
+ 
+ 	/* FIXME why should return 38 0 as precision and scale ?? correct ?? */
+ 	precision = 18;
+-	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");
+-	Test("DECIMAL(18,2)", "123", SQL_C_NUMERIC, SQL_DECIMAL, "18 0 1 7B");
++	TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");
++	TestOutput("DECIMAL(18,2)", "123", SQL_C_NUMERIC, SQL_DECIMAL, "18 0 1 7B");
+ 	precision = 38;
+-	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
++	TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
+ 	TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");
+ 	/* MS driver behavior for output parameters is different */
+ 	if (driver_is_freetds())
+-		Test("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");
++		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");
+ 	else
+-		Test("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "313233");
++		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "313233");
+ 	/* FIXME our driver ignore precision for date */
+ 	precision = 3;
+-	Test("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
+-	Test("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP,
++	TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
++	TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP,
+ 	     big_endian ? "0000949700FB9640" : "979400004096FB00");
+ 	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34");
+ 
+@@ -271,6 +290,7 @@ AllTests(void)
+ 	TestInput(SQL_C_UTINYINT, "TINYINT", SQL_TINYINT, "TINYINT", "231");
+ 
+ 	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_NUMERIC, "NUMERIC(20,3)", "765432.2 -> 765432");
++	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_VARCHAR, "VARCHAR(20)", "578246.234 -> 578246");
+ 
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");
+@@ -284,13 +304,13 @@ AllTests(void)
+ 
+ 	precision = 6;
+ 	/* output from char with conversions */
+-	Test("VARCHAR(20)", "foo test", SQL_C_CHAR, SQL_VARCHAR, "6 foo te");
++	TestOutput("VARCHAR(20)", "foo test", SQL_C_CHAR, SQL_VARCHAR, "6 foo te");
+ 	/* TODO use collate in sintax if available */
+-	Test("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");
++	TestOutput("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");
+ 
+ 	/* TODO some Sybase versions */
+ 	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
+-		Test("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
++		TestOutput("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
+ 		/* test for invalid stream due to truncation*/
+@@ -305,16 +325,20 @@ AllTests(void)
+ 		TestInput(SQL_C_LONG, "INT", SQL_WVARCHAR, "NVARCHAR(100)", "45236");
+ 
+ 		precision = 6;
+-		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
++		TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
+ 		precision = 12;
+-		Test("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "8 foo test");
++		TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "8 foo test");
+ 		/* TODO use collate in sintax if available */
+-		Test("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");
++		TestOutput("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");
+ 
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest2");
++		use_nts = 1;
++		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest3");
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
+ 
++#ifdef ENABLE_DEVELOPING
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");
++#endif
+ 	}
+ }
+ 
+
+commit 9f418e96acf1612047c567b712faa928e71e7847
+Author: freddy77 <freddy77>
+Date:   Fri Oct 24 14:03:04 2008 +0000
+
+    make it works under windows
+
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index b3ff985..7c06fea 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.22 2008/10/23 08:02:45 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.23 2008/10/24 14:03:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -149,7 +149,9 @@ main(int argc, char *argv[])
+ 		/* nvarchar without extended characters */
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+ 		/* nvarchar with extended characters */
+-		Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_CHAR, "4 \x83hi\xf2");
++		/* don't test with MS which usually have a not compatible encoding */
++		if (driver_is_freetds())
++			Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_CHAR, "4 \x83hi\xf2");
+ 
+ 		Test("VARCHAR(20)", "test", SQL_C_WCHAR, "4 test");
+ 		/* nvarchar with extended characters */
+
+commit 539d7e332596c197d9aedea614e426d115502ea4
+Author: freddy77 <freddy77>
+Date:   Mon Oct 27 08:50:51 2008 +0000
+
+    remove warning
+
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 6de5f97..7c421b3 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -45,8 +45,6 @@ exit_forced(int s)
+ static void
+ sigalrm_handler(int s)
+ {
+-	SQLRETURN rcode;
+-
+ 	printf(">>>> SQLCancel() ...\n");
+ 	CHK(SQLCancel, (Statement));
+ 	printf(">>>> ... SQLCancel done\n");
+
+commit 28caef183fe708e23cf9aeb26f38e92b7c3d160d
+Author: freddy77 <freddy77>
+Date:   Mon Oct 27 14:23:22 2008 +0000
+
+    improve and fix test for SQLGetData and SQL_C_WCHAR
+
+diff --git a/ChangeLog b/ChangeLog
+index 42daf9a..102fd32 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Oct 27 15:21:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy src/odbc/odbc.c src/odbc/unittests/getdata.c:
++	- improve and fix test for SQLGetData and SQL_C_WCHAR
++	- small fix for odbc_prret
++
+ Fri Oct 24 10:27:54 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy: update
+ 	* src/odbc/sql2tds.c: fix SQL_NTS for SQL_C_WCHAR
+@@ -777,4 +782,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2638 2008/10/24 08:29:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2639 2008/10/27 14:23:22 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index bdb3a70..9180179 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -49,7 +49,7 @@ Check iso8859-1 for single ??
+ test to review
+ - data.c (char -> sql_c_char) DONE
+ - genparams.c
+-- getdata.c ??
++- getdata.c DONE
+ - putdata.c ??
+ - blob1.c (SQLGetData test with binary -> char and between chars)
+ Is it possible to support direct binding for parameters using different
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 1c9cfee..62a1a75 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.502 2008/10/17 08:56:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.503 2008/10/27 14:23:23 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -160,8 +160,8 @@ odbc_prret(SQLRETURN ret)
+ 	static char unknown[32];
+ 	
+ 	switch (ret) {
+-	case SQL_NULL_DATA:		return "SQL_ERROR or SQL_NULL_DATA";
+-	case SQL_DATA_AT_EXEC:		return "SQL_DATA_AT_EXEC or SQL_INVALID_HANDLE";
++	case SQL_ERROR:			return "SQL_ERROR";
++	case SQL_INVALID_HANDLE:	return "SQL_INVALID_HANDLE";
+ 	case SQL_SUCCESS:		return "SQL_SUCCESS";
+ 	case SQL_SUCCESS_WITH_INFO:	return "SQL_SUCCESS_WITH_INFO";
+ #if ODBCVER >= 0x0300
+@@ -4731,7 +4731,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		if (*pcbValue == SQL_NULL_DATA)
+ 			ODBC_RETURN(stmt, SQL_ERROR);
+ 		
+-		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_BINARY)) {
++		if (is_variable_type(colinfo->column_type) && (fCType == SQL_C_CHAR || fCType == SQL_C_WCHAR || fCType == SQL_C_BINARY)) {
+ 			/* avoid infinite SQL_SUCCESS on empty strings */
+ 			if (colinfo->column_text_sqlgetdatapos == 0 && cbValueMax > 0)
+ 				++colinfo->column_text_sqlgetdatapos;
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index f772605..d827e42 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,6 +1,7 @@
+ #include "common.h"
++#include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.7 2008/06/12 03:10:16 jklowden Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.8 2008/10/27 14:23:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -50,6 +51,28 @@ test_err(const char *data, int c_type, const char *state)
+ 	ResetStatement();
+ }
+ 
++static int lc;
++static int type;
++
++static int
++mycmp(const char *s1, const char *s2)
++{
++	SQLWCHAR buf[128], *wp;
++	unsigned l;
++
++	if (type == SQL_C_CHAR)
++		return strcmp(s1, s2);
++
++	l = strlen(s2);
++	assert(l < (sizeof(buf)/sizeof(buf[0])));
++	wp = buf;
++	do {
++		*wp++ = *s2;
++	} while (*s2++);
++
++	return memcmp(s1, buf, l * lc + lc);
++}
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -59,52 +82,63 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	/* TODO test with VARCHAR too */
+-	Command(Statement, "SELECT CONVERT(TEXT,'Prova')");
++	lc = 1;
++	type = SQL_C_CHAR;
+ 
+-	CHK(SQLFetch, (Statement));
++	for (;;) {
++		/* TODO test with VARCHAR too */
++		Command(Statement, "SELECT CONVERT(TEXT,'Prova')");
+ 
+-	/* these 2 tests test an old severe BUG in FreeTDS */
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("Unable to get data");
++		CHK(SQLFetch, (Statement));
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("Unable to get data");
++		/* these 2 tests test an old severe BUG in FreeTDS */
++		if (SQLGetData(Statement, 1, type, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
++			ODBC_REPORT_ERROR("Unable to get data");
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 3, NULL) != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("Unable to get data");
+-	if (strcmp(buf, "Pr") != 0) {
+-		printf("Wrong data result 1\n");
+-		exit(1);
+-	}
++		if (SQLGetData(Statement, 1, type, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
++			ODBC_REPORT_ERROR("Unable to get data");
+ 
+-	CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, buf, 16, NULL));
+-	if (strcmp(buf, "ova") != 0) {
+-		printf("Wrong data result 2 res = '%s'\n", buf);
+-		exit(1);
+-	}
++		if (SQLGetData(Statement, 1, type, buf, 3 * lc, NULL) != SQL_SUCCESS_WITH_INFO)
++			ODBC_REPORT_ERROR("Unable to get data");
++		if (mycmp(buf, "Pr") != 0) {
++			printf("Wrong data result 1\n");
++			exit(1);
++		}
+ 
+-	ResetStatement();
++		CHK(SQLGetData, (Statement, 1, type, buf, 16, NULL));
++		if (mycmp(buf, "ova") != 0) {
++			printf("Wrong data result 2 res = '%s'\n", buf);
++			exit(1);
++		}
+ 
+-	/* test with varchar, not blob but variable */
+-	Command(Statement, "SELECT CONVERT(VARCHAR(100), 'Other test')");
++		ResetStatement();
+ 
+-	CHK(SQLFetch, (Statement));
++		/* test with varchar, not blob but variable */
++		Command(Statement, "SELECT CONVERT(VARCHAR(100), 'Other test')");
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 7, NULL) != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("Unable to get data");
+-	if (strcmp(buf, "Other ") != 0) {
+-		printf("Wrong data result 1\n");
+-		exit(1);
+-	}
++		CHK(SQLFetch, (Statement));
+ 
+-	CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, buf, 16, NULL));
+-	if (strcmp(buf, "test") != 0) {
+-		printf("Wrong data result 2 res = '%s'\n", buf);
+-		exit(1);
+-	}
++		if (SQLGetData(Statement, 1, type, buf, 7 * lc, NULL) != SQL_SUCCESS_WITH_INFO)
++			ODBC_REPORT_ERROR("Unable to get data");
++		if (mycmp(buf, "Other ") != 0) {
++			printf("Wrong data result 1\n");
++			exit(1);
++		}
+ 
+-	ResetStatement();
++		CHK(SQLGetData, (Statement, 1, type, buf, 16, NULL));
++		if (mycmp(buf, "test") != 0) {
++			printf("Wrong data result 2 res = '%s'\n", buf);
++			exit(1);
++		}
++
++		ResetStatement();
++
++		if (type != SQL_C_CHAR)
++			break;
++
++		type = SQL_C_WCHAR;
++		lc = sizeof(SQLWCHAR);
++	}
+ 
+ 	/* test with fixed length */
+ 	Command(Statement, "SELECT CONVERT(INT, 12345)");
+@@ -144,21 +178,33 @@ main(int argc, char *argv[])
+ 	/* overflow */
+ 	test_err("1234567890123456789", SQL_C_LONG,      "22003");
+ 
++	/* test for empty string from mssql */
+ 	if (db_is_microsoft()) {
+-		Command(Statement, "SELECT CONVERT(TEXT,'')");
++		lc = 1;
++		type = SQL_C_CHAR;
+ 
+-		CHK(SQLFetch, (Statement));
++		for (;;) {
++			Command(Statement, "SELECT CONVERT(TEXT,'')");
+ 
+-		len = 1234;
+-		CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, buf, 1, &len));
++			CHK(SQLFetch, (Statement));
+ 
+-		if (len != 0) {
+-			fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
+-			return 1;
+-		}
++			len = 1234;
++			CHK(SQLGetData, (Statement, 1, type, buf, lc, &len));
++
++			if (len != 0) {
++				fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
++				return 1;
++			}
++
++			if (SQLGetData(Statement, 1, type, buf, lc, NULL) != SQL_NO_DATA)
++				ODBC_REPORT_ERROR("invalid return from SQLGetData");
++			ResetStatement();
+ 
+-		if (SQLGetData(Statement, 1, SQL_C_CHAR, buf, 1, NULL) != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("invalid return from SQLGetData");
++			if (type != SQL_C_CHAR)
++				break;
++			lc = sizeof(SQLWCHAR);
++			type = SQL_C_WCHAR;
++		}	
+ 	}
+ 
+ 	Disconnect();
+
+commit 2580348caf4d5253344f07fa97dbe161e04dacb8
+Author: freddy77 <freddy77>
+Date:   Mon Oct 27 14:27:01 2008 +0000
+
+    implement conversion from SQL_C_WCHAR to no char
+
+diff --git a/ChangeLog b/ChangeLog
+index 102fd32..795bcb3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Oct 27 15:25:06 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
++	- implement conversion from SQL_C_WCHAR to no char
++
+ Mon Oct 27 15:21:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy src/odbc/odbc.c src/odbc/unittests/getdata.c:
+ 	- improve and fix test for SQLGetData and SQL_C_WCHAR
+@@ -782,4 +786,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2639 2008/10/27 14:23:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2640 2008/10/27 14:27:01 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 56595ac..896f15e 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.77 2008/10/24 08:29:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.78 2008/10/27 14:27:01 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -126,6 +126,35 @@ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+ 	return sizeof(TDS_DATETIME);
+ }
+ 
++static char*
++odbc_wstr2str(TDS_STMT * stmt, const char *src, int* len)
++{
++	int srclen = (*len) / sizeof(SQLWCHAR);
++	char *out = (char *) malloc(srclen + 1), *p;
++	const SQLWCHAR *wp = (const SQLWCHAR *) src;
++
++	if (!out) {
++		odbc_errs_add(&stmt->errs, "HY001", NULL);
++		return NULL;
++	}
++
++        /* convert */
++        p = out;
++	for (; srclen && *wp < 256; --srclen)
++		*p++ = *wp++;
++
++	/* still characters, wrong format */
++	if (srclen) {
++		free(out);
++		/* TODO correct error ?? */
++		odbc_errs_add(&stmt->errs, "07006", NULL);
++		return NULL;
++	}
++
++	*len = p - out;
++	return out;
++}
++
+ /**
+  * Convert parameters to libtds format
+  * @return SQL_SUCCESS, SQL_ERROR or SQL_NEED_DATA
+@@ -138,7 +167,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 	int dest_type, src_type, sql_src_type, res;
+ 	CONV_RESULT ores;
+ 	TDSBLOB *blob;
+-	char *src;
++	char *src, *converted_src;
+ 	unsigned char *dest;
+ 	int len;
+ 	TDS_DATETIME dt;
+@@ -317,7 +346,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 	case XSYBNVARCHAR:
+ 	case XSYBNCHAR:
+ 	case SYBNVARCHAR:
+-		if (!need_data && is_char_type(src_type)) {
++		if (!need_data && (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR)) {
+ 			if (curcol->column_data && curcol->column_data_free)
+ 				curcol->column_data_free(curcol);
+ 			curcol->column_data_free = NULL;
+@@ -370,6 +399,14 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		/* TODO intervals */
+ 	}
+ 
++	converted_src = NULL;
++	if (sql_src_type == SQL_C_WCHAR) {
++		converted_src = src = odbc_wstr2str(stmt, src, &len);
++		if (!src)
++			return SQL_ERROR;
++		src_type = SYBVARCHAR;
++	}
++
+ 	dest = curcol->column_data;
+ 	switch ((TDS_SERVER_TYPE) dest_type) {
+ 	case SYBCHAR:
+@@ -396,6 +433,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 			res = curcol->column_size;
+ 		break;
+ 	case SYBTEXT:
++	case SYBNTEXT:
+ 	case SYBLONGBINARY:
+ 	case SYBIMAGE:
+ 		res = tds_convert(dbc->env->tds_ctx, src_type, src, len, dest_type, &ores);
+@@ -433,7 +471,6 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		res = tds_convert(dbc->env->tds_ctx, src_type, src, len, dest_type, (CONV_RESULT*) dest);
+ 		break;
+ 	default:
+-	case SYBNTEXT:
+ 	case SYBVOID:
+ 	case SYBVARIANT:
+ 		/* TODO ODBC 3.5 */
+@@ -442,6 +479,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		break;
+ 	}
+ 
++	free(converted_src);
+ 	if (res < 0) {
+ 		odbc_convert_err_set(&stmt->errs, res);
+ 		return SQL_ERROR;
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 15e91c9..0a32c39 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -7,18 +7,18 @@
+ /*
+  * This test is useful to test odbc_sql2tds function using TestInput
+  * odbc_sql2tds have some particular cases:
+- * (1) char    -> char     handled differently with encoding problems DONE
+- * (2) date    -> *        different format
+- * (3) numeric -> *        different format DONE
+- * (4) *       -> numeric  take precision and scale from ipd
++ * (1) char    -> char     handled differently with encoding problems
++ * (2) date    -> *        different format TODO
++ * (3) numeric -> *        different format
++ * (4) *       -> numeric  take precision and scale from ipd TODO
+  * (5) *       -> char     test wide
+- * (6) *       -> blob     test wchar and ntext
+- * (7) *       -> binary   test also with wchar
+- * (8) binary  -> *        test aldo with wchar
++ * (6) *       -> blob     test wchar and ntext TODO
++ * (7) *       -> binary   test also with wchar TODO
++ * (8) binary  -> *        test also with wchar TODO
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.34 2008/10/24 08:29:22 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.35 2008/10/27 14:27:01 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -336,9 +336,7 @@ AllTests(void)
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest3");
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
+ 
+-#ifdef ENABLE_DEVELOPING
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");
+-#endif
+ 	}
+ }
+ 
+
+commit 01373c68762cab0b09f72ea2901779821f5ade43
+Author: freddy77 <freddy77>
+Date:   Tue Oct 28 12:50:57 2008 +0000
+
+    relax libTDS check
+
+diff --git a/ChangeLog b/ChangeLog
+index 795bcb3..0d3174b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Oct 28 13:50:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/tds_checks.c: relax libTDS check
++
+ Mon Oct 27 15:25:06 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
+ 	- implement conversion from SQL_C_WCHAR to no char
+@@ -786,4 +789,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2640 2008/10/27 14:27:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2641 2008/10/28 12:50:57 freddy77 Exp $
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index 0c2f6c8..2ba07fa 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.20 2007/06/21 07:21:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.21 2008/10/28 12:50:57 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -232,7 +232,7 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 		assert(column->column_size == column->on_server.column_size);
+ 	} else {
+ 		assert(!is_fixed_type(column->column_type));
+-		assert(column->char_conv || (column->on_server.column_size == column->column_size || column->on_server.column_size == 0));
++		assert(is_char_type(column->column_type) || (column->on_server.column_size == column->column_size || column->on_server.column_size == 0));
+ 		assert(column->column_varint_size != 0);
+ 	}
+ 
+
+commit 505d3d2dffd10593f26c33ce123992ddb86bd151
+Author: freddy77 <freddy77>
+Date:   Wed Oct 29 08:42:37 2008 +0000
+
+    fix small memory read overflow
+
+diff --git a/ChangeLog b/ChangeLog
+index 0d3174b..85facd3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Oct 29 09:41:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: fix small memory read overflow
++
+ Tue Oct 28 13:50:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/tds_checks.c: relax libTDS check
+ 
+@@ -789,4 +792,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2641 2008/10/28 12:50:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2642 2008/10/29 08:42:37 freddy77 Exp $
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 89b4e32..c589476 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.184 2008/09/17 12:16:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.185 2008/10/29 08:42:38 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -3002,7 +3002,7 @@ string_to_int(const char *buf, const char *pend, TDS_INT * res)
+ 	for (; p != pend; ++p) {
+ 		/* check for trailing spaces */
+ 		if (*p == blank) {
+-			while (p != pend && *++p == blank);
++			while (++p != pend && *p == blank);
+ 			if (p != pend)
+ 				return TDS_CONVERT_SYNTAX;
+ 			break;
+
+commit 350b3905b38b20faa1edba16449eb0efa15442ac
+Author: freddy77 <freddy77>
+Date:   Wed Oct 29 09:33:50 2008 +0000
+
+    new functions to read and check db version
+
+diff --git a/ChangeLog b/ChangeLog
+index 85facd3..207552e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Wed Oct 29 10:31:08 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/data.c:
++	* src/odbc/unittests/genparams.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/utf8.c src/odbc/unittests/utf8_2.c:
++	- new function to read and check db version
++
+ Wed Oct 29 09:41:42 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/convert.c: fix small memory read overflow
+ 
+@@ -792,4 +799,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2642 2008/10/29 08:42:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2643 2008/10/29 09:33:50 freddy77 Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 82215d5..f9ae4bf 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.46 2008/09/09 14:48:04 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.47 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -308,6 +308,30 @@ driver_is_freetds(void)
+ 	return freetds_driver;
+ }
+ 
++static char db_str_version[32];
++
++const char *db_version(void)
++{
++	SQLSMALLINT version_len;
++
++	if (!db_str_version[0])
++		CHK(SQLGetInfo, (Connection, SQL_DBMS_VER, db_str_version, sizeof(db_str_version), &version_len));
++
++	return db_str_version;
++}
++
++unsigned int db_version_int(void)
++{
++	unsigned int h, l;
++	if (sscanf(db_version(), "%u.%u.", &h, &l) != 2) {
++		fprintf(stderr, "Wrong db version: %s\n", db_version());
++		Disconnect();
++		exit(1);
++	}
++
++	return (h << 24) | ((l & 0xFFu) << 16);
++}
++
+ void
+ CheckCols(int n, int line, const char * file)
+ {
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 5e89ddf..bf4c174 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.23 2008/03/12 13:35:50 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.24 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -68,6 +68,8 @@ int Disconnect(void);
+ void Command(HSTMT stmt, const char *command);
+ SQLRETURN CommandWithResult(HSTMT stmt, const char *command);
+ int db_is_microsoft(void);
++const char *db_version(void);
++unsigned int db_version_int(void);
+ int driver_is_freetds(void);
+ 
+ #define int2ptr(i) ((void*)(((char*)0)+(i)))
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index 28e4609..39dc6dd 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.13 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.14 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHK_INFO(func,params) \
+@@ -195,13 +195,9 @@ Test(int use_sql)
+ int
+ main(int argc, char *argv[])
+ {
+-	char version[32];
+-	SQLSMALLINT version_len;
+-
+ 	Connect();
+ 
+-	SQLGetInfo(Connection, SQL_DBMS_VER, version, sizeof(version), &version_len);
+-	if (db_is_microsoft() && strncmp(version, "09.00.", 6) == 0)
++	if (db_is_microsoft() && db_version_int() >= 0x09000000u)
+ 		mssql2005 = 1;
+ 
+ 	Test(1);
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 7c06fea..8915107 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.23 2008/10/24 14:03:04 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.24 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -97,15 +97,11 @@ int
+ main(int argc, char *argv[])
+ {
+ 	int big_endian = 1;
+-	char version[32];
+-	SQLSMALLINT version_len;
+ 
+ 	Connect();
+ 
+ 	if (((char *) &big_endian)[0] == 1)
+ 		big_endian = 0;
+-	memset(version, 0, sizeof(version));
+-	SQLGetInfo(Connection, SQL_DBMS_VER, version, sizeof(version), &version_len);
+ 
+ 	Test("NUMERIC(18,2)", "123", SQL_C_NUMERIC, "38 0 1 7B");
+ 
+@@ -130,8 +126,8 @@ main(int argc, char *argv[])
+ 	Test("TINYINT", "231", SQL_C_BINARY, "E7");
+ 	Test("SMALLINT", "4321", SQL_C_BINARY, big_endian ? "10E1" : "E110");
+ 	Test("INT", "1234567", SQL_C_BINARY, big_endian ? "0012D687" : "87D61200");
+-	if ((db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0))
+-	    || (!db_is_microsoft() && strncmp(version, "15.00.", 6) >= 0)) {
++	if ((db_is_microsoft() && db_version_int() >= 0x08000000u)
++	    || (!db_is_microsoft() && strncmp(db_version(), "15.00.", 6) >= 0)) {
+ 		int old_result = result;
+ 
+ 		Test("BIGINT", "123456789012345", SQL_C_BINARY, big_endian ? "00007048860DDF79" : "79DF0D8648700000");
+@@ -145,7 +141,7 @@ main(int argc, char *argv[])
+ 	Test("INT", "-123", SQL_C_CHAR, "4 -123");
+ 	Test("INT", "78654", SQL_C_WCHAR, "5 78654");
+ 	Test("VARCHAR(10)", "  51245  ", SQL_C_LONG, "51245");
+-	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
++	if (db_is_microsoft() && (strncmp(db_version(), "08.00.", 6) == 0 || strncmp(db_version(), "09.00.", 6) == 0)) {
+ 		/* nvarchar without extended characters */
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+ 		/* nvarchar with extended characters */
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 0a32c39..7f8c9b6 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.35 2008/10/27 14:27:01 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.36 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -211,7 +211,6 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ }
+ 
+ static int big_endian = 1;
+-static char version[32];
+ 
+ static void
+ AllTests(void)
+@@ -309,7 +308,7 @@ AllTests(void)
+ 	TestOutput("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");
+ 
+ 	/* TODO some Sybase versions */
+-	if (db_is_microsoft() && (strncmp(version, "08.00.", 6) == 0 || strncmp(version, "09.00.", 6) == 0)) {
++	if (db_is_microsoft() && db_version_int() >= 0x08000000u) {
+ 		TestOutput("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
+@@ -343,14 +342,9 @@ AllTests(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	SQLSMALLINT version_len;
+-
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	memset(version, 0, sizeof(version));
+-	SQLGetInfo(Connection, SQL_DBMS_VER, version, sizeof(version), &version_len);
+-
+ 	if (((char *) &big_endian)[0] == 1)
+ 		big_endian = 0;
+ 
+diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c
+index 671ef79..0f90c55 100644
+--- a/src/odbc/unittests/tables.c
++++ b/src/odbc/unittests/tables.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: tables.c,v 1.14 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: tables.c,v 1.15 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef WIN32
+@@ -149,16 +149,13 @@ DoTest(const char *type, int row_returned)
+ int
+ main(int argc, char *argv[])
+ {
+-	char version[32];
+ 	char type[32];
+-	SQLSMALLINT version_len;
+ 	int mssql2005 = 0;
+ 
+ 	use_odbc_version3 = 0;
+ 	Connect();
+ 
+-	SQLGetInfo(Connection, SQL_DBMS_VER, version, sizeof(version), &version_len);
+-	if (db_is_microsoft() && strncmp(version, "09.00.", 6) == 0) {
++	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
+ 		mssql2005 = 1;
+ 		strcpy(expected_type, "VIEW");
+ 		CommandWithResult(Statement, "USE master");
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index c353021..8b9a0f1 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.4 2008/09/08 19:22:44 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.5 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -141,9 +141,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-        memset(tmp, 0, sizeof(tmp));
+-        SQLGetInfo(Connection, SQL_DBMS_VER, tmp, sizeof(tmp), &len);
+-	if (!db_is_microsoft() || (strncmp(tmp, "08.00.", 6) != 0 && strncmp(tmp, "09.00.", 6) != 0)) {
++	if (!db_is_microsoft() || db_version_int() >= 0x08000000u) {
+ 		Disconnect();
+ 		printf("Test for MSSQL only\n");
+ 		return 0;
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index 756445f..a275d07 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.2 2008/10/15 14:53:00 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.3 2008/10/29 09:33:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -67,9 +67,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	memset(tmp, 0, sizeof(tmp));
+-	SQLGetInfo(Connection, SQL_DBMS_VER, tmp, sizeof(tmp), &len);
+-	if (!db_is_microsoft() || (strncmp(tmp, "08.00.", 6) != 0 && strncmp(tmp, "09.00.", 6) != 0)) {
++	if (!db_is_microsoft() || db_version_int() >= 0x08000000u) {
+ 		Disconnect();
+ 		printf("Test for MSSQL only\n");
+ 		return 0;
+
+commit 38916fd46e44aae1dd6ad4f9be5041c6e80aeef2
+Author: freddy77 <freddy77>
+Date:   Wed Oct 29 09:56:53 2008 +0000
+
+    improve test for wide charaters
+
+diff --git a/ChangeLog b/ChangeLog
+index 207552e..49bc2f5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Oct 29 10:54:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/putdata.c: improve test for wide charaters
++
+ Wed Oct 29 10:31:08 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
+ 	* src/odbc/unittests/cursor1.c src/odbc/unittests/data.c:
+@@ -799,4 +802,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2643 2008/10/29 09:33:50 freddy77 Exp $
++$Id: ChangeLog,v 1.2644 2008/10/29 09:56:53 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index 9180179..e8d8869 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -50,7 +50,7 @@ test to review
+ - data.c (char -> sql_c_char) DONE
+ - genparams.c
+ - getdata.c DONE
+-- putdata.c ??
++- putdata.c DONE
+ - blob1.c (SQLGetData test with binary -> char and between chars)
+ Is it possible to support direct binding for parameters using different
+ encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index 3eff23f..254ac2e 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.11 2008/02/08 09:28:04 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.12 2008/10/29 09:56:53 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -19,47 +19,72 @@ main(int argc, char *argv[])
+ 	SQLPOINTER ptr;
+ 	unsigned char buf[256], *pb;
+ 	SQLRETURN retcode;
++	int type, lc, sql_type;
+ 
+ 	Connect();
+ 
+ 	/* create table to hold data */
+ 	Command(Statement, "CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (SQLPOINTER) 123, 0, &ind));
+-	/* length required */
+-	ind = SQL_LEN_DATA_AT_EXEC(len);
+-
+-	/* 
+-	 * test for char 
+-	 */
++	sql_type = SQL_LONGVARCHAR;
++	type = SQL_C_CHAR;
++	lc = 1;
++	for (;;) {
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind));
++		/* length required */
++		ind = SQL_LEN_DATA_AT_EXEC(len * lc);
++
++		/* 
++		 * test for char 
++		 */
++
++		CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
++
++		if (SQLExecute(Statement) != SQL_NEED_DATA)
++			ODBC_REPORT_ERROR("Wrong result executing statement");
++
++		p = test_text;
++		n = 5;
++		if (SQLParamData(Statement, &ptr) != SQL_NEED_DATA)
++			ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++		if (ptr != (SQLPOINTER) 123)
++			ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
++		while (*p) {
++			int l = strlen(p);
++
++			if (l < n)
++				n = l;
++			if (type == SQL_C_CHAR) {
++				CHK(SQLPutData, (Statement, (char *) p, n));
++			} else {
++				SQLWCHAR buf[256];
++				int i;
++				for (i = 0; i < n; ++i)
++					buf[i] = p[i];
++				CHK(SQLPutData, (Statement, (char *) buf, n * lc));
++			}
++			p += n;
++			n *= 2;
++		}
++		CHK(SQLParamData, (Statement, &ptr));
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
++		if (SQLParamData(Statement, &ptr) != SQL_ERROR)
++			ODBC_REPORT_ERROR("Wrong result from SQLParamData");
+ 
+-	if (SQLExecute(Statement) != SQL_NEED_DATA)
+-		ODBC_REPORT_ERROR("Wrong result executing statement");
++		/* check state  and reset some possible buffers */
++		Command(Statement, "DECLARE @i INT");
+ 
+-	p = test_text;
+-	n = 5;
+-	if (SQLParamData(Statement, &ptr) != SQL_NEED_DATA)
+-		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
+-	if (ptr != (SQLPOINTER) 123)
+-		ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
+-	while (*p) {
+-		int l = strlen(p);
++		if (sql_type == SQL_LONGVARCHAR && db_is_microsoft() && db_version_int() >= 0x08000000u) {
++			sql_type = SQL_WLONGVARCHAR;
++			continue;
++		}
+ 
+-		if (l < n)
+-			n = l;
+-		CHK(SQLPutData, (Statement, (char *) p, n));
+-		p += n;
+-		n *= 2;
++		if (type != SQL_C_CHAR)
++			break;
++		sql_type = SQL_LONGVARCHAR;
++		type = SQL_C_WCHAR;
++		lc = sizeof(SQLWCHAR);
+ 	}
+-	CHK(SQLParamData, (Statement, &ptr));
+-
+-	if (SQLParamData(Statement, &ptr) != SQL_ERROR)
+-		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
+-
+-	/* check state  and reset some possible buffers */
+-	Command(Statement, "DECLARE @i INT");
+ 
+ 	/* update row setting binary field */
+ 	for (i = 0; i < 255; ++i)
+@@ -104,21 +129,28 @@ main(int argc, char *argv[])
+ 	/* test len == 0 case from ML */
+ 	CHK(SQLFreeStmt, (Statement, SQL_RESET_PARAMS));
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
++	type = SQL_C_CHAR;
++	for (;;) {
++		CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind));
++		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind));
+ 
+-	ind = SQL_LEN_DATA_AT_EXEC(0);
++		ind = SQL_LEN_DATA_AT_EXEC(0);
+ 
+-	if ((retcode = SQLExecute(Statement)) != SQL_NEED_DATA) {
+-		printf("Wrong result executing statement (retcode=%d)\n", (int) retcode);
+-		exit(1);
+-	}
+-	while (retcode == SQL_NEED_DATA) {
+-		retcode = SQLParamData(Statement, &ptr);
+-		if (retcode == SQL_NEED_DATA) {
+-			SQLPutData(Statement, "abc", 3);
++		if ((retcode = SQLExecute(Statement)) != SQL_NEED_DATA) {
++			printf("Wrong result executing statement (retcode=%d)\n", (int) retcode);
++			exit(1);
++		}
++		while (retcode == SQL_NEED_DATA) {
++			retcode = SQLParamData(Statement, &ptr);
++			if (retcode == SQL_NEED_DATA) {
++				SQLPutData(Statement, "abc", 3);
++			}
+ 		}
++		if (type != SQL_C_CHAR)
++			break;
++		type = SQL_C_WCHAR;
++		ResetStatement();
+ 	}
+ 
+ 	/* TODO check inserts ... */
+
+commit 48b72f3c96b8caf9c2222b2d90d288596d161af9
+Author: freddy77 <freddy77>
+Date:   Fri Oct 31 14:00:11 2008 +0000
+
+    minor tests issues
+
+diff --git a/ChangeLog b/ChangeLog
+index 49bc2f5..2df6022 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Oct 31 14:59:36 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/utf8.c src/odbc/unittests/utf8_2.c:
++	- fix test for MSSQL
++	* src/odbc/unittests/common.c src/odbc/unittests/cursor1.c:
++	- reuse code
++
+ Wed Oct 29 10:54:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/putdata.c: improve test for wide charaters
+ 
+@@ -802,4 +808,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2644 2008/10/29 09:56:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2645 2008/10/31 14:00:11 freddy77 Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index f9ae4bf..00f2af3 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.47 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.48 2008/10/31 14:00:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -185,19 +185,12 @@ Connect(void)
+ 	if (read_login_info())
+ 		exit(1);
+ 
+-	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		printf("Unable to allocate env\n");
+-		exit(1);
+-	}
++	CHK(SQLAllocEnv, (&Environment));
+ 
+ 	if (use_odbc_version3)
+ 		SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+ 
+-	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		printf("Unable to allocate connection\n");
+-		SQLFreeEnv(Environment);
+-		exit(1);
+-	}
++	CHK(SQLAllocConnect, (Environment, &Connection));
+ 	printf("odbctest\n--------\n\n");
+ 	printf("connection parameters:\nserver:   '%s'\nuser:     '%s'\npassword: '%s'\ndatabase: '%s'\n",
+ 	       SERVER, USER, "????" /* PASSWORD */ , DATABASE);
+@@ -211,10 +204,7 @@ Connect(void)
+ 		CheckReturn();
+ 	}
+ 
+-	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS) {
+-		printf("Unable to allocate statement\n");
+-		CheckReturn();
+-	}
++	CHK(SQLAllocStmt, (Connection, &Statement));
+ 
+ 	sprintf(command, "use %s", DATABASE);
+ 	printf("%s\n", command);
+@@ -379,8 +369,7 @@ ResetStatement(void)
+ {
+ 	SQLFreeStmt(Statement, SQL_DROP);
+ 	Statement = SQL_NULL_HSTMT;
+-	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS)
+-		ODBC_REPORT_ERROR("Unable to allocate statement");
++	CHK(SQLAllocStmt, (Connection, &Statement));
+ }
+ 
+ void
+@@ -393,9 +382,7 @@ CheckCursor(void)
+ 		char output[256];
+ 		unsigned char sqlstate[6];
+ 
+-		retcode = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL);
+-		if (retcode != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("SQLGetDiagRec");
++		CHK(SQLGetDiagRec, (SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL));
+ 		sqlstate[5] = 0;
+ 		if (strcmp((const char*) sqlstate, "01S02") == 0) {
+ 			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index 39dc6dd..59d8ecd 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.14 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.15 2008/10/31 14:00:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHK_INFO(func,params) \
+@@ -68,20 +68,7 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 
+ 	/* set cursor options */
+ 	ResetStatement();
+-	retcode = SQLSetStmtAttr(Statement, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
+-	if (retcode != SQL_SUCCESS) {
+-		char output[256];
+-		unsigned char sqlstate[6];
+-
+-		CHK(SQLGetDiagRec, (SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL));
+-		sqlstate[5] = 0;
+-		if (strcmp((const char*) sqlstate, "01S02") == 0) {
+-			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+-			Disconnect();
+-			exit(0);
+-		}
+-		ODBC_REPORT_ERROR("SQLSetStmtAttr");
+-	}
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0));
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0));
+ 	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0));
+@@ -196,6 +183,7 @@ int
+ main(int argc, char *argv[])
+ {
+ 	Connect();
++	CheckCursor();
+ 
+ 	if (db_is_microsoft() && db_version_int() >= 0x09000000u)
+ 		mssql2005 = 1;
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 8b9a0f1..2eb02b7 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.5 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.6 2008/10/31 14:00:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -141,7 +141,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	if (!db_is_microsoft() || db_version_int() >= 0x08000000u) {
++	if (!db_is_microsoft() || db_version_int() < 0x08000000u) {
+ 		Disconnect();
+ 		printf("Test for MSSQL only\n");
+ 		return 0;
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index a275d07..1c7071e 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.3 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.4 2008/10/31 14:00:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -67,7 +67,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	if (!db_is_microsoft() || db_version_int() >= 0x08000000u) {
++	if (!db_is_microsoft() || db_version_int() < 0x08000000u) {
+ 		Disconnect();
+ 		printf("Test for MSSQL only\n");
+ 		return 0;
+
+commit 01f31f6ccbd7fa13e29e37fa2a112ed3afe81639
+Author: freddy77 <freddy77>
+Date:   Fri Oct 31 14:35:23 2008 +0000
+
+    style updates, reuse macros
+
+diff --git a/ChangeLog b/ChangeLog
+index 2df6022..4045ec0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Oct 31 15:35:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor5.c:
++	* src/odbc/unittests/utf8.c src/odbc/unittests/utf8_2.c:
++	- style updates, reuse macros
++
+ Fri Oct 31 14:59:36 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/utf8.c src/odbc/unittests/utf8_2.c:
+ 	- fix test for MSSQL
+@@ -808,4 +813,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2645 2008/10/31 14:00:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2646 2008/10/31 14:35:23 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index 59d8ecd..1882457 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.15 2008/10/31 14:00:11 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.16 2008/10/31 14:35:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHK_INFO(func,params) \
+@@ -10,7 +10,7 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 		ODBC_REPORT_ERROR(#func); \
+ 	} while(0)
+ 
+-#define SWAP_STMT(a,b) do { SQLHSTMT xyz = a; a = b; b = xyz; } while(0)
++#define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
+ 
+ static int mssql2005 = 0;
+ 
+@@ -102,10 +102,10 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 			else
+ 				CHK(SQLSetPos, (Statement, i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE));
+ 			if (use_sql) {
+-				SWAP_STMT(Statement, stmt2);
++				SWAP_STMT(stmt2);
+ 				CHK(SQLPrepare, (Statement, (SQLCHAR *) "DELETE FROM #test WHERE CURRENT OF C1", SQL_NTS));
+ 				CHK(SQLExecute, (Statement));
+-				SWAP_STMT(Statement, stmt2);
++				SWAP_STMT(stmt2);
+ 			}
+ 		}
+ 
+@@ -134,14 +134,14 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 				}
+ 			}
+ 			if (use_sql) {
+-				SWAP_STMT(Statement, stmt2);
++				SWAP_STMT(stmt2);
+ 				CHK(SQLPrepare, (Statement, (SQLCHAR *) "UPDATE #test SET c=? WHERE CURRENT OF C1", SQL_NTS));
+ 				CHK(SQLBindParameter,
+ 				    (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL));
+ 				CHK(SQLExecute, (Statement));
+ 				/* FIXME this is not necessary for mssql driver */
+ 				SQLMoreResults(Statement);
+-				SWAP_STMT(Statement, stmt2);
++				SWAP_STMT(stmt2);
+ 			}
+ 		}
+ 	}
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index 9b300f5..4797287 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.5 2008/02/06 08:28:10 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.6 2008/10/31 14:35:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -41,11 +41,11 @@ getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+ }
+ 
+ static void
+-doFetch(SQLHSTMT m_hstmt, int dir, int pos)
++doFetch(int dir, int pos)
+ {
+-	SQLRETURN rcode = SQLFetchScroll(m_hstmt, dir, pos);
++	SQLRETURN rcode = SQLFetchScroll(Statement, dir, pos);
+ 
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLFetchScroll");
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLFetchScroll");
+ 	if (rcode != SQL_NO_DATA)
+ 		printf(">> fetch %2d %10d : %d [%s]\n", dir, pos, v_ind_3_1 ? (int) v_int_3 : -1, v_ind_3_2 ? v_char_3 : "null");
+ 	else
+@@ -56,78 +56,49 @@ int
+ main(int argc, char **argv)
+ {
+ 	SQLRETURN rcode;
+-	SQLHSTMT m_hstmt1;
+-	SQLHSTMT m_hstmt2;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 	CheckCursor();
+ 
+-	rcode = SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_ENV, Connection, "SQLSetConnectAttr(autocommit)");
+-
+-	m_hstmt1 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH 1");
+-
+-	m_hstmt2 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle StmtH 2");
+-
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "create table #mytab1 (k int, c char(30))", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.1");
+-
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (1,'aaa')", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.2");
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (2,'bbb')", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.3");
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "insert into #mytab1 values (3,'ccc')", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 1.4");
+-
+-/*
+-	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0);
+-	CHECK_RCODE(SQL_HANDLE_STMT,m_hstmt2,"SQLSetStmtAttr 1");
+-*/
+-
+-	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLSetStmtAttr 1");
+-
+-	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "select k, c from #mytab1 order by k", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLPrepare 3");
+-
+-	rcode = SQLBindCol(m_hstmt2, 1, SQL_C_LONG, &v_int_3, 0, &v_ind_3_1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLBindCol 3.1");
+-
+-	rcode = SQLBindCol(m_hstmt2, 2, SQL_C_CHAR, v_char_3, sizeof(v_char_3), &v_ind_3_2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLBindCol 3.2");
+-
+-	rcode = SQLExecute(m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLExecute StmtH 3");
+-
+-	doFetch(m_hstmt2, SQL_FETCH_LAST, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_PRIOR, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_PRIOR, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_PRIOR, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_NEXT, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_NEXT, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_NEXT, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_NEXT, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_FIRST, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_NEXT, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_NEXT, 0);
+-	doFetch(m_hstmt2, SQL_FETCH_ABSOLUTE, 3);
+-	doFetch(m_hstmt2, SQL_FETCH_RELATIVE, -2);
+-	doFetch(m_hstmt2, SQL_FETCH_RELATIVE, -2);
+-	doFetch(m_hstmt2, SQL_FETCH_RELATIVE, 5);
+-
+-	rcode = SQLCloseCursor(m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLCloseCursor StmtH 2");
+-
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle StmtH 1");
+-
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLFreeHandle StmtH 2");
++	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER));
++
++	Command(Statement, "create table #mytab1 (k int, c char(30))");
++	Command(Statement, "insert into #mytab1 values (1,'aaa')");
++	Command(Statement, "insert into #mytab1 values (2,'bbb')");
++	Command(Statement, "insert into #mytab1 values (3,'ccc')");
++
++	ResetStatement();
++/*	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0));	*/
++	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER));
++
++	rcode = SQLPrepare(Statement, (SQLCHAR *) "select k, c from #mytab1 order by k", SQL_NTS);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLPrepare 3");
++
++	CHK(SQLBindCol, (Statement, 1, SQL_C_LONG, &v_int_3, 0, &v_ind_3_1));
++	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, v_char_3, sizeof(v_char_3), &v_ind_3_2));
++
++	rcode = SQLExecute(Statement);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLExecute StmtH 3");
++
++	doFetch(SQL_FETCH_LAST, 0);
++	doFetch(SQL_FETCH_PRIOR, 0);
++	doFetch(SQL_FETCH_PRIOR, 0);
++	doFetch(SQL_FETCH_PRIOR, 0);
++	doFetch(SQL_FETCH_NEXT, 0);
++	doFetch(SQL_FETCH_NEXT, 0);
++	doFetch(SQL_FETCH_NEXT, 0);
++	doFetch(SQL_FETCH_NEXT, 0);
++	doFetch(SQL_FETCH_FIRST, 0);
++	doFetch(SQL_FETCH_NEXT, 0);
++	doFetch(SQL_FETCH_NEXT, 0);
++	doFetch(SQL_FETCH_ABSOLUTE, 3);
++	doFetch(SQL_FETCH_RELATIVE, -2);
++	doFetch(SQL_FETCH_RELATIVE, -2);
++	doFetch(SQL_FETCH_RELATIVE, 5);
++
++	rcode = SQLCloseCursor(Statement);
++	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLCloseCursor StmtH 2");
+ 
+ 	Disconnect();
+ 	return 0;
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 2eb02b7..31f57d6 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.6 2008/10/31 14:00:11 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.7 2008/10/31 14:35:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,16 +9,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		printf("Unable to allocate env\n");
+-		exit(1);
+-	}
++	CHK(SQLAllocEnv, (&Environment));
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		printf("Unable to allocate connection\n");
+-		SQLFreeEnv(Environment);
+-		exit(1);
+-	}
++	CHK(SQLAllocConnect, (Environment, &Connection));
+ }
+ 
+ static void
+@@ -147,10 +140,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS) {
+-		printf("Unable to allocate statement\n");
+-		CheckReturn();
+-	}
++	CHK(SQLAllocStmt, (Connection, &Statement));
+ 
+ 	/* create test table */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index 1c7071e..7203a40 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.4 2008/10/31 14:00:11 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.5 2008/10/31 14:35:23 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,16 +9,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		printf("Unable to allocate env\n");
+-		exit(1);
+-	}
++	CHK(SQLAllocEnv, (&Environment));
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		printf("Unable to allocate connection\n");
+-		SQLFreeEnv(Environment);
+-		exit(1);
+-	}
++	CHK(SQLAllocConnect, (Environment, &Connection));
+ }
+ 
+ static const char * const strings[] = {
+@@ -73,10 +66,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	if (SQLAllocStmt(Connection, &Statement) != SQL_SUCCESS) {
+-		printf("Unable to allocate statement\n");
+-		CheckReturn();
+-	}
++	CHK(SQLAllocStmt, (Connection, &Statement));
+ 
+ 	/* create test table */
+ 	Command(Statement, "CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
+
+commit e60e2d4bc01c0a6dfc410f7659b2ec5362aa42a1
+Author: freddy77 <freddy77>
+Date:   Tue Nov 4 10:59:02 2008 +0000
+
+    introduced new CHK* macros and use them
+
+diff --git a/ChangeLog b/ChangeLog
+index 4045ec0..3df21ec 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,38 @@
++Tue Nov 04 11:56:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array_out.c src/odbc/unittests/binary_test.c:
++	* src/odbc/unittests/blob1.c src/odbc/unittests/cancel.c:
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/compute.c src/odbc/unittests/connect.c:
++	* src/odbc/unittests/connect2.c src/odbc/unittests/const_params.c:
++	* src/odbc/unittests/convert_error.c src/odbc/unittests/copydesc.c:
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
++	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
++	* src/odbc/unittests/cursor5.c src/odbc/unittests/cursor6.c:
++	* src/odbc/unittests/cursor7.c src/odbc/unittests/data.c:
++	* src/odbc/unittests/date.c src/odbc/unittests/describecol.c:
++	* src/odbc/unittests/error.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/funccall.c src/odbc/unittests/genparams.c:
++	* src/odbc/unittests/getdata.c src/odbc/unittests/hidden.c:
++	* src/odbc/unittests/insert_speed.c src/odbc/unittests/lang_error.c:
++	* src/odbc/unittests/moreandcount.c src/odbc/unittests/norowset.c:
++	* src/odbc/unittests/paramcore.c src/odbc/unittests/params.c:
++	* src/odbc/unittests/prepare_results.c src/odbc/unittests/prepclose.c:
++	* src/odbc/unittests/preperror.c src/odbc/unittests/print.c:
++	* src/odbc/unittests/putdata.c src/odbc/unittests/raiserror.c:
++	* src/odbc/unittests/rebindpar.c src/odbc/unittests/rownumber.c:
++	* src/odbc/unittests/rowset.c src/odbc/unittests/rpc.c:
++	* src/odbc/unittests/scroll.c src/odbc/unittests/t0001.c:
++	* src/odbc/unittests/t0002.c src/odbc/unittests/t0003.c:
++	* src/odbc/unittests/t0004.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/test64.c src/odbc/unittests/testodbc.c:
++	* src/odbc/unittests/timeout.c src/odbc/unittests/timeout2.c:
++	* src/odbc/unittests/timeout3.c src/odbc/unittests/timeout4.c:
++	* src/odbc/unittests/transaction.c src/odbc/unittests/transaction2.c:
++	* src/odbc/unittests/typeinfo.c src/odbc/unittests/utf8.c:
++	* src/odbc/unittests/utf8_2.c src/odbc/unittests/warning.c:
++	* src/odbc/unittests/wchar.c:
++	- introduced new CHK* macros and use them
++
+ Fri Oct 31 15:35:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor5.c:
+ 	* src/odbc/unittests/utf8.c src/odbc/unittests/utf8_2.c:
+@@ -813,4 +848,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2646 2008/10/31 14:35:23 freddy77 Exp $
++$Id: ChangeLog,v 1.2647 2008/11/04 10:59:02 freddy77 Exp $
+diff --git a/src/odbc/unittests/array_out.c b/src/odbc/unittests/array_out.c
+index 1bbb852..5117d65 100644
+--- a/src/odbc/unittests/array_out.c
++++ b/src/odbc/unittests/array_out.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array_out.c,v 1.12 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: array_out.c,v 1.13 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -74,7 +74,7 @@ query_test(SQLRETURN expected, const char *expected_status)
+ 	SQLBindCol(Statement, 1, SQL_C_ULONG, &IDS(0), 0, &ID_LENS(0));
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, DESCS(0), desc_len, &DESC_LENS(0));
+ 
+-	CHK(SQLExecDirect, (Statement, (SQLCHAR *) test_query, SQL_NTS));
++	CHKExecDirect((SQLCHAR *) test_query, SQL_NTS, "S");
+ 
+ 	ret = SQLFetch(Statement);
+ 	if (ret != expected)
+diff --git a/src/odbc/unittests/binary_test.c b/src/odbc/unittests/binary_test.c
+index ddb4911..f32e0b9 100644
+--- a/src/odbc/unittests/binary_test.c
++++ b/src/odbc/unittests/binary_test.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: binary_test.c,v 1.6 2007/10/16 15:12:22 freddy77 Exp $";
++static char software_version[] = "$Id: binary_test.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define ERR_BUF_SIZE 256
+@@ -24,38 +24,12 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ #define TEST_BUF_LEN (1024*128)
+ 
+ 
+-static SQLRETURN err;
+ static unsigned char *buf;
+ 
+-static int
+-sqlreturn_noerr(SQLRETURN rv)
+-{
+-	return (rv == SQL_SUCCESS || rv == SQL_SUCCESS_WITH_INFO || rv == SQL_NO_DATA || rv == SQL_NEED_DATA);
+-}
+-
+-/* return pointer to ODBC error string: caller owns storage */
+-static const char *
+-get_odbc_error(SQLHSTMT stmt_handle)
+-{
+-	SQLCHAR *error_buf = (SQLCHAR *) malloc(ERR_BUF_SIZE + 1);
+-	SQLCHAR sql_state[100];
+-	SQLINTEGER native_error;
+-	SQLSMALLINT len;
+-
+-	err = SQLError(Environment, Connection, stmt_handle, sql_state, &native_error, error_buf, ERR_BUF_SIZE, &len);
+-
+-	assert(err != SQL_ERROR);
+-
+-	if (err == SQL_NO_DATA) {
+-		strncpy((char *) error_buf, "(could not obtain error string)", ERR_BUF_SIZE);
+-	}
+-	return (const char *) error_buf;
+-}
+-
+ static void
+-show_error(const char *where, const char *what, int no)
++show_error(const char *where, const char *what)
+ {
+-	printf("ERROR in %s: %s [%d].\n", where, what, no);
++	printf("ERROR in %s: %s.\n", where, what);
+ }
+ 
+ static void
+@@ -68,7 +42,7 @@ clean_up(void)
+ static int
+ test_insert(void *buf, SQLLEN buflen)
+ {
+-	SQLHSTMT stmt_handle;
++	SQLHSTMT old_Statement;
+ 	SQLLEN strlen_or_ind;
+ 	const char *qstr = "insert into " TEST_TABLE_NAME " values (?)";
+ 
+@@ -76,46 +50,24 @@ test_insert(void *buf, SQLLEN buflen)
+ 	assert(Environment);
+ 
+ 	/* allocate new statement handle */
+-	err = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &stmt_handle);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_insert(): allocating new statement handle", get_odbc_error(0), err);
+-		return -1;
+-	}
++	old_Statement = Statement;
++	Statement = SQL_NULL_HSTMT;
++	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "SI");
+ 
+ 	/* execute query */
+-	err = SQLPrepare(stmt_handle, (SQLCHAR *) qstr, SQL_NTS);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_insert(): preparing statement", get_odbc_error(stmt_handle), err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKPrepare((SQLCHAR *) qstr, SQL_NTS, "SI");
+ 
+ 	strlen_or_ind = buflen;
+-	err = SQLBindParameter(stmt_handle,
+-			       1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, (SQLUINTEGER) (-1), 0, buf, buflen,
+-			       &strlen_or_ind);
+-
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_insert(): binding to parameter", get_odbc_error(stmt_handle), err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, (SQLUINTEGER) (-1), 0, buf, buflen,
++			       &strlen_or_ind, "SI");
+ 
+-	err = SQLExecute(stmt_handle);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_insert(): executing prepared query", get_odbc_error(stmt_handle), err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKExecute("SI");
+ 
+ 	/* this command shouldn't fail */
+-	Command(stmt_handle, "DECLARE @i INT");
++	Command(Statement, "DECLARE @i INT");
+ 
+-	SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-	stmt_handle = 0;
++	SQLFreeHandle(SQL_HANDLE_STMT, Statement);
++	Statement = old_Statement;
+ 	return 0;
+ }
+ 
+@@ -123,7 +75,7 @@ test_insert(void *buf, SQLLEN buflen)
+ static int
+ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ {
+-	SQLHSTMT stmt_handle;
++	SQLHSTMT old_Statement;
+ 	SQLLEN strlen_or_ind = 0;
+ 	const char *qstr = "select * from " TEST_TABLE_NAME;
+ 
+@@ -131,54 +83,26 @@ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ 	assert(Environment);
+ 
+ 	/* allocate new statement handle */
+-	err = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &stmt_handle);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_select(): allocating new statement handle", get_odbc_error(0), err);
+-		return -1;
+-	}
++	old_Statement = Statement;
++	Statement = SQL_NULL_HSTMT;
++	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "SI");
+ 
+ 	/* execute query */
+-	err = SQLExecDirect(stmt_handle, (SQLCHAR *) qstr, SQL_NTS);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_select(): executing query", get_odbc_error(stmt_handle), err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKExecDirect((SQLCHAR *) qstr, SQL_NTS, "SINo");
+ 
+ 	/* fetch first page of first result row of unbound column */
+-	err = SQLFetch(stmt_handle);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_select(): fetching results", get_odbc_error(stmt_handle), err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKFetch("S");
+ 
+ 	strlen_or_ind = 0;
+-	err = SQLGetData(stmt_handle, 1, SQL_C_BINARY, buf, buflen, &strlen_or_ind);
+-	if (!sqlreturn_noerr(err)) {
+-		show_error("test_select(): getting column", get_odbc_error(stmt_handle), err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKGetData(1, SQL_C_BINARY, buf, buflen, &strlen_or_ind, "SINo");
+ 
+ 	*bytes_returned = ((strlen_or_ind > buflen || (strlen_or_ind == SQL_NO_TOTAL)) ? buflen : strlen_or_ind);
+ 
+ 	/* ensure that this was the only row */
+-	err = SQLFetch(stmt_handle);
+-	if (err != SQL_NO_DATA) {
+-		show_error("test_select(): retrieving results",
+-			   "Number of result rows must be exactly equal to 1.\n"
+-			   "Please delete all entries from table '" TEST_TABLE_NAME "' and rerun test.", err);
+-		SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-		stmt_handle = 0;
+-		return -1;
+-	}
++	CHKFetch("No");
+ 
+-	SQLFreeHandle(SQL_HANDLE_STMT, stmt_handle);
+-	stmt_handle = 0;
++	SQLFreeHandle(SQL_HANDLE_STMT, Statement);
++	Statement = old_Statement;
+ 	return 0;
+ }
+ 
+@@ -219,7 +143,7 @@ main(int argc, char **argv)
+ 
+ 	/* compare inserted and read back test patterns */
+ 	if (bytes_returned != TEST_BUF_LEN) {
+-		show_error("main(): comparing buffers", "Mismatch in input and output pattern sizes.", 0);
++		show_error("main(): comparing buffers", "Mismatch in input and output pattern sizes.");
+ 		clean_up();
+ 		return -1;
+ 	}
+@@ -227,7 +151,7 @@ main(int argc, char **argv)
+ 	for (i = 0; i < TEST_BUF_LEN; ++i) {
+ 		if (buf[i] != BYTE_AT(i)) {
+ 			printf("mismatch at pos %d %d != %d\n", i, buf[i], BYTE_AT(i));
+-			show_error("main(): comparing buffers", "Mismatch in input and output patterns.", 0);
++			show_error("main(): comparing buffers", "Mismatch in input and output patterns.");
+ 			clean_up();
+ 			return -1;
+ 		}
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index eccf5d4..eea40ee 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,12 +3,12 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.9 2008/10/17 12:21:10 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_SUCCESS && rcode != SQL_SUCCESS_WITH_INFO && rcode != SQL_NO_DATA && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
++   if ( RetCode != SQL_SUCCESS && RetCode != SQL_SUCCESS_WITH_INFO && RetCode != SQL_NO_DATA && RetCode != SQL_NEED_DATA ) { \
++      fprintf(stderr,"Error %d at: %s\n",RetCode,m); \
+       getErrorInfo(t,h); \
+       exit(1); \
+    }
+@@ -20,13 +20,12 @@ static int failed = 0;
+ static void
+ getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+ {
+-	SQLRETURN rcode = 0;
+ 	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+ 	SQLINTEGER naterror = 0;
+ 	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+ 	SQLSMALLINT msgtextl = 0;
+ 
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
++	SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+ 			      (SQLHANDLE) sqlhandle,
+ 			      (SQLSMALLINT) 1,
+ 			      (SQLCHAR *) sqlstate,
+@@ -85,9 +84,9 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ }
+ 
+ static int
+-readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
++readBlob(SQLUSMALLINT pos)
+ {
+-	SQLRETURN rcode;
++	SQLRETURN RetCode;
+ 	char buf[4096];
+ 	SQLLEN len, total = 0;
+ 	int i = 0;
+@@ -96,8 +95,8 @@ readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+ 	printf(">> readBlob field %d\n", pos);
+ 	while (1) {
+ 		i++;
+-		rcode = SQLGetData(stmth, pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len);
+-		if (!SQL_SUCCEEDED(rcode) || len <= 0)
++		CHKGetData(pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len, "SINo");
++		if (RetCode == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		if (len > (SQLLEN) sizeof(buf))
+ 			len = (SQLLEN) sizeof(buf);
+@@ -115,13 +114,13 @@ readBlob(SQLHSTMT * stmth, SQLUSMALLINT pos)
+ 	printf(">>   total bytes read = %d \n", (int) total);
+ 	if (total != 10000)
+ 		failed = 1;
+-	return rcode;
++	return RetCode;
+ }
+ 
+ static int
+-readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
++readBlobAsChar(SQLUSMALLINT pos, int step)
+ {
+-	SQLRETURN rcode = SQL_SUCCESS_WITH_INFO;
++	SQLRETURN RetCode = SQL_SUCCESS_WITH_INFO;
+ 	char buf[8192];
+ 	SQLLEN len, total = 0;
+ 	int i = 0;
+@@ -132,10 +131,10 @@ readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
+ 	else bufsize = sizeof(buf);
+ 
+ 	printf(">> readBlobAsChar field %d\n", pos);
+-	while (rcode == SQL_SUCCESS_WITH_INFO) {
++	while (RetCode == SQL_SUCCESS_WITH_INFO) {
+ 		i++;
+-		rcode = SQLGetData(stmth, pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len);
+-		if (!SQL_SUCCEEDED(rcode) || len <= 0)
++		CHKGetData(pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
++		if (RetCode == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		if (len > (SQLLEN) bufsize)
+ 			len = (SQLLEN) bufsize - 1;
+@@ -152,15 +151,16 @@ readBlobAsChar(SQLHSTMT * stmth, SQLUSMALLINT pos, int step)
+ 	printf(">>   total bytes read = %d \n", (int) total);
+ 	if (total != 20000)
+ 		failed = 1;
+-	return rcode;
++	return RetCode;
+ }
+ 
+ 
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN rcode;
++	SQLRETURN RetCode;
+ 	SQLHSTMT m_hstmt = NULL;
++	SQLHSTMT old_Statement = SQL_NULL_HSTMT;
+ 	int i;
+ 
+ 	int key;
+@@ -183,15 +183,17 @@ main(int argc, char **argv)
+ 	for (i = 0; i < cnt; i++) {
+ 
+ 		m_hstmt = NULL;
+-		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &m_hstmt));
++		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt, "S");
++		old_Statement = Statement;
++		Statement = m_hstmt;
+ 
+-		CHK(SQLPrepare, (m_hstmt, (SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS));
++		CHKPrepare((SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS, "S");
+ 
+-		CHK(SQLBindParameter, (m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0));
+-		CHK(SQLBindParameter, (m_hstmt, 2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1));
+-		CHK(SQLBindParameter, (m_hstmt, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2));
+-		CHK(SQLBindParameter, (m_hstmt, 4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3));
+-		CHK(SQLBindParameter, (m_hstmt, 5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0));
++		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
++		CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1, "S");
++		CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2, "S");
++		CHKBindParameter(4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3, "S");
++		CHKBindParameter(5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
+ 
+ 		key = i;
+ 		vind0 = 0;
+@@ -207,35 +209,33 @@ main(int argc, char **argv)
+ 		
+ 
+ 		printf(">> insert... %d\n", i);
+-		rcode = SQLExecute(m_hstmt);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLExecute StmtH");
+-		while (rcode == SQL_NEED_DATA) {
++		CHKR(SQLExecute, (m_hstmt), "SINe");
++		while (RetCode == SQL_NEED_DATA) {
+ 			char *p;
+ 
+-			rcode = SQLParamData(m_hstmt, (SQLPOINTER) & p);
+-			CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "SQLParamData StmtH");
+-			printf(">> SQLParamData: ptr = %p  rcode = %d\n", (void *) p, rcode);
+-			if (rcode == SQL_NEED_DATA) {
++			CHKR(SQLParamData, (m_hstmt, (SQLPOINTER) & p), "SINe");
++			printf(">> SQLParamData: ptr = %p  RetCode = %d\n", (void *) p, RetCode);
++			if (RetCode == SQL_NEED_DATA) {
+ 				if (p == buf3) {
+ 					fill_hex(buf3, NBYTES, 987, 25);
+ 					
+-					CHK(SQLPutData, (m_hstmt, p, NBYTES - (i&1)));
++					CHKPutData(p, NBYTES - (i&1), "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
+ 					
+-					CHK(SQLPutData, (m_hstmt, p + NBYTES - (i&1), NBYTES + (i&1)));
++					CHKPutData(p + NBYTES - (i&1), NBYTES + (i&1), "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
+ 				} else {
+-					CHK(SQLPutData, (m_hstmt, p, NBYTES));
++					CHKPutData(p, NBYTES, "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES);
+ 				}
+ 			}
+ 		}
+ 
+-		CHK(SQLFreeHandle, (SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt));
+-
++		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt, "S");
++		Statement = old_Statement;
+ 	}
+ 
+ 	/* Now fetch rows ... */
+@@ -244,39 +244,42 @@ main(int argc, char **argv)
+ 
+ 		m_hstmt = NULL;
+ 		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &m_hstmt));
++		old_Statement = Statement;
++		Statement = m_hstmt;
+ 
+ 		if (db_is_microsoft()) {
+-			CHK(SQLSetStmtAttr, (m_hstmt, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER));
+-			CHK(SQLSetStmtAttr, (m_hstmt, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER));
++			CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
++			CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+ 		}
+ 
+-		CHK(SQLPrepare, (m_hstmt, (SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS));
++		CHKPrepare((SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS, "S");
+ 
+-		CHK(SQLBindParameter, (m_hstmt, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0));
++		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0, "S");
+ 
+-		CHK(SQLBindCol, (m_hstmt, 1, SQL_C_BINARY, NULL, 0, &vind1));
+-		CHK(SQLBindCol, (m_hstmt, 2, SQL_C_BINARY, NULL, 0, &vind2));
+-		CHK(SQLBindCol, (m_hstmt, 3, SQL_C_BINARY, NULL, 0, &vind3));
+-		CHK(SQLBindCol, (m_hstmt, 4, SQL_C_LONG, &key, 0, &vind0));
++		CHKBindCol(1, SQL_C_BINARY, NULL, 0, &vind1, "S");
++		CHKBindCol(2, SQL_C_BINARY, NULL, 0, &vind2, "S");
++		CHKBindCol(3, SQL_C_BINARY, NULL, 0, &vind3, "S");
++		CHKBindCol(4, SQL_C_LONG, &key, 0, &vind0, "S");
+ 
+ 		vind0 = 0;
+ 		vind1 = SQL_DATA_AT_EXEC;
+ 		vind2 = SQL_DATA_AT_EXEC;
+ 
+-		CHK(SQLExecute, (m_hstmt));
++		CHKExecute("S");
+ 
+-		CHK(SQLFetchScroll, (m_hstmt, SQL_FETCH_NEXT, 0));
++		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
+ 		printf(">> fetch... %d\n", i);
+ 
+-		rcode = readBlob(m_hstmt, 1);
++		RetCode = readBlob(1);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
+-		rcode = readBlob(m_hstmt, 2);
++		RetCode = readBlob(2);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
+-		rcode = readBlobAsChar(m_hstmt, 3, i);
++		RetCode = readBlobAsChar(3, i);
+ 		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR");
+ 
+-		CHK(SQLCloseCursor, (m_hstmt));
+-		CHK(SQLFreeHandle, (SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt));
++		CHKCloseCursor("S");
++		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt, "S");
++		Statement = old_Statement;
+ 	}
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 7c421b3..2d2b543 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -45,8 +45,10 @@ exit_forced(int s)
+ static void
+ sigalrm_handler(int s)
+ {
++	SQLRETURN RetCode;
++
+ 	printf(">>>> SQLCancel() ...\n");
+-	CHK(SQLCancel, (Statement));
++	CHKCancel("S");
+ 	printf(">>>> ... SQLCancel done\n");
+ 
+ 	alarm(4);
+@@ -56,7 +58,7 @@ sigalrm_handler(int s)
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN rcode;
++	SQLRETURN RetCode;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+@@ -64,19 +66,15 @@ main(int argc, char **argv)
+ 	printf(">> Wait 5 minutes...\n");
+ 	alarm(4);
+ 	signal(SIGALRM, sigalrm_handler);
+-	rcode = SQLExecDirect(Statement, (SQLCHAR *) "WAITFOR DELAY '000:05:00'", SQL_NTS);
++	CHKExecDirect((SQLCHAR *) "WAITFOR DELAY '000:05:00'", SQL_NTS, "E");
+ 	alarm(0);
+-	if (rcode != SQL_ERROR) {
+-		fprintf(stderr, "SQLExecDirect should return error\n");
+-		return 1;
+-	}
+ 	getErrorInfo(SQL_HANDLE_STMT, Statement);
+ 	if (strcmp(sqlstate, "HY008") != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+ 		Disconnect();
+ 		return 1;
+ 	}
+-	printf(">> ...  done rcode = %d\n", rcode);
++	printf(">> ...  done RetCode = %d\n", RetCode);
+ 
+ 	ResetStatement();
+ 
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 00f2af3..2ae6150 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,12 +12,13 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.48 2008/10/31 14:00:11 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.49 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+ HDBC Connection;
+ HSTMT Statement;
++SQLRETURN RetCode;
+ int use_odbc_version3 = 0;
+ void (*odbc_set_conn_attr)(void) = NULL;
+ 
+@@ -394,3 +395,50 @@ CheckCursor(void)
+ 	ResetStatement();
+ }
+ 
++SQLRETURN
++CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res)
++{
++	const char *p = res;
++	for (;;) {
++		if (*p == 'S') {
++			if (rc == SQL_SUCCESS)
++				return rc;
++			++p;
++		} else if (*p == 'I') {
++			if (rc == SQL_SUCCESS_WITH_INFO)
++				return rc;
++			++p;
++		} else if (*p == 'E') {
++			if (rc == SQL_ERROR)
++				return rc;
++			++p;
++		} else if (strncmp(p, "No", 2) == 0) {
++			if (rc == SQL_NO_DATA)
++				return rc;
++			p += 2;
++		} else if (strncmp(p, "Ne", 2) == 0) {
++			if (rc == SQL_NEED_DATA)
++				return rc;
++			p += 2;
++		} else {
++			ReportError("Wrong results specified", line, file);
++			return rc;
++		}
++	}
++	ReportError(func, line, file);
++	return rc;
++}
++
++SQLSMALLINT
++AllocHandleErrType(SQLSMALLINT type)
++{
++	switch (type) {
++	case SQL_HANDLE_DESC:
++		return SQL_HANDLE_STMT;
++	case SQL_HANDLE_STMT:
++		return SQL_HANDLE_DBC;
++	case SQL_HANDLE_DBC:
++		return SQL_HANDLE_ENV;
++	}
++	return 0;
++}
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index bf4c174..3e6ac46 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.24 2008/10/29 09:33:50 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.25 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -36,6 +36,7 @@ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_wa
+ extern HENV Environment;
+ extern HDBC Connection;
+ extern HSTMT Statement;
++extern SQLRETURN RetCode;
+ extern int use_odbc_version3;
+ extern void (*odbc_set_conn_attr)(void);
+ 
+@@ -59,10 +60,85 @@ void CheckCursor(void);
+ #define ODBC_REPORT_ERROR(msg) ReportError(msg, __LINE__, __FILE__)
+ 
+ #define CHK(func,params) \
+-	do { if (func params != SQL_SUCCESS) \
++	do { if ((RetCode=(func params)) != SQL_SUCCESS) \
+ 		ODBC_REPORT_ERROR(#func); \
+ 	} while(0)
+ 
++SQLRETURN CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res);
++#define CHKR(func, params, res) \
++	CheckRes(__FILE__, __LINE__, (RetCode=(func params)), 0, 0, #func, res)
++#define CHKR2(func, params, type, handle, res) \
++	CheckRes(__FILE__, __LINE__, (RetCode=(func params)), type, handle, #func, res)
++
++SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
++
++#define CHKAllocStmt(a,res) \
++	CHKR2(SQLAllocStmt, (Connection,a), SQL_HANDLE_DBC, Connection, res)
++#define CHKAllocHandle(a,b,c,res) \
++	CHKR2(SQLAllocHandle, (a,b,c), AllocHandleErrType(a), b, res)
++#define CHKBindCol(a,b,c,d,e,res) \
++	CHKR2(SQLBindCol, (Statement,a,b,c,d,e), SQL_HANDLE_STMT, Statement, res)
++#define CHKBindParameter(a,b,c,d,e,f,g,h,i,res) \
++	CHKR2(SQLBindParameter, (Statement,a,b,c,d,e,f,g,h,i), SQL_HANDLE_STMT, Statement, res)
++#define CHKCancel(res) \
++	CHKR2(SQLCancel, (Statement), SQL_HANDLE_STMT, Statement, res)
++#define CHKCloseCursor(res) \
++	CHKR2(SQLCloseCursor, (Statement), SQL_HANDLE_STMT, Statement, res)
++#define CHKColAttribute(a,b,c,d,e,f,res) \
++	CHKR2(SQLColAttribute, (Statement,a,b,c,d,e,f), SQL_HANDLE_STMT, Statement, res)
++#define CHKDescribeCol(a,b,c,d,e,f,g,h,res) \
++	CHKR2(SQLDescribeCol, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++#define CHKEndTran(a,b,c,res) \
++	CHKR2(SQLEndTran, (a,b,c), a, b, res)
++#define CHKExecDirect(a,b,res) \
++	CHKR2(SQLExecDirect, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++#define CHKExecute(res) \
++	CHKR2(SQLExecute, (Statement), SQL_HANDLE_STMT, Statement, res)
++#define CHKExtendedFetch(a,b,c,d,res) \
++	CHKR2(SQLExtendedFetch, (Statement,a,b,c,d), SQL_HANDLE_STMT, Statement, res)
++#define CHKFetch(res) \
++	CHKR2(SQLFetch, (Statement), SQL_HANDLE_STMT, Statement, res)
++#define CHKFetchScroll(a,b,res) \
++	CHKR2(SQLFetchScroll, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++#define CHKFreeHandle(a,b,res) \
++	CHKR2(SQLFreeHandle, (a,b), a, b, res)
++#define CHKFreeStmt(a,res) \
++	CHKR2(SQLFreeStmt, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++#define CHKGetConnectAttr(a,b,c,d,res) \
++	CHKR2(SQLGetConnectAttr, (Connection,a,b,c,d), SQL_HANDLE_DBC, Connection, res)
++#define CHKGetDiagRec(a,b,c,d,e,f,g,h,res) \
++	CHKR2(SQLGetDiagRec, (a,b,c,d,e,f,g,h), a, b, res)
++#define CHKGetStmtAttr(a,b,c,d,res) \
++	CHKR2(SQLGetStmtAttr, (Statement,a,b,c,d), SQL_HANDLE_STMT, Statement, res)
++#define CHKGetTypeInfo(a,res) \
++	CHKR2(SQLGetTypeInfo, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++#define CHKGetData(a,b,c,d,e,res) \
++	CHKR2(SQLGetData, (Statement,a,b,c,d,e), SQL_HANDLE_STMT, Statement, res)
++#define CHKMoreResults(res) \
++	CHKR2(SQLMoreResults, (Statement), SQL_HANDLE_STMT, Statement, res)
++#define CHKNumResultCols(a,res) \
++	CHKR2(SQLNumResultCols, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++#define CHKParamData(a,res) \
++	CHKR2(SQLParamData, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++#define CHKPrepare(a,b,res) \
++	CHKR2(SQLPrepare, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++#define CHKPutData(a,b,res) \
++	CHKR2(SQLPutData, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++#define CHKRowCount(a,res) \
++	CHKR2(SQLRowCount, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++#define CHKSetConnectAttr(a,b,c,res) \
++	CHKR2(SQLSetConnectAttr, (Connection,a,b,c), SQL_HANDLE_DBC, Connection, res)
++#define CHKSetCursorName(a,b,res) \
++	CHKR2(SQLSetCursorName, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++#define CHKSetPos(a,b,c,res) \
++	CHKR2(SQLSetPos, (Statement,a,b,c), SQL_HANDLE_STMT, Statement, res)
++#define CHKSetStmtAttr(a,b,c,res) \
++	CHKR2(SQLSetStmtAttr, (Statement,a,b,c), SQL_HANDLE_STMT, Statement, res)
++#define CHKSetStmtOption(a,b,res) \
++	CHKR2(SQLSetStmtOption, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++#define CHKTables(a,b,c,d,e,f,g,h,res) \
++	CHKR2(SQLTables, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++
+ int Connect(void);
+ int Disconnect(void);
+ void Command(HSTMT stmt, const char *command);
+diff --git a/src/odbc/unittests/compute.c b/src/odbc/unittests/compute.c
+index 11c0548..20bca06 100644
+--- a/src/odbc/unittests/compute.c
++++ b/src/odbc/unittests/compute.c
+@@ -9,7 +9,7 @@
+  * and declared in odbcss.h
+  */
+ 
+-static char software_version[] = "$Id: compute.c,v 1.10 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: compute.c,v 1.11 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char col1[256], col2[256];
+@@ -35,14 +35,14 @@ TestName(SQLSMALLINT index, const char *expected_name)
+ 	} while(0)
+ 
+ 	/* retrieve with SQLDescribeCol */
+-	CHK(SQLDescribeCol, (Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL));
++	CHKDescribeCol(index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL, "S");
+ 	NAME_TEST;
+ 
+ 	/* retrieve with SQLColAttribute */
+-	CHK(SQLColAttribute, (Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL));
++	CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
+ 	if (db_is_microsoft())
+ 		NAME_TEST;
+-	CHK(SQLColAttribute, (Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL));
++	CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
+ 	NAME_TEST;
+ }
+ 
+@@ -53,7 +53,7 @@ CheckFetch(const char *c1name, const char *c1, const char *c2)
+ 
+ 	TestName(1, c1name);
+ 
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 
+ 	if (strlen(c1) != ind1 || strcmp(c1, col1) != 0) {
+ 		fprintf(stderr, "%s:%d: Column 1 error '%s' (%d) expected '%s' (%d)\n", __FILE__, main_line, col1, (int) ind1, c1,
+@@ -101,19 +101,16 @@ main(int argc, char *argv[])
+ 	CheckFetch("c", "pluto", "1");
+ 	CheckFetch("c", "pluto", "2");
+ 	CheckFetch("c", "pluto", "3");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	/* why I need to rebind ?? ms bug of feature ?? */
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	col2[0] = '@';
+ 	CheckFetch("sum", "52", "@");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
++	CHKFetch("No");
++	CHKMoreResults("No");
+ 
+ 
+ 
+@@ -124,43 +121,37 @@ main(int argc, char *argv[])
+ 	Command(Statement, "select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
+ 	CheckFetch("mao", "pippo", "12");
+ 	CheckFetch("mao", "pippo", "34");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	strcpy(col2, "##");
+ 	CheckFetch("sum", "46", "##");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	CheckFetch("mao", "pluto", "1");
+ 	CheckFetch("mao", "pluto", "2");
+ 	CheckFetch("mao", "pluto", "3");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	strcpy(col2, "%");
+ 	CheckFetch("sum", "6", "%");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	strcpy(col2, "&");
+ 	CheckFetch("max", "34", "&");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
++	CHKFetch("No");
++	CHKMoreResults("No");
+ 
+ 
+ 
+@@ -171,23 +162,20 @@ main(int argc, char *argv[])
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	Command(Statement, "select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
+ 	CheckFetch("c", "pippo", "34");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	/* here just skip results, before a row */
+-	CHK(SQLMoreResults, (Statement));
++	CHKMoreResults("S");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	CheckFetch("c", "pluto", "2");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
+-	CHK(SQLMoreResults, (Statement));
++	CHKFetch("No");
++	CHKMoreResults("S");
+ 
+ 	/* here just skip results, before done */
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data ??");
++	CHKMoreResults("No");
+ 
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c
+index b897544..1d1537d 100644
+--- a/src/odbc/unittests/connect.c
++++ b/src/odbc/unittests/connect.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: connect.c,v 1.9 2006/04/11 11:52:24 freddy77 Exp $";
++static char software_version[] = "$Id: connect.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,21 +9,13 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		printf("Unable to allocate env\n");
+-		exit(1);
+-	}
+-	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		printf("Unable to allocate connection\n");
+-		SQLFreeEnv(Environment);
+-		exit(1);
+-	}
++	CHKR(SQLAllocEnv, (&Environment), "S");
++	CHKR(SQLAllocConnect, (Environment, &Connection), "S");
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	int res;
+ 	char tmp[2048];
+ 	SQLSMALLINT len;
+ 	int failures = 0;
+@@ -66,12 +58,7 @@ main(int argc, char *argv[])
+ 	printf("connect string DSN connect..\n");
+ 	init_connect();
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+-		CheckReturn();
+-		return 1;
+-	}
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
+ 	Disconnect();
+ 
+ 	/* try connect string using old SERVERNAME specification */
+@@ -81,9 +68,9 @@ main(int argc, char *argv[])
+ 	/* this is expected to work with unixODBC */
+ 	init_connect();
+ 	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (!SQL_SUCCEEDED(res)) {
+-		printf("Unable to open data source (ret=%d)\n", res);
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SIE");
++	if (RetCode == SQL_ERROR) {
++		printf("Unable to open data source (ret=%d)\n", RetCode);
+ 		++failures;
+ 	}
+ 	Disconnect();
+@@ -91,9 +78,9 @@ main(int argc, char *argv[])
+ 	/* this is expected to work with iODBC */
+ 	init_connect();
+ 	sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", DRIVER, SERVER, USER, PASSWORD, DATABASE);
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (!SQL_SUCCEEDED(res)) {
+-		printf("Unable to open data source (ret=%d)\n", res);
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SIE");
++	if (RetCode == SQL_ERROR) {
++		printf("Unable to open data source (ret=%d)\n", RetCode);
+ 		++failures;
+ 	}
+ 	Disconnect();
+diff --git a/src/odbc/unittests/connect2.c b/src/odbc/unittests/connect2.c
+index 0f00546..9eacb7b 100644
+--- a/src/odbc/unittests/connect2.c
++++ b/src/odbc/unittests/connect2.c
+@@ -5,7 +5,7 @@
+  * either SQLConnect and SQLDriverConnect
+  */
+ 
+-static char software_version[] = "$Id: connect2.c,v 1.5 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: connect2.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -15,27 +15,14 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		printf("Unable to allocate env\n");
+-		exit(1);
+-	}
+-	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		printf("Unable to allocate connection\n");
+-		SQLFreeEnv(Environment);
+-		exit(1);
+-	}
++	CHKR(SQLAllocEnv, (&Environment), "S");
++	CHKR(SQLAllocConnect, (Environment, &Connection), "S");
+ }
+ 
+ static void
+ normal_connect(void)
+ {
+-	int res;
+-
+-	res = SQLConnect(Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+-		CheckReturn();
+-	}
++	CHKR(SQLConnect, (Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS), "SI");
+ }
+ 
+ static void
+@@ -43,13 +30,8 @@ driver_connect(const char *conn_str)
+ {
+ 	char tmp[1024];
+ 	SQLSMALLINT len;
+-	int res;
+ 
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) conn_str, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+-		CheckReturn();
+-	}
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) conn_str, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
+ }
+ 
+ static void
+@@ -57,14 +39,9 @@ check_dbname(const char *dbname)
+ {
+ 	SQLINTEGER len;
+ 	char out[512];
+-	int res;
+ 
+ 	len = sizeof(out);
+-	res = SQLGetConnectAttr(Connection, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) out, sizeof(out), &len);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to get database name to %s\n", dbname);
+-		CheckReturn();
+-	}
++	CHKGetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) out, sizeof(out), &len, "SI");
+ 
+ 	if (strcmp(out, dbname) != 0) {
+ 		fprintf(stderr, "Current database (%s) is not %s\n", out, dbname);
+@@ -75,20 +52,13 @@ check_dbname(const char *dbname)
+ static void
+ set_dbname(const char *dbname)
+ {
+-	int res;
+-
+-	res = SQLSetConnectAttr(Connection, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) dbname, strlen(dbname));
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to set database name to %s\n", dbname);
+-		CheckReturn();
+-	}
++	CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) dbname, strlen(dbname), "SI");
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+ 	char tmp[1024];
+-	int res;
+ 
+ 	if (read_login_info())
+ 		exit(1);
+@@ -107,11 +77,7 @@ main(int argc, char *argv[])
+ 
+ 	printf("SQLConnect after not existing..\n");
+ 	strcpy(tmp, "IDontExist");
+-	res = SQLSetConnectAttr(Connection, SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) tmp, strlen(tmp));
+-	if (res != SQL_ERROR) {
+-		fprintf(stderr, "SQLSetConnectAttr should fail\n");
+-		return 1;
+-	}
++	CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) tmp, strlen(tmp), "E");
+ 	check_dbname("tempdb");
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/const_params.c b/src/odbc/unittests/const_params.c
+index a1482e1..92bbbf2 100644
+--- a/src/odbc/unittests/const_params.c
++++ b/src/odbc/unittests/const_params.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?,123,'foo')} syntax and run */
+ 
+-static char software_version[] = "$Id: const_params.c,v 1.14 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: const_params.c,v 1.15 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -26,17 +26,16 @@ main(int argc, char *argv[])
+ 		" return 24680\n"
+ 		"end");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind));
+-
+-	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind2));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind, "S");
++	CHKBindParameter(2, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1, 0, &ind2, "S");
+ 
+ 	/* TODO use {ts ...} for date */
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{call const_param(?, 13579, '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "{call const_param(?, 13579, '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS, "S");
+ 
+ 	input = 13579;
+ 	ind = sizeof(input);
+ 	out1 = output = 0xdeadbeef;
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	if (out1 != 7654321) {
+ 		fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
+@@ -46,17 +45,17 @@ main(int argc, char *argv[])
+ 	/* just to reset some possible buffers */
+ 	Command(Statement, "DECLARE @i INT");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
+-	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2));
+-	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1,   0, &ind3));
++	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind,  "S");
++	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2, "S");
++	CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1,   0, &ind3, "S");
+ 
+ 	/* TODO use {ts ...} for date */
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{?=call const_param(?, , '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "{?=call const_param(?, , '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS, "S");
+ 
+ 	input = 13579;
+ 	ind2 = sizeof(input);
+ 	out1 = output = 0xdeadbeef;
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	if (out1 != 7654321) {
+ 		fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
+@@ -77,12 +76,12 @@ main(int argc, char *argv[])
+ 		" return 54321\n"
+ 		"end");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
++	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{?=call const_param(12.5, 0x0102030405060708)}", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "{?=call const_param(12.5, 0x0102030405060708)}", SQL_NTS, "S");
+ 
+ 	output = 0xdeadbeef;
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	if (output != 54321) {
+ 		fprintf(stderr, "Invalid result %d (0x%x) expected 54321\n", (int) output, (int) output);
+@@ -100,7 +99,7 @@ main(int argc, char *argv[])
+ 	/* catch problem reported by Peter Deacon */
+ 	output = 0xdeadbeef;
+ 	Command(Statement, "{CALL const_param('value')}");
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_SLONG, &output, 0, &ind));
++	CHKBindCol(1, SQL_C_SLONG, &output, 0, &ind, "S");
+ 	SQLFetch(Statement);
+ 
+ 	if (output != 8421) {
+diff --git a/src/odbc/unittests/convert_error.c b/src/odbc/unittests/convert_error.c
+index 68a70ef..676adf0 100644
+--- a/src/odbc/unittests/convert_error.c
++++ b/src/odbc/unittests/convert_error.c
+@@ -4,7 +4,7 @@
+  */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: convert_error.c,v 1.8 2008/01/31 09:13:08 freddy77 Exp $";
++static char software_version[] = "$Id: convert_error.c,v 1.9 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int test_num = 0;
+@@ -22,13 +22,13 @@ Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2)
+ 	++test_num;
+ 	sprintf(sql, "insert into #test_output values (%s, %s)", bind1, bind2);
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) sql, strlen(sql)));
++	CHKPrepare((SQLCHAR *) sql, strlen(sql), "S");
+ 	if (bind1[0] == '?')
+-		CHK(SQLBindParameter, (Statement, id++, SQL_PARAM_INPUT, SQL_C_LONG, type1, 3, 0, &test_num, 0, &ind));
++		CHKBindParameter(id++, SQL_PARAM_INPUT, SQL_C_LONG, type1, 3, 0, &test_num, 0, &ind, "S");
+ 	if (bind2[0] == '?')
+-		CHK(SQLBindParameter, (Statement, id++, SQL_PARAM_INPUT, SQL_C_CHAR, type2, strlen(val) + 1, 0, (SQLCHAR *) val,
+-					 0, &ind));
+-	CHK(SQLExecute, (Statement));
++		CHKBindParameter(id++, SQL_PARAM_INPUT, SQL_C_CHAR, type2, strlen(val) + 1, 0, (SQLCHAR *) val,
++					 0, &ind, "S");
++	CHKExecute("S");
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/copydesc.c b/src/odbc/unittests/copydesc.c
+index 75380bc..9488154 100644
+--- a/src/odbc/unittests/copydesc.c
++++ b/src/odbc/unittests/copydesc.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLCopyDesc and SQLAllocHandle(SQL_HANDLE_DESC) */
+ 
+-static char software_version[] = "$Id: copydesc.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: copydesc.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -15,20 +15,20 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_APP_ROW_DESC, &ard, 0, NULL));
++	CHKGetStmtAttr(SQL_ATTR_APP_ROW_DESC, &ard, 0, NULL, "S");
+ 
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1));
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, name, sizeof(name), &ind2));
++	CHKBindCol(1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1, "S");
++	CHKBindCol(2, SQL_C_CHAR, name, sizeof(name), &ind2, "S");
+ 
+-	CHK(SQLAllocHandle, (SQL_HANDLE_DESC, Connection, &ard2));
++	CHKAllocHandle(SQL_HANDLE_DESC, Connection, &ard2, "S");
+ 
+ 	/*
+ 	 * this is an additional test to test additional allocation 
+ 	 * As of 0.64 for a bug in SQLAllocDesc we only allow to allocate one
+ 	 */
+-	CHK(SQLAllocHandle, (SQL_HANDLE_DESC, Connection, &ard3));
++	CHKAllocHandle(SQL_HANDLE_DESC, Connection, &ard3, "S");
+ 
+-	CHK(SQLCopyDesc, (ard, ard2));
++	CHKR(SQLCopyDesc, (ard, ard2), "S");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index 1882457..e19fb2c 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,14 +2,9 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.16 2008/10/31 14:35:23 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.17 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHK_INFO(func,params) \
+-	do { if (!SQL_SUCCEEDED(func params)) \
+-		ODBC_REPORT_ERROR(#func); \
+-	} while(0)
+-
+ #define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
+ 
+ static int mssql2005 = 0;
+@@ -17,26 +12,22 @@ static int mssql2005 = 0;
+ static void
+ CheckNoRow(const char *query)
+ {
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 
+-	retcode = SQLExecDirect(Statement, (SQLCHAR *) query, SQL_NTS);
+-	if (retcode == SQL_NO_DATA)
++	CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
++	if (RetCode == SQL_NO_DATA)
+ 		return;
+ 
+-	if (!SQL_SUCCEEDED(retcode))
+-		ODBC_REPORT_ERROR("SQLExecDirect");
+-
+ 	do {
+ 		SQLSMALLINT cols;
+ 
+-		retcode = SQLNumResultCols(Statement, &cols);
+-		if (retcode != SQL_SUCCESS || cols != 0) {
++		CHKNumResultCols(&cols, "S");
++		if (cols != 0) {
+ 			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
++			Disconnect();
+ 			exit(1);
+ 		}
+-	} while ((retcode = SQLMoreResults(Statement)) == SQL_SUCCESS);
+-	if (retcode != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLMoreResults");
++	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
+ }
+ 
+ static void
+@@ -53,7 +44,7 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 	SQLUSMALLINT i;
+ 	SQLULEN num_row;
+ 	SQLHSTMT stmt2;
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 
+ 	/* create test table */
+ 	Command(Statement, "IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+@@ -68,27 +59,24 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 
+ 	/* set cursor options */
+ 	ResetStatement();
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
+-	CHK(SQLSetCursorName, (Statement, (SQLCHAR *) "C1", SQL_NTS));
++	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
++	CHKSetCursorName((SQLCHAR *) "C1", SQL_NTS, "S");
+ 
+ 	/* */
+-	CHK(SQLExecDirect, (Statement, (SQLCHAR *) select_sql, SQL_NTS));
++	CHKExecDirect((SQLCHAR *) select_sql, SQL_NTS, "S");
+ 
+ 	/* bind some rows at a time */
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_ULONG, n, 0, n_len));
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, c, C_LEN, c_len));
++	CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S");
++	CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S");
+ 
+ 	/* allocate an additional statement */
+-	CHK(SQLAllocStmt, (Connection, &stmt2));
+-
+-	while ((retcode = SQLFetchScroll(Statement, SQL_FETCH_NEXT, 0)) != SQL_ERROR) {
+-		if (retcode == SQL_NO_DATA)
+-			break;
++	CHKAllocStmt(&stmt2, "S");
+ 
++	while (CHKFetchScroll(SQL_FETCH_NEXT, 0, "SNo") == SQL_SUCCESS) {
+ 		/* print, just for debug */
+ 		for (i = 0; i < num_row; ++i)
+ 			printf("row %d i %d c %s\n", (int) (i + 1), (int) n[i], c[i]);
+@@ -98,13 +86,13 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 		i = 1;
+ 		if (i > 0 && i <= num_row) {
+ 			if (mssql2005)
+-				CHK_INFO(SQLSetPos, (Statement, i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE));
++				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "SI");
+ 			else
+-				CHK(SQLSetPos, (Statement, i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE));
++				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_DELETE, SQL_LOCK_NO_CHANGE, "S");
+ 			if (use_sql) {
+ 				SWAP_STMT(stmt2);
+-				CHK(SQLPrepare, (Statement, (SQLCHAR *) "DELETE FROM #test WHERE CURRENT OF C1", SQL_NTS));
+-				CHK(SQLExecute, (Statement));
++				CHKPrepare((SQLCHAR *) "DELETE FROM #test WHERE CURRENT OF C1", SQL_NTS, "S");
++				CHKExecute("S");
+ 				SWAP_STMT(stmt2);
+ 			}
+ 		}
+@@ -115,19 +103,15 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 			strcpy(c[i - 1], "foo");
+ 			c_len[i - 1] = 3;
+ 			if (strstr(select_sql, "#a") == NULL || use_sql) {
+-				CHK(SQLSetPos, (Statement, i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE));
++				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "S");
+ 			} else {
+ 				unsigned char sqlstate[6];
+ 				unsigned char msg[256];
+ 
+ 				n[i - 1] = 321;
+-				retcode = SQLSetPos(Statement, i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE);
+-				if (retcode != SQL_ERROR) {
+-					fprintf(stderr, "Error expected at line %d\n", __LINE__);
+-					exit(1);
+-				}
++				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "E");
+ 
+-				CHK(SQLGetDiagRec, (SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL));
++				CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "S");
+ 				if (strstr((char *) msg, "Invalid column name 'c'") == NULL) {
+ 					fprintf(stderr, "Expected message not found at line %d\n", __LINE__);
+ 					exit(1);
+@@ -135,10 +119,9 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 			}
+ 			if (use_sql) {
+ 				SWAP_STMT(stmt2);
+-				CHK(SQLPrepare, (Statement, (SQLCHAR *) "UPDATE #test SET c=? WHERE CURRENT OF C1", SQL_NTS));
+-				CHK(SQLBindParameter,
+-				    (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL));
+-				CHK(SQLExecute, (Statement));
++				CHKPrepare((SQLCHAR *) "UPDATE #test SET c=? WHERE CURRENT OF C1", SQL_NTS, "S");
++				CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL, "S");
++				CHKExecute("S");
+ 				/* FIXME this is not necessary for mssql driver */
+ 				SQLMoreResults(Statement);
+ 				SWAP_STMT(stmt2);
+@@ -146,10 +129,9 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 		}
+ 	}
+ 
+-	if (retcode == SQL_ERROR)
+-		ODBC_REPORT_ERROR("SQLFetchScroll");
+-
+-	CHK(SQLFreeStmt, (stmt2, SQL_DROP));
++	SWAP_STMT(stmt2);
++	CHKFreeStmt(SQL_DROP, "S");
++	SWAP_STMT(stmt2);
+ 
+ 	ResetStatement();
+ 
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index ac1d1db..9d261f6 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursor do not give error for statement that do not return rows  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -18,7 +18,7 @@ main(int argc, char *argv[])
+ 
+ 	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE,  (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
+ 	if (retcode != SQL_SUCCESS) {
+-		CHK(SQLGetDiagRec, (SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL));
++		CHKGetDiagRec(SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL, "S");
+ 		sqlstate[5] = 0;
+ 		if (strcmp((const char*) sqlstate, "S1092") == 0) {
+ 			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+@@ -33,8 +33,7 @@ main(int argc, char *argv[])
+ 	/* this should not fail or return warnings */
+ 	Command(Statement, "DROP TABLE #cursor2_test");
+ 
+-	if (SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("no warning expected");
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "No");
+ 
+ 	Disconnect();
+ 	
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index 5a6849f..abe3513 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,62 +1,15 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.6 2008/02/06 08:28:10 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_NO_DATA \
+-     && rcode != SQL_SUCCESS \
+-     && rcode != SQL_SUCCESS_WITH_INFO  \
+-     && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+-static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+-{
+-	SQLRETURN rcode = 0;
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
+-
+-static void
+-exec_direct(int check, const char *stmt)
+-{
+-	SQLRETURN rcode;
+-	SQLHSTMT stmth = 0;
+-
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & stmth);
+-	CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLAllocHandle");
+-	rcode = SQLExecDirect(stmth, (SQLCHAR *) stmt, SQL_NTS);
+-	if (check) {
+-		CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLExecDirect");
+-	}
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) stmth);
+-	CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLFreeHandle");
+-}
+-
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN rcode;
+-	SQLHSTMT m_hstmt1;
+-	SQLHSTMT m_hstmt2;
++	SQLHSTMT stmt1 = SQL_NULL_HSTMT;
++	SQLHSTMT stmt2 = SQL_NULL_HSTMT;
++	SQLHSTMT old_Statement;
+ 	char buff[64];
+ 	SQLLEN ind;
+ 
+@@ -65,88 +18,70 @@ main(int argc, char **argv)
+ 
+ 	CheckCursor();
+ 
+-	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (2, 'bbbbb')");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (3, 'ccccccccc')");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (4, 'dd')");
+-
+-	m_hstmt1 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle 1");
+-
+-	m_hstmt2 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle 2");
++	Command(Statement, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
++	Command(Statement, "INSERT INTO #t1 VALUES (1, 'aaa')");
++	Command(Statement, "INSERT INTO #t1 VALUES (2, 'bbbbb')");
++	Command(Statement, "INSERT INTO #t1 VALUES (3, 'ccccccccc')");
++	Command(Statement, "INSERT INTO #t1 VALUES (4, 'dd')");
+ 
+-/*
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT,m_hstmt1,"Set attribute SQL_ATTR_CURSOR_SCROLLABLE 1");
+-*/
++	old_Statement = Statement;
+ 
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Set attribute SQL_ATTR_CURSOR_SENSITIVITY 1");
++	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &stmt1, "S");
++	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &stmt2, "S");
+ 
+-/*
+-	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT,m_hstmt2,"Set attribute SQL_ATTR_CURSOR_SCROLLABLE 2");
+-*/
+ 
+-	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "Set attribute SQL_ATTR_CURSOR_SENSITIVITY 2");
++	Statement = stmt1;
++/*	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); */
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
++/*	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S"); */
+ 
+-/*
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT,m_hstmt1,"Set attribute SQL_ATTR_CONCURRENCY 1");
+ 
+-	rcode = SQLSetStmtAttr(m_hstmt2, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT,m_hstmt2,"Set attribute SQL_ATTR_CONCURRENCY 2");
+-*/
++	Statement = stmt2;
++/*	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); */
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
++/*	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S"); */
+ 
+-	rcode = SQLSetCursorName(m_hstmt1, (SQLCHAR *) "c1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SetCursorName c1");
++	Statement = stmt1;
++	CHKSetCursorName((SQLCHAR *) "c1", SQL_NTS, "S");
+ 
+-	rcode = SQLSetCursorName(m_hstmt2, (SQLCHAR *) "c2", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SetCursorName c2");
++	Statement = stmt2;
++	CHKSetCursorName((SQLCHAR *) "c2", SQL_NTS, "S");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Prepare 1");
++	Statement = stmt1;
++	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1", SQL_NTS, "S");
+ 
+-	rcode = SQLPrepare(m_hstmt2, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "Prepare 2");
++	Statement = stmt2;
++	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1", SQL_NTS, "S");
+ 
+-	rcode = SQLExecute(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecute 1");
++	Statement = stmt1;
++	CHKExecute("S");
+ 
+-	rcode = SQLExecute(m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLExecute 2");
++	Statement = stmt2;
++	CHKExecute("S");
+ 
+-	rcode = SQLFetch(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFetch 1");
++	Statement = stmt1;
++	CHKFetch("S");
+ 
+-	rcode = SQLGetData(m_hstmt1, 2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLGetData 1");
++	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+ 	printf(">> Fetch from 1: [%s]\n", buff);
+ 
+-	rcode = SQLFetch(m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLFetch 2");
++	Statement = stmt2;
++	CHKFetch("S");
+ 
+-	rcode = SQLGetData(m_hstmt2, 2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLGetData 2");
++	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+ 	printf(">> Fetch from 2: [%s]\n", buff);
+ 
+-	rcode = SQLCloseCursor(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLCloseCursor 1");
+-
+-	rcode = SQLCloseCursor(m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLCloseCursor 2");
+-
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle 1");
++	Statement = stmt1;
++	CHKCloseCursor("SI");
++	Statement = stmt2;
++	CHKCloseCursor("SI");
+ 
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt2);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt2, "SQLFreeHandle 2");
++	Statement = stmt1;
++	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) stmt1, "S");
++	Statement = stmt2;
++	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) stmt2, "S");
+ 
++	Statement = old_Statement;
+ 	Disconnect();
+ 
+ 	return 0;
+diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c
+index c1ac6cd..9f228b5 100755
+--- a/src/odbc/unittests/cursor4.c
++++ b/src/odbc/unittests/cursor4.c
+@@ -5,61 +5,24 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.6 2008/02/06 08:28:10 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_NO_DATA \
+-     && rcode != SQL_SUCCESS \
+-     && rcode != SQL_SUCCESS_WITH_INFO  \
+-     && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+ static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
++exec_direct(const char *stmt)
+ {
+-	SQLRETURN rcode = 0;
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
++	SQLHSTMT old_Statement = Statement;
+ 
+-static void
+-exec_direct(int check, const char *stmt)
+-{
+-	SQLRETURN rcode;
+-	SQLHSTMT stmth = 0;
+-
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & stmth);
+-	CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLAllocHandle");
+-	rcode = SQLExecDirect(stmth, (SQLCHAR *) stmt, SQL_NTS);
+-	if (check) {
+-		CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLExecDirect");
+-	}
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) stmth);
+-	CHECK_RCODE(SQL_HANDLE_STMT, stmth, "SQLFreeHandle");
++	Statement = SQL_NULL_HSTMT;
++	CHKAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & Statement, "S");
++	Command(Statement, stmt);
++	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
++	Statement = old_Statement;
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN rcode;
+-	SQLHSTMT m_hstmt1;
+ 	char buff[64];
+ 	SQLLEN ind;
+ 
+@@ -68,50 +31,39 @@ main(int argc, char **argv)
+ 
+ 	CheckCursor();
+ 
+-	exec_direct(1, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+-	exec_direct(1, "INSERT INTO #t1 VALUES (1, 'aaa')");
++	exec_direct("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
++	exec_direct("INSERT INTO #t1 VALUES (1, 'aaa')");
+ 
+-	m_hstmt1 = NULL;
+-	rcode = SQLAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_DBC, Connection, "SQLAllocHandle 1");
++	ResetStatement();
+ 
+-	rcode = SQLSetStmtAttr(m_hstmt1, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Set attribute SQL_ATTR_CONCURRENCY");
++	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S");
+ 
+-	rcode = SQLSetCursorName(m_hstmt1, (SQLCHAR *) "c112", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SetCursorName c112");
++	CHKSetCursorName((SQLCHAR *) "c112", SQL_NTS, "S");
+ 
+-	rcode = SQLPrepare(m_hstmt1, (SQLCHAR *) "SELECT * FROM #t1 FOR UPDATE", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "Prepare 2");
++	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1 FOR UPDATE", SQL_NTS, "S");
+ 
+-	exec_direct(1, "BEGIN TRANSACTION");
++	exec_direct("BEGIN TRANSACTION");
+ 
+-	rcode = SQLExecute(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecute 2");
++	CHKExecute("S");
+ 
+-	rcode = SQLFetch(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFetch 1");
++	CHKFetch("S");
+ 
+-	exec_direct(1, "UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");
++	exec_direct("UPDATE #t1 SET c = 'xxx' WHERE CURRENT OF c112");
+ 
+-	rcode = SQLCloseCursor(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLCloseCursor 2");
++	CHKCloseCursor("SI");
+ 
+-	exec_direct(1, "COMMIT TRANSACTION");
++	exec_direct("COMMIT TRANSACTION");
+ 
+-	rcode = SQLExecDirect(m_hstmt1, (SQLCHAR *) "SELECT c FROM #t1 WHERE k = 1", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLExecDirect 2");
++	CHKExecDirect((SQLCHAR *) "SELECT c FROM #t1 WHERE k = 1", SQL_NTS, "S");
+ 
+-	rcode = SQLFetch(m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFetch 2");
++	CHKFetch("S");
+ 
+-	rcode = SQLGetData(m_hstmt1, 1, SQL_C_CHAR, buff, sizeof(buff), &ind);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLGetData");
++	CHKGetData(1, SQL_C_CHAR, buff, sizeof(buff), &ind, "S");
+ 
+ 	printf(">> New value after update = [%s] (should be [xxx]) \n", buff);
+ 
+-	rcode = SQLFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt1);
+-	CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt1, "SQLFreeHandle 1");
++	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
++	Statement = SQL_NULL_HSTMT;
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index 4797287..ea8d459 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,18 +1,8 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.6 2008/10/31 14:35:23 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHECK_RCODE(t,h,m) \
+-   if ( rcode != SQL_NO_DATA \
+-     && rcode != SQL_SUCCESS \
+-     && rcode != SQL_SUCCESS_WITH_INFO  \
+-     && rcode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",rcode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+ static SQLINTEGER v_int_3;
+ static SQLLEN v_ind_3_1;
+ 
+@@ -20,33 +10,13 @@ static char v_char_3[21];
+ static SQLLEN v_ind_3_2;
+ 
+ static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+-{
+-	SQLRETURN rcode = 0;
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	rcode = SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
+-
+-static void
+ doFetch(int dir, int pos)
+ {
+-	SQLRETURN rcode = SQLFetchScroll(Statement, dir, pos);
++	SQLRETURN RetCode;
++
++	CHKFetchScroll(dir, pos, "SINo");
+ 
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLFetchScroll");
+-	if (rcode != SQL_NO_DATA)
++	if (RetCode != SQL_NO_DATA)
+ 		printf(">> fetch %2d %10d : %d [%s]\n", dir, pos, v_ind_3_1 ? (int) v_int_3 : -1, v_ind_3_2 ? v_char_3 : "null");
+ 	else
+ 		printf(">> fetch %2d %10d : no data found\n", dir, pos);
+@@ -55,13 +25,11 @@ doFetch(int dir, int pos)
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN rcode;
+-
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 	CheckCursor();
+ 
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER));
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER, "S");
+ 
+ 	Command(Statement, "create table #mytab1 (k int, c char(30))");
+ 	Command(Statement, "insert into #mytab1 values (1,'aaa')");
+@@ -69,17 +37,15 @@ main(int argc, char **argv)
+ 	Command(Statement, "insert into #mytab1 values (3,'ccc')");
+ 
+ 	ResetStatement();
+-/*	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0));	*/
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER));
++/*	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0, "S");	*/
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER, "S");
+ 
+-	rcode = SQLPrepare(Statement, (SQLCHAR *) "select k, c from #mytab1 order by k", SQL_NTS);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLPrepare 3");
++	CHKPrepare((SQLCHAR *) "select k, c from #mytab1 order by k", SQL_NTS, "SI");
+ 
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_LONG, &v_int_3, 0, &v_ind_3_1));
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, v_char_3, sizeof(v_char_3), &v_ind_3_2));
++	CHKBindCol(1, SQL_C_LONG, &v_int_3, 0, &v_ind_3_1, "S");
++	CHKBindCol(2, SQL_C_CHAR, v_char_3, sizeof(v_char_3), &v_ind_3_2, "S");
+ 
+-	rcode = SQLExecute(Statement);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLExecute StmtH 3");
++	CHKExecute("SI");
+ 
+ 	doFetch(SQL_FETCH_LAST, 0);
+ 	doFetch(SQL_FETCH_PRIOR, 0);
+@@ -97,8 +63,7 @@ main(int argc, char **argv)
+ 	doFetch(SQL_FETCH_RELATIVE, -2);
+ 	doFetch(SQL_FETCH_RELATIVE, 5);
+ 
+-	rcode = SQLCloseCursor(Statement);
+-	CHECK_RCODE(SQL_HANDLE_STMT, Statement, "SQLCloseCursor StmtH 2");
++	CHKCloseCursor("SI");
+ 
+ 	Disconnect();
+ 	return 0;
+diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c
+index 3553852..6f3e431 100755
+--- a/src/odbc/unittests/cursor6.c
++++ b/src/odbc/unittests/cursor6.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with no binded columns */
+ 
+-static char software_version[] = "$Id: cursor6.c,v 1.3 2008/07/16 07:47:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor6.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int bind_all = 0;
+@@ -25,18 +25,18 @@ static void Test(void)
+ 
+ 	/* this should not fail or return warnings */
+ 	if (use_cursors) {
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0));
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0));
++		CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0, "S");
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0, "S");
+ 	}
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT c, i FROM #cursor6_test", SQL_NTS));
+-	CHK(SQLExecute, (Statement));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, statuses, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
++	CHKPrepare((SQLCHAR *) "SELECT c, i FROM #cursor6_test", SQL_NTS, "S");
++	CHKExecute("S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, statuses, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
+ 	if (bind_all)
+-		CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c));
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i));
++		CHKBindCol(1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c, "S");
++	CHKBindCol(2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i, "S");
+ 
+ #define FILL(s, n) do { \
+ 	int _n; for (_n = 0; _n < sizeof(s)/sizeof(s[0]); ++_n) s[_n] = n; \
+@@ -46,9 +46,9 @@ static void Test(void)
+ 	data[0].i = 0xdeadbeef;
+ 	data[1].i = 0xdeadbeef;
+ 	if (normal_fetch)
+-		CHK(SQLFetch, (Statement));
++		CHKFetch("S");
+ 	else
+-		CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
++		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
+ 
+ 	/* now check row numbers */
+ 	printf("num_row %d statuses[0] %d statuses[1] %d odbc3 %d\n", (int) num_row,
+@@ -69,9 +69,9 @@ static void Test(void)
+ 	FILL(statuses, 8765);
+ 	num_row = -3;
+ 	if (normal_fetch)
+-		CHK(SQLFetch, (Statement));
++		CHKFetch("S");
+ 	else
+-		CHK(SQLFetchScroll, (Statement, SQL_FETCH_NEXT, 0));
++		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
+ }
+ 
+ static void Init(void)
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index acd58c9..02cac03 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.5 2008/07/16 07:47:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -19,27 +19,27 @@ Test(void)
+ 	SQLULEN num_row;
+ 
+ 	int i;
+-	SQLRETURN ErrCode;
++	SQLRETURN RetCode;
+ 
+ 	ResetStatement();
+ 
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0));
++	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0, "S");
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT c, i FROM #cursor7_test", SQL_NTS));
+-	CHK(SQLExecute, (Statement));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, statuses, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
++	CHKPrepare((SQLCHAR *) "SELECT c, i FROM #cursor7_test", SQL_NTS, "S");
++	CHKExecute("S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_BIND_TYPE, int2ptr(sizeof(data[0])), 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, int2ptr(ROWS), 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, statuses, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
+ 
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c));
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i));
++	CHKBindCol(1, SQL_C_CHAR, &data[0].c, sizeof(data[0].c), &data[0].ind_c, "S");
++	CHKBindCol(2, SQL_C_LONG, &data[0].i, sizeof(data[0].i), &data[0].ind_i, "S");
+ 
+ 	/* Read records from last to first */
+ 	printf("\n\nReading records from last to first:\n");
+-	ErrCode = SQLFetchScroll(Statement, SQL_FETCH_LAST, -ROWS);
+-	while ((ErrCode == SQL_SUCCESS) || (ErrCode == SQL_SUCCESS_WITH_INFO)) {
++	CHKFetchScroll(SQL_FETCH_LAST, -ROWS, "SINo");
++	while (RetCode != SQL_NO_DATA) {
+ 		SQLULEN RowNumber;
+ 
+ 		/* Print this set of rows */
+@@ -49,16 +49,16 @@ Test(void)
+ 		}
+ 		printf("\n");
+ 
+-		CHK(SQLGetStmtAttr, (Statement, SQL_ROW_NUMBER, (SQLPOINTER)(&RowNumber), sizeof(RowNumber), NULL));
++		CHKGetStmtAttr(SQL_ROW_NUMBER, (SQLPOINTER)(&RowNumber), sizeof(RowNumber), NULL, "S");
+ 		printf("---> We are in record No: %u\n", (unsigned int) RowNumber);
+ 
+ 		/* Read next rowset */
+ 		if ( (RowNumber>1) && (RowNumber<ROWS) ) {
+-			ErrCode=SQLFetchScroll(Statement, SQL_FETCH_RELATIVE, 1-RowNumber); 
++			CHKFetchScroll(SQL_FETCH_RELATIVE, 1-RowNumber, "SINo"); 
+ 			for (i=RowNumber-1; i<ROWS; ++i)
+ 				statuses[i] = SQL_ROW_NOROW;
+ 		} else {
+-			ErrCode=SQLFetchScroll(Statement, SQL_FETCH_RELATIVE, -ROWS);
++			CHKFetchScroll(SQL_FETCH_RELATIVE, -ROWS, "SINo");
+ 		}
+ 	}
+ }
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 8915107..557453b 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.24 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.25 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -37,15 +37,9 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 		sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
+ 	Command(Statement, sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+-	CHK(SQLFetch, (Statement));
+-	if (SQLFetch(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Row not expected\n");
+-		exit(1);
+-	}
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Recordset not expected\n");
+-		exit(1);
+-	}
++	CHKFetch("S");
++	CHKFetch("No");
++	CHKMoreResults("No");
+ 
+ 	/* test results */
+ 	sbuf[0] = 0;
+diff --git a/src/odbc/unittests/date.c b/src/odbc/unittests/date.c
+index a37360f..1b1075c 100644
+--- a/src/odbc/unittests/date.c
++++ b/src/odbc/unittests/date.c
+@@ -1,14 +1,12 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: date.c,v 1.10 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: date.c,v 1.11 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ DoTest(int n)
+ {
+-	int res;
+-
+ 	SQLCHAR output[256];
+ 
+ 	SQLSMALLINT colType;
+@@ -20,18 +18,15 @@ DoTest(int n)
+ 
+ 	Command(Statement, "select convert(datetime, '2002-12-27 18:43:21')");
+ 
+-	res = SQLFetch(Statement);
+-	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("Unable to fetch row");
+-
+-	CHK(SQLDescribeCol, (Statement, 1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable));
++	CHKFetch("SI");
++	CHKDescribeCol(1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable, "S");
+ 
+ 	if (n == 0) {
+ 		memset(&ts, 0, sizeof(ts));
+-		CHK(SQLGetData, (Statement, 1, SQL_C_TIMESTAMP, &ts, sizeof(ts), &dataSize));
++		CHKGetData(1, SQL_C_TIMESTAMP, &ts, sizeof(ts), &dataSize, "S");
+ 		sprintf((char *) output, "%04d-%02d-%02d %02d:%02d:%02d.000", ts.year, ts.month, ts.day, ts.hour, ts.minute, ts.second);
+ 	} else {
+-		CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize));
++		CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &dataSize, "S");
+ 	}
+ 
+ 	printf("Date returned: %s\n", output);
+@@ -40,13 +35,8 @@ DoTest(int n)
+ 		exit(1);
+ 	}
+ 
+-	res = SQLFetch(Statement);
+-	if (res != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Unable to fetch row");
+-
+-	res = SQLCloseCursor(Statement);
+-	if (!SQL_SUCCEEDED(res))
+-		ODBC_REPORT_ERROR("Unable to close cursor");
++	CHKFetch("No");
++	CHKCloseCursor("SI");
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c
+index 3739957..234e45a 100644
+--- a/src/odbc/unittests/describecol.c
++++ b/src/odbc/unittests/describecol.c
+@@ -6,7 +6,7 @@
+  * test what say SQLDescribeCol about precision using some type
+  */
+ 
+-static char software_version[] = "$Id: describecol.c,v 1.14 2008/01/20 14:23:59 freddy77 Exp $";
++static char software_version[] = "$Id: describecol.c,v 1.15 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -268,8 +268,7 @@ main(int argc, char *argv[])
+ 				continue;
+ 			}
+ 
+-			if (!SQL_SUCCEEDED(SQLFetch(Statement)))
+-				ODBC_REPORT_ERROR("Unable to fetch row");
++			CHKFetch("SI");
+ 			SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 			get_attr_p = get_attr_ird;
+ 		}
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index d8cffb2..1475b6b 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.4 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -11,10 +11,7 @@ static void ReadError(void);
+ static void
+ ReadError(void)
+ {
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
+ 	printf("Message: %s\n", output);
+ }
+ 
+@@ -45,10 +42,9 @@ main(int argc, char *argv[])
+ 
+ 		/* TODO when multiple row fetch available test for error on some columns */
+ 
+-		CHK(SQLFetch, (Statement));
+-		CHK(SQLFetch, (Statement));
+-		if (SQLFetch(Statement) != SQL_ERROR)
+-			ODBC_REPORT_ERROR("SQLFetch succeed when it shouldn't");
++		CHKFetch("S");
++		CHKFetch("S");
++		CHKFetch("E");
+ 	}
+ 
+ 	ReadError();
+@@ -62,12 +58,11 @@ main(int argc, char *argv[])
+ 	SQLFetch(Statement);
+ 	SQLMoreResults(Statement);
+ 
+-	CHK(SQLAllocStmt, (Connection, &stmt));
++	CHKAllocStmt(&stmt, "S");
+ 
+ 	Command(Statement, "SELECT * FROM sysobjects");
+ 
+-	if (CommandWithResult(stmt, "SELECT * FROM sysobjects") != SQL_ERROR)
+-		ODBC_REPORT_ERROR("Error expected");
++	CHKR(CommandWithResult, (stmt, "SELECT * FROM sysobjects"), "E");
+ 
+ 	tmp_stmt = Statement;
+ 	Statement = stmt;
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 6998ac2..7908880 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -50,7 +50,7 @@
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.6 2007/11/26 18:12:31 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+@@ -272,7 +272,6 @@ fake_thread_proc(void * arg)
+ int
+ main(int argc, char **argv)
+ {
+-	SQLHSTMT hstmt = NULL;
+ 	SQLLEN sql_nts = SQL_NTS;
+ 	const char *query;
+ 	SQLINTEGER id = 0;
+@@ -316,8 +315,7 @@ main(int argc, char **argv)
+ 	/* real test */
+ 	Command(Statement, "CREATE TABLE #test(i int, c varchar(40))");
+ 
+-	if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, Connection, &hstmt)))
+-		return 1;
++	ResetStatement();
+ 
+ 	/* do not take into account connection statistics */
+ 	round_trips = 0;
+@@ -325,30 +323,17 @@ main(int argc, char **argv)
+ 
+ 	query = "insert into #test values (?, ?)";
+ 
+-	if (!SQL_SUCCEEDED(SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts))
+-	    ||
+-	    !SQL_SUCCEEDED(SQLBindParameter
+-			   (hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts))) 
+-	{
+-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-		return 1;
+-	}
+-
+-	if (!SQL_SUCCEEDED(SQLPrepare(hstmt, (SQLCHAR *) query, SQL_NTS))) {
+-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-		return 1;
+-	}
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
++	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+ 
++	CHKPrepare((SQLCHAR *) query, SQL_NTS, "SI");
+ 	for (id = 0; id < num_inserts; id++) {
+ 		sprintf(string, "This is a test (%d)", (int) id);
+-		if (!SQL_SUCCEEDED(SQLExecute(hstmt))) {
+-			SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-			return 1;
+-		}
+-		SQLFreeStmt(hstmt, SQL_CLOSE);
++		CHKExecute("SI");
++		CHKFreeStmt(SQL_CLOSE, "S");
+ 	}
+ 
+-	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
++	ResetStatement();
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/funccall.c b/src/odbc/unittests/funccall.c
+index bf80de9..d5a1323 100644
+--- a/src/odbc/unittests/funccall.c
++++ b/src/odbc/unittests/funccall.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?)} syntax and run */
+ 
+-static char software_version[] = "$Id: funccall.c,v 1.15 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: funccall.c,v 1.16 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -19,16 +19,15 @@ main(int argc, char *argv[])
+ 
+ 	Command(Statement, "create proc simpleresult @i int as begin return @i end");
+ 
+-	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2));
++	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
++	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
+-
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ \n?\t\r= call simpleresult(?)}", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "{ \n?\t\r= call simpleresult(?)}", SQL_NTS, "S");
+ 
+ 	input = 123;
+ 	ind2 = sizeof(input);
+ 	output = 0xdeadbeef;
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	if (output != 123) {
+ 		printf("Invalid result\n");
+@@ -48,7 +47,7 @@ main(int argc, char *argv[])
+ 	input = 567;
+ 	ind2 = sizeof(input);
+ 	output = 0xdeadbeef;
+-	CHK(SQLExecDirect, (Statement, (SQLCHAR *) "{?=call simpleresult(?)}", SQL_NTS));
++	CHKExecDirect((SQLCHAR *) "{?=call simpleresult(?)}", SQL_NTS, "S");
+ 
+ 	if (output != 567) {
+ 		fprintf(stderr, "Invalid result\n");
+@@ -56,10 +55,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* should return "Invalid cursor state" */
+-	if (SQLFetch(Statement) != SQL_ERROR) {
+-		fprintf(stderr, "Data not expected\n");
+-		exit(1);
+-	}
++	CHKFetch("E");
+ 
+ 	Command(Statement, "drop proc simpleresult");
+ 
+@@ -72,12 +68,12 @@ main(int argc, char *argv[])
+ 	Command(Statement,
+ 		"create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind));
+-	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2));
+-	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &out1,   0,            &ind3));
+-	CHK(SQLBindParameter, (Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR,  SQL_VARCHAR, 20, 0, out2,    sizeof(out2), &ind4));
++	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind,  "S");
++	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2, "S");
++	CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &out1,   0,            &ind3, "S");
++	CHKBindParameter(4, SQL_PARAM_OUTPUT, SQL_C_CHAR,  SQL_VARCHAR, 20, 0, out2,    sizeof(out2), &ind4, "S");
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ \n?\t\r= call simpleresult2(?,?,?)}", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "{ \n?\t\r= call simpleresult2(?,?,?)}", SQL_NTS, "S");
+ 
+ 	input = 987;
+ 	ind2 = sizeof(input);
+@@ -85,7 +81,7 @@ main(int argc, char *argv[])
+ 	output = 0xdeadbeef;
+ 	ind3 = SQL_DATA_AT_EXEC;
+ 	ind4 = SQL_DEFAULT_PARAM;
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	if (output != 987 || ind3 <= 0 || ind4 <= 0 || out1 != 6789 || strcmp(out2, "test foo") != 0) {
+ 		printf("ouput = %d ind3 = %d ind4 = %d out1 = %d out2 = %s\n", (int) output, (int) ind3, (int) ind4, (int) out1,
+@@ -114,23 +110,22 @@ main(int argc, char *argv[])
+ 	Command(Statement, "create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
+ 	SQLCloseCursor(Statement);
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ ? = CALL rpc_read ( ?, ? ) }" , SQL_NTS));
++	CHKPrepare((SQLCHAR *) "{ ? = CALL rpc_read ( ?, ? ) }" , SQL_NTS, "S");
+ 
+ 	ind = 0;
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
++	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+ 
+ 	ind2 = 0;
+-	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2));
++	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
+ 
+ 	ind3 = 8;
+-	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3));
++	CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_VARBINARY, 8, 0, out2, 8, &ind3, "S");
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Data not expected\n");
++	CHKFetch("No");
+ 
+ 	ResetStatement();
+ 	Command(Statement, "drop proc rpc_read");
+@@ -151,11 +146,11 @@ main(int argc, char *argv[])
+ 
+ 		ResetStatement();
+ 
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *) "{ call sp_test(?)}", SQL_NTS));
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind));
++		CHKPrepare((SQLCHAR *) "{ call sp_test(?)}", SQL_NTS, "S");
++		CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+ 
+ 		output = 0xdeadbeef;
+-		CHK(SQLExecute, (Statement));
++		CHKExecute("S");
+ 
+ 		if (output != 456) {
+ 			fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 7f8c9b6..bb0b542 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.36 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.37 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -55,28 +55,28 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 
+ 	if (use_cursors) {
+ 		ResetStatement();
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0));
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+ 	}
+ 
+ 	/* bind parameter */
+ 	if (exec_direct) {
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
+-			     sizeof(out_buf), &out_len));
++		CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
++			     sizeof(out_buf), &out_len, "S");
+ 
+ 		/* call store procedure */
+-		CHK(SQLExecDirect, (Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS));
++		CHKExecDirect((SQLCHAR *) "{call spTestProc(?)}", SQL_NTS, "S");
+ 	} else {
+ 		if (prepare_before)
+-			CHK(SQLPrepare, (Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS));
++			CHKPrepare((SQLCHAR *) "{call spTestProc(?)}", SQL_NTS, "S");
+ 
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
+-			     sizeof(out_buf), &out_len));
++		CHKBindParameter(1, SQL_PARAM_OUTPUT, out_c_type, out_sql_type, precision, 0, out_buf,
++			     sizeof(out_buf), &out_len, "S");
+ 
+ 		if (!prepare_before)
+-			CHK(SQLPrepare, (Statement, (SQLCHAR *) "{call spTestProc(?)}", SQL_NTS));
++			CHKPrepare((SQLCHAR *) "{call spTestProc(?)}", SQL_NTS, "S");
+ 
+-		CHK(SQLExecute, (Statement));
++		CHKExecute("S");
+ 	}
+ 
+ 	/* test results */
+@@ -137,12 +137,9 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	sprintf(sbuf, "SELECT CONVERT(%s, %s%.*s%s)", type, sep, (int) value_len, value_to_convert, sep);
+ 	Command(Statement, sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+-	if (!SQL_SUCCEEDED(SQLFetch(Statement)))
+-		ODBC_REPORT_ERROR("Expected row");
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Row not expected");
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Recordset not expected");
++	CHKFetch("SI");
++	CHKFetch("No");
++	CHKMoreResults("No");
+ 	if (use_nts) {
+ 		out_len = SQL_NTS;
+ 		use_nts = 0;
+@@ -155,40 +152,32 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 
+ 	if (use_cursors) {
+ 		ResetStatement();
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0));
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+ 	}
+ 
+ 	/* insert data using prepared statements */
+ 	sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)");
+ 	if (exec_direct) {
+-		SQLRETURN rc;
++		CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len, "S");
+ 
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
+-
+-		rc = SQLExecDirect(Statement, (SQLCHAR *) sbuf, SQL_NTS);
+-		if (check_truncation) {
+-			if (rc != SQL_ERROR)
+-				ODBC_REPORT_ERROR("SQLExecDirect should return error!");
+-		} else if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("SQLExecDirect() failure!");
++		if (check_truncation)
++			CHKExecDirect((SQLCHAR *) sbuf, SQL_NTS, "E");
++		else
++			CHKExecDirect((SQLCHAR *) sbuf, SQL_NTS, "SNo");
+ 	} else {
+-		SQLRETURN rc;
+-
+ 		if (prepare_before)
+-			CHK(SQLPrepare, (Statement, (SQLCHAR *) sbuf, SQL_NTS));
++			CHKPrepare((SQLCHAR *) sbuf, SQL_NTS, "S");
+ 
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len));
++		CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, out_buf, sizeof(out_buf), &out_len, "S");
+ 
+ 		if (!prepare_before)
+-			CHK(SQLPrepare, (Statement, (SQLCHAR *) sbuf, SQL_NTS));
+-
+-		rc = SQLExecute(Statement);
+-		if (check_truncation) {
+-			if (rc != SQL_ERROR)
+-				ODBC_REPORT_ERROR("SQLExecute should return error!");
+-		} else if (rc != SQL_SUCCESS && rc != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("SQLExecute() failure!");
++			CHKPrepare((SQLCHAR *) sbuf, SQL_NTS, "S");
++
++		if (check_truncation)
++			CHKExecute("E");
++		else
++			CHKExecute("SNo");
+ 	}
+ 
+ 	/* check is row is present */
+@@ -200,11 +189,9 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+ 		Command(Statement, sbuf);
+ 
+-		CHK(SQLFetch, (Statement));
+-		if (SQLFetch(Statement) != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("Row not expected");
+-		if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("Recordset not expected");
++		CHKFetch("S");
++		CHKFetch("No");
++		CHKMoreResults("No");
+ 	}
+ 	check_truncation = 0;
+ 	Command(Statement, "DROP TABLE #tmp_insert");
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index d827e42..b570f7a 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.8 2008/10/27 14:23:23 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.9 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -12,17 +12,8 @@ ReadError(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT
+-					, Statement
+-					, 1
+-					, (SQLCHAR *) odbc_sqlstate
+-					, NULL
+-					, (SQLCHAR *) odbc_err
+-					, sizeof(odbc_err)
+-					, NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate,
++		      NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+ 	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+ }
+ 
+@@ -30,7 +21,6 @@ static void
+ test_err(const char *data, int c_type, const char *state)
+ {
+ 	char sql[128];
+-	SQLRETURN rc;
+ 	SQLLEN ind;
+ 	const unsigned int buf_size = 128;
+ 	char *buf = (char *) malloc(buf_size);
+@@ -38,10 +28,8 @@ test_err(const char *data, int c_type, const char *state)
+ 	sprintf(sql, "SELECT '%s'", data);
+ 	Command(Statement, sql);
+ 	SQLFetch(Statement);
+-	rc = SQLGetData(Statement, 1, c_type, buf, buf_size, &ind);
++	CHKGetData(1, c_type, buf, buf_size, &ind, "E");
+ 	free(buf);
+-	if (rc != SQL_ERROR)
+-		ODBC_REPORT_ERROR("SQLGetData error expected");
+ 	ReadError();
+ 	if (strcmp(odbc_sqlstate, state) != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+@@ -89,23 +77,18 @@ main(int argc, char *argv[])
+ 		/* TODO test with VARCHAR too */
+ 		Command(Statement, "SELECT CONVERT(TEXT,'Prova')");
+ 
+-		CHK(SQLFetch, (Statement));
++		CHKFetch("S");
+ 
+ 		/* these 2 tests test an old severe BUG in FreeTDS */
+-		if (SQLGetData(Statement, 1, type, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
+-			ODBC_REPORT_ERROR("Unable to get data");
+-
+-		if (SQLGetData(Statement, 1, type, buf, 0, NULL) != SQL_SUCCESS_WITH_INFO)
+-			ODBC_REPORT_ERROR("Unable to get data");
+-
+-		if (SQLGetData(Statement, 1, type, buf, 3 * lc, NULL) != SQL_SUCCESS_WITH_INFO)
+-			ODBC_REPORT_ERROR("Unable to get data");
++		CHKGetData(1, type, buf, 0, NULL, "I");
++		CHKGetData(1, type, buf, 0, NULL, "I");
++		CHKGetData(1, type, buf, 3 * lc, NULL, "I");
+ 		if (mycmp(buf, "Pr") != 0) {
+ 			printf("Wrong data result 1\n");
+ 			exit(1);
+ 		}
+ 
+-		CHK(SQLGetData, (Statement, 1, type, buf, 16, NULL));
++		CHKGetData(1, type, buf, 16, NULL, "S");
+ 		if (mycmp(buf, "ova") != 0) {
+ 			printf("Wrong data result 2 res = '%s'\n", buf);
+ 			exit(1);
+@@ -116,16 +99,15 @@ main(int argc, char *argv[])
+ 		/* test with varchar, not blob but variable */
+ 		Command(Statement, "SELECT CONVERT(VARCHAR(100), 'Other test')");
+ 
+-		CHK(SQLFetch, (Statement));
++		CHKFetch("S");
+ 
+-		if (SQLGetData(Statement, 1, type, buf, 7 * lc, NULL) != SQL_SUCCESS_WITH_INFO)
+-			ODBC_REPORT_ERROR("Unable to get data");
++		CHKGetData(1, type, buf, 7 * lc, NULL, "I");
+ 		if (mycmp(buf, "Other ") != 0) {
+ 			printf("Wrong data result 1\n");
+ 			exit(1);
+ 		}
+ 
+-		CHK(SQLGetData, (Statement, 1, type, buf, 16, NULL));
++		CHKGetData(1, type, buf, 16, NULL, "S");
+ 		if (mycmp(buf, "test") != 0) {
+ 			printf("Wrong data result 2 res = '%s'\n", buf);
+ 			exit(1);
+@@ -143,17 +125,16 @@ main(int argc, char *argv[])
+ 	/* test with fixed length */
+ 	Command(Statement, "SELECT CONVERT(INT, 12345)");
+ 
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 
+ 	int_buf = 0xdeadbeef;
+-	CHK(SQLGetData, (Statement, 1, SQL_C_SLONG, &int_buf, 0, NULL));
++	CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "S");
+ 	if (int_buf != 12345) {
+ 		printf("Wrong data result\n");
+ 		exit(1);
+ 	}
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_SLONG, &int_buf, 0, NULL) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Unable to get data");
++	CHKGetData(1, SQL_C_SLONG, &int_buf, 0, NULL, "No");
+ 	if (int_buf != 12345) {
+ 		printf("Wrong data result 2 res = %d\n", (int) int_buf);
+ 		exit(1);
+@@ -186,18 +167,17 @@ main(int argc, char *argv[])
+ 		for (;;) {
+ 			Command(Statement, "SELECT CONVERT(TEXT,'')");
+ 
+-			CHK(SQLFetch, (Statement));
++			CHKFetch("S");
+ 
+ 			len = 1234;
+-			CHK(SQLGetData, (Statement, 1, type, buf, lc, &len));
++			CHKGetData(1, type, buf, lc, &len, "S");
+ 
+ 			if (len != 0) {
+ 				fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
+ 				return 1;
+ 			}
+ 
+-			if (SQLGetData(Statement, 1, type, buf, lc, NULL) != SQL_NO_DATA)
+-				ODBC_REPORT_ERROR("invalid return from SQLGetData");
++			CHKGetData(1, type, buf, lc, NULL, "No");
+ 			ResetStatement();
+ 
+ 			if (type != SQL_C_CHAR)
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+index a911f10..c106b7b 100755
+--- a/src/odbc/unittests/hidden.c
++++ b/src/odbc/unittests/hidden.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.5 2008/10/17 12:21:10 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -23,7 +23,7 @@ main(int argc, char **argv)
+ 
+ 	Command(Statement, "SELECT c, b FROM #tmp1");
+ 
+-	CHK(SQLNumResultCols, (Statement, &cnt));
++	CHKNumResultCols(&cnt, "S");
+ 
+ 	if (cnt != 2) {
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+@@ -34,14 +34,14 @@ main(int argc, char **argv)
+ 	/* test hidden column with cursors*/
+ 	CheckCursor();
+ 
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER));
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT * FROM #t1", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1", SQL_NTS, "S");
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+-	CHK(SQLNumResultCols, (Statement, &cnt));
++	CHKNumResultCols(&cnt, "S");
+ 
+ 	if (cnt != 3) {
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+diff --git a/src/odbc/unittests/insert_speed.c b/src/odbc/unittests/insert_speed.c
+index 9e47343..6fa5cbc 100644
+--- a/src/odbc/unittests/insert_speed.c
++++ b/src/odbc/unittests/insert_speed.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: insert_speed.c,v 1.6 2007/11/26 18:12:31 freddy77 Exp $";
++static char software_version[] = "$Id: insert_speed.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SQL_QUERY_LENGTH 80
+@@ -10,105 +10,54 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* I don't remember where this test came ... - freddy77 */
+ 
+-static int
++static void
+ insert_test_auto(void)
+ {
+-	SQLHSTMT hstmt = NULL;
+ 	SQLLEN sql_nts = SQL_NTS;
+-	char query[SQL_QUERY_LENGTH];
+ 	SQLINTEGER id = 0;
+ 	char string[64];
+ 
+-	if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, Connection, &hstmt))) {
+-		return (-1);
+-	}
+-
+-	strcpy(query, "insert into test values (?, ?)");
+-
+-	if (!SQL_SUCCEEDED(SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts))
+-	    ||
+-	    !SQL_SUCCEEDED(SQLBindParameter
+-			   (hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts))) {
+-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-		return (-1);
+-	}
++	ResetStatement();
+ 
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
++	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+ 
+-	if (!SQL_SUCCEEDED(SQLPrepare(hstmt, (SQLCHAR *) query, SQL_NTS))) {
+-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-		return (-1);
+-	}
+-
++	CHKPrepare((SQLCHAR *) "insert into test values (?, ?)", SQL_NTS, "SI");
+ 	for (id = 0; id < 20; id++) {
+ 		sprintf(string, "This is a test (%d)", (int) id);
+-		if (!SQL_SUCCEEDED(SQLExecute(hstmt))) {
+-			SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-			return (-1);
+-		}
++		CHKExecute("SI");
+ 	}
+ 
+-	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-	return (0);
++	ResetStatement();
+ }
+ 
+ 
+-static int
++static void
+ insert_test_man(void)
+ {
+-	SQLHSTMT hstmt = NULL;
+ 	SQLLEN sql_nts = SQL_NTS;
+ 	SQLINTEGER commit_off = SQL_AUTOCOMMIT_OFF;
+ 	SQLINTEGER commit_on = SQL_AUTOCOMMIT_ON;
+-	char query[SQL_QUERY_LENGTH];
+ 	SQLINTEGER id = 0;
+ 
+ 	char string[64];
+ 
+-	if (!SQL_SUCCEEDED(SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_off), SQL_IS_INTEGER))) {
+-		fprintf(stderr, "Unable to set autocommit mode\n");
+-		return (-1);
+-	}
+-
+-	if (!SQL_SUCCEEDED(SQLAllocHandle(SQL_HANDLE_STMT, Connection, &hstmt))) {
+-		fprintf(stderr, "Unable to allocate statement handle\n");
+-		return (-1);
+-	}
+-
+-	strcpy(query, "insert into test values (?, ?)");
+-
+-	if (!SQL_SUCCEEDED(SQLBindParameter(hstmt, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts))
+-	    ||
+-	    !SQL_SUCCEEDED(SQLBindParameter
+-			   (hstmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts))) {
+-		SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_on), SQL_IS_INTEGER);
+-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-		fprintf(stderr, "unable to bind parameters\n");
+-		return (-1);
+-	}
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(commit_off), SQL_IS_INTEGER, "SI");
+ 
++	ResetStatement();
+ 
+-	if (!SQL_SUCCEEDED(SQLPrepare(hstmt, (SQLCHAR *) query, SQL_NTS))) {
+-		SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_on), SQL_IS_INTEGER);
+-		SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-		fprintf(stderr, "Unable to prepare statement\n");
+-		return (-1);
+-	}
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
++	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+ 
++	CHKPrepare((SQLCHAR *) "insert into test values (?, ?)", SQL_NTS, "SI");
+ 	for (id = 0; id < 20; id++) {
+ 		sprintf(string, "This is a test (%d)", (int) id);
+-		if (!SQL_SUCCEEDED(SQLExecute(hstmt))) {
+-			SQLEndTran(SQL_HANDLE_DBC, hstmt, SQL_ROLLBACK);
+-			SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_on), SQL_IS_INTEGER);
+-			SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-			fprintf(stderr, "Unable to execute statement %d\n", (int) id);
+-			return (-1);
+-		}
++		CHKExecute("SI");
+ 	}
+ 
+ 	SQLEndTran(SQL_HANDLE_DBC, Connection, SQL_COMMIT);
+ 	SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_on), SQL_IS_INTEGER);
+-	SQLFreeHandle(SQL_HANDLE_STMT, hstmt);
+-	return (0);
++	ResetStatement();
+ }
+ 
+ int
+@@ -119,13 +68,11 @@ main(int argc, char **argv)
+ 	CommandWithResult(Statement, "DROP TABLE test");
+ 	Command(Statement, "CREATE TABLE test(i int, c varchar(40))");
+ 
+-	if (insert_test_man() < 0)
+-		return 1;
++	insert_test_man();
+ 
+ 	Command(Statement, "DELETE FROM test");
+ 
+-	if (insert_test_auto() < 0)
+-		return 1;
++	insert_test_auto();
+ 
+ 	Command(Statement, "DROP TABLE test");
+ 
+diff --git a/src/odbc/unittests/lang_error.c b/src/odbc/unittests/lang_error.c
+index 90192b4..c974cbd 100644
+--- a/src/odbc/unittests/lang_error.c
++++ b/src/odbc/unittests/lang_error.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test if SQLExecDirect return error if a error in row is returned */
+ 
+-static char software_version[] = "$Id: lang_error.c,v 1.3 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: lang_error.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -11,10 +11,7 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	/* issue print statement and test message returned */
+-	if (CommandWithResult(Statement, "SELECT DATEADD(dd,-100000,getdate())") != SQL_ERROR) {
+-		fprintf(stderr, "SQLExecDirect should return SQL_ERROR\n");
+-		return 1;
+-	}
++	CHKR(CommandWithResult, (Statement, "SELECT DATEADD(dd,-100000,getdate())"), "E");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/moreandcount.c b/src/odbc/unittests/moreandcount.c
+index 95ae329..4ecf7af 100644
+--- a/src/odbc/unittests/moreandcount.c
++++ b/src/odbc/unittests/moreandcount.c
+@@ -2,34 +2,10 @@
+ 
+ /* Test for SQLMoreResults and SQLRowCount on batch */
+ 
+-static char software_version[] = "$Id: moreandcount.c,v 1.15 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: moreandcount.c,v 1.16 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+-NextResults(SQLRETURN expected, int line)
+-{
+-	if (SQLMoreResults(Statement) != expected) {
+-		if (expected == SQL_SUCCESS)
+-			fprintf(stderr, "Expected another recordset line %d\n", line);
+-		else
+-			fprintf(stderr, "Not expected another recordset line %d\n", line);
+-		exit(1);
+-	}
+-}
+-
+-static void
+-Fetch(SQLRETURN expected)
+-{
+-	if (SQLFetch(Statement) != expected) {
+-		if (expected == SQL_SUCCESS)
+-			fprintf(stderr, "Expected another record\n");
+-		else
+-			fprintf(stderr, "Not expected another record\n");
+-		exit(1);
+-	}
+-}
+-
+-static void
+ DoTest(int prepare)
+ {
+ 	int n = 0;
+@@ -45,59 +21,59 @@ DoTest(int prepare)
+ 		"UPDATE #tmp1 SET i=i+1 WHERE i >= 2";
+ 
+ 	if (prepare) {
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *) query, SQL_NTS));
+-		CHK(SQLExecute, (Statement));
++		CHKPrepare((SQLCHAR *) query, SQL_NTS, "S");
++		CHKExecute("S");
+ 	} else {
+ 
+ 		/* execute a batch command select insert insert select and check rows */
+-		CHK(SQLExecDirect, (Statement, (SQLCHAR *) query, SQL_NTS));
++		CHKExecDirect((SQLCHAR *) query, SQL_NTS, "S");
+ 	}
+ 	if (!prepare) {
+ 		printf("Result %d\n", ++n);
+ 		CHECK_COLS(0);
+ 		CHECK_ROWS(1);
+-		NextResults(SQL_SUCCESS, __LINE__);
++		CHKMoreResults("S");
+ 	}
+ 	printf("Result %d\n", ++n);
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+-	Fetch(SQL_SUCCESS);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
++	CHKFetch("S");
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+-	Fetch(SQL_NO_DATA);
++	CHKFetch("No");
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(2);
+-	NextResults(SQL_SUCCESS, __LINE__);
++	CHKMoreResults("S");
+ 	if (!prepare) {
+ 		printf("Result %d\n", ++n);
+ 		CHECK_COLS(0);
+ 		CHECK_ROWS(1);
+-		NextResults(SQL_SUCCESS, __LINE__);
++		CHKMoreResults("S");
+ 		printf("Result %d\n", ++n);
+ 		CHECK_COLS(0);
+ 		CHECK_ROWS(2);
+-		NextResults(SQL_SUCCESS, __LINE__);
++		CHKMoreResults("S");
+ 	}
+ 	printf("Result %d\n", ++n);
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+-	Fetch(SQL_NO_DATA);
++	CHKFetch("No");
+ 	CHECK_COLS(1);
+ 	if (prepare) {
+ 		/* collapse 2 recordset... after a lot of testing this is the behavior! */
+ 		CHECK_ROWS(2);
+ 	} else {
+ 		CHECK_ROWS(1);
+-		NextResults(SQL_SUCCESS, __LINE__);
++		CHKMoreResults("S");
+ 		CHECK_COLS(0);
+ 		CHECK_ROWS(2);
+ 	}
+ 
+-	NextResults(SQL_NO_DATA, __LINE__);
++	CHKMoreResults("No");
+ #ifndef TDS_NO_DM
+ 	if (!prepare)
+ 		CHECK_COLS(-1);
+diff --git a/src/odbc/unittests/norowset.c b/src/odbc/unittests/norowset.c
+index b18245c..9a2117d 100644
+--- a/src/odbc/unittests/norowset.c
++++ b/src/odbc/unittests/norowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: norowset.c,v 1.6 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: norowset.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Test that a select following a store procedure execution return results */
+@@ -8,7 +8,6 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int
+ main(int argc, char *argv[])
+ {
+-	int res;
+ 	char output[256];
+ 	SQLLEN dataSize;
+ 
+@@ -22,25 +21,18 @@ main(int argc, char *argv[])
+ 
+ 	/* note, mssql 2005 seems to not return row for tempdb, use always master */
+ 	Command(Statement, "select name from master..sysobjects where name = 'sysobjects'");
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 
+-	CHK(SQLGetData, (Statement, 1, SQL_C_CHAR, output, sizeof(output), &dataSize));
++	CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &dataSize, "S");
+ 
+ 	if (strcmp(output, "sysobjects") != 0) {
+ 		printf("Unexpected result\n");
+ 		exit(1);
+ 	}
+ 
+-	res = SQLFetch(Statement);
+-	if (res != SQL_NO_DATA) {
+-		fprintf(stderr, "Row not expected\n");
+-		CheckReturn();
+-	}
++	CHKFetch("No");
+ 
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Not expected another recordset\n");
+-		exit(1);
+-	}
++	CHKMoreResults("No");
+ 
+ 	Command(Statement, "drop proc sp_norowset_test");
+ 
+diff --git a/src/odbc/unittests/paramcore.c b/src/odbc/unittests/paramcore.c
+index 0addd1f..5d69ae3 100644
+--- a/src/odbc/unittests/paramcore.c
++++ b/src/odbc/unittests/paramcore.c
+@@ -4,7 +4,7 @@
+  * Try to make core dump using SQLBindParameter
+  */
+ 
+-static char software_version[] = "$Id: paramcore.c,v 1.4 2006/07/25 08:11:00 freddy77 Exp $";
++static char software_version[] = "$Id: paramcore.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{call sp_paramcore_test(?)}"
+@@ -29,7 +29,6 @@ ReadError(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	SQLRETURN rc;
+ 	SQLLEN cb = SQL_NTS;
+ 
+ 	use_odbc_version3 = 1;
+@@ -40,20 +39,20 @@ main(int argc, char *argv[])
+ 	Command(Statement, "create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");
+ 
+ 	/* here we pass a NULL buffer for input SQL_NTS */
+-	rc = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb);
++	SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb);
+ 	ReadError();
+ 
+ 	cb = SQL_NTS;
+-	rc = CommandWithResult(Statement, SP_TEXT);
++	CommandWithResult(Statement, SP_TEXT);
+ 	ReadError();
+ 	ResetStatement();
+ 
+ 	/* here we pass a NULL buffer for input */
+-	rc = SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_VARCHAR, 18, 0, NULL, OUTSTRING_LEN, &cb);
++	SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_VARCHAR, 18, 0, NULL, OUTSTRING_LEN, &cb);
+ 	ReadError();
+ 
+ 	cb = 1;
+-	rc = CommandWithResult(Statement, SP_TEXT);
++	CommandWithResult(Statement, SP_TEXT);
+ 	ReadError();
+ 	ResetStatement();
+ 
+@@ -64,11 +63,11 @@ main(int argc, char *argv[])
+ #if 0	/* this fails even on native platforms */
+ 	/* here we pass a NULL buffer for output */
+ 	cb = sizeof(SQL_NUMERIC_STRUCT);
+-	rc = SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_NUMERIC, SQL_NUMERIC, 18, 0, NULL, OUTSTRING_LEN, &cb);
++	SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_NUMERIC, SQL_NUMERIC, 18, 0, NULL, OUTSTRING_LEN, &cb);
+ 	ReadError();
+ 
+ 	cb = 1;
+-	rc = CommandWithResult(Statement, SP_TEXT);
++	CommandWithResult(Statement, SP_TEXT);
+ 	ReadError();
+ 	ResetStatement();
+ #endif
+diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c
+index dc382cb..9b17a27 100644
+--- a/src/odbc/unittests/params.c
++++ b/src/odbc/unittests/params.c
+@@ -3,7 +3,7 @@
+ /* Test for store procedure and params */
+ /* Test from Tom Rogers */
+ 
+-static char software_version[] = "$Id: params.c,v 1.9 2008/02/08 09:28:03 freddy77 Exp $";
++static char software_version[] = "$Id: params.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* SP definition */
+@@ -39,21 +39,21 @@ Test(int bind_before)
+ 	Command(Statement, sp_define);
+ 
+ 	if (!bind_before)
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)));
++		CHKPrepare((SQLCHAR *) SP_TEXT, strlen(SP_TEXT), "S");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode));
+-	CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT,  SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam,    0, &cbInParam));
+-	CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam,   0, &cbOutParam));
++	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode, "S");
++	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam,    0, &cbInParam,    "S");
++	CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam,   0, &cbOutParam,   "S");
+ 
+ 	OutString[0] = '\0';
+ 	strcpy(OutString, "Test");	/* Comment this line and we get an error!  Why? */
+-	CHK(SQLBindParameter, (Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, 
+-	    OUTSTRING_LEN, &cbOutString));
++	CHKBindParameter(4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, 
++	    OUTSTRING_LEN, &cbOutString, "S");
+ 
+ 	if (bind_before)
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)));
++		CHKPrepare((SQLCHAR *) SP_TEXT, strlen(SP_TEXT), "S");
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	Command(Statement, "DROP PROC spTestProc");
+ 
+diff --git a/src/odbc/unittests/prepare_results.c b/src/odbc/unittests/prepare_results.c
+index 8ebdb4e..da1549e 100644
+--- a/src/odbc/unittests/prepare_results.c
++++ b/src/odbc/unittests/prepare_results.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for data format returned from SQLPrepare */
+ 
+-static char software_version[] = "$Id: prepare_results.c,v 1.9 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: prepare_results.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -22,9 +22,9 @@ main(int argc, char *argv[])
+ 	SQLMoreResults(Statement);
+ 
+ 	/* test query returns column information for update */
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS, "S");
+ 
+-	CHK(SQLNumResultCols, (Statement, &count));
++	CHKNumResultCols(&count, "S");
+ 
+ 	if (count != 0) {
+ 		fprintf(stderr, "Wrong number of columns returned. Got %d expected 0\n", (int) count);
+@@ -32,30 +32,30 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* test query returns column information */
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "select * from #odbctestdata select * from #odbctestdata", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
+ 
+-	CHK(SQLNumResultCols, (Statement, &count));
++	CHKNumResultCols(&count, "S");
+ 
+ 	if (count != 3) {
+ 		fprintf(stderr, "Wrong number of columns returned. Got %d expected 3\n", (int) count);
+ 		exit(1);
+ 	}
+ 
+-	CHK(SQLDescribeCol, (Statement, 1, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable));
++	CHKDescribeCol(1, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable, "S");
+ 
+ 	if (type != SQL_INTEGER || strcmp(name, "i") != 0) {
+ 		fprintf(stderr, "wrong column 1 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+ 		exit(1);
+ 	}
+ 
+-	CHK(SQLDescribeCol, (Statement, 2, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable));
++	CHKDescribeCol(2, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable, "S");
+ 
+ 	if (type != SQL_CHAR || strcmp(name, "c") != 0 || (size != 20 && (db_is_microsoft() || size != 40))) {
+ 		fprintf(stderr, "wrong column 2 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+ 		exit(1);
+ 	}
+ 
+-	CHK(SQLDescribeCol, (Statement, 3, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable));
++	CHKDescribeCol(3, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable, "S");
+ 
+ 	if (type != SQL_NUMERIC || strcmp(name, "n") != 0 || size != 34 || digits != 12) {
+ 		fprintf(stderr, "wrong column 3 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+diff --git a/src/odbc/unittests/prepclose.c b/src/odbc/unittests/prepclose.c
+index ff3ca9d..78ae112 100644
+--- a/src/odbc/unittests/prepclose.c
++++ b/src/odbc/unittests/prepclose.c
+@@ -26,7 +26,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: prepclose.c,v 1.3 2006/07/24 09:40:46 freddy77 Exp $";
++static char software_version[] = "$Id: prepclose.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -65,7 +65,7 @@ static int
+ Test(int direct)
+ {
+ 	char buf[256];
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 	unsigned char sqlstate[6];
+ 
+ 	Connect();
+@@ -77,20 +77,11 @@ Test(int direct)
+ 
+ 	/* force disconnection closing socket */
+ 	if (direct)
+-		ret = SQLExecDirect(Statement, (SQLCHAR *) "SELECT 1", SQL_NTS);
++		CHKExecDirect((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
+ 	else
+-		ret = SQLPrepare(Statement, (SQLCHAR *) "SELECT 1", SQL_NTS);
+-	if (ret != SQL_ERROR) {
+-		fprintf(stderr, "Error expected\n");
+-		return 1;
+-	}
++		CHKPrepare((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
+ 
+-	ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL);
+-	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Error not set\n");
+-		Disconnect();
+-		return 1;
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	sqlstate[5] = 0;
+ 	printf("state=%s err=%s\n", (char*) sqlstate, buf);
+ 	
+diff --git a/src/odbc/unittests/preperror.c b/src/odbc/unittests/preperror.c
+index 1a8f17a..e3966bb 100644
+--- a/src/odbc/unittests/preperror.c
++++ b/src/odbc/unittests/preperror.c
+@@ -2,7 +2,7 @@
+ 
+ /* test error on prepared statement, from Nathaniel Talbott test */
+ 
+-static char software_version[] = "$Id: preperror.c,v 1.6 2005/08/14 09:20:53 freddy77 Exp $";
++static char software_version[] = "$Id: preperror.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -10,7 +10,6 @@ main(int argc, char *argv[])
+ {
+ 	SQLLEN cbInString = SQL_NTS;
+ 	char buf[256];
+-	SQLRETURN ret;
+ 	unsigned char sqlstate[6];
+ 
+ 	Connect();
+@@ -18,55 +17,27 @@ main(int argc, char *argv[])
+ 	Command(Statement, "CREATE TABLE #urls ( recdate DATETIME ) ");
+ 
+ 	/* test implicit conversion error */
+-	if (CommandWithResult(Statement, "INSERT INTO #urls ( recdate ) VALUES ( '2003-10-1 10:11:1 0' )") != SQL_ERROR) {
+-		fprintf(stderr, "SQLExecDirect success instead of failing!\n");
+-		return 1;
+-	}
++	CHKExecDirect((SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( '2003-10-1 10:11:1 0' )", SQL_NTS, "E");
+ 
+ 	/* test prepared implicit conversion error */
+-	if (!SQL_SUCCEEDED(SQLPrepare(Statement, (SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( ? )", SQL_NTS))) {
+-		fprintf(stderr, "SQLPrepare failure!\n");
+-		return 1;
+-	}
++	CHKPrepare((SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( ? )", SQL_NTS, "SI");
+ 
+ 	strcpy(buf, "2003-10-1 10:11:1 0");
+-	if (!SQL_SUCCEEDED
+-	    (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 128, 0, buf, sizeof(buf), &cbInString))) {
+-		fprintf(stderr, "SQLBindParameter failure!\n");
+-		return 1;
+-	}
+-
+-	if (SQLExecute(Statement) != SQL_ERROR) {
+-		fprintf(stderr, "SQLExecute succeeded instead of failing! (line %d)\n", __LINE__);
+-		return 1;
+-	}
+-
+-	ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL);
+-	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Error not set (line %d)\n", __LINE__);
+-		return 1;
+-	}
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 128, 0, buf, sizeof(buf), &cbInString, "SI");
++
++	CHKExecute("E");
++
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	printf("err=%s\n", buf);
+ 
+ 	/* assure initial state */
+ 	ResetStatement();
+ 
+ 	/* try to prepare and execute a statement with error (from DBD::ODBC test) */
+-	ret = SQLPrepare(Statement, (SQLCHAR *) "SELECT XXNOTCOLUMN FROM sysobjects", SQL_NTS);
+-
+-	if (ret == SQL_SUCCESS)
+-		ret = SQLExecute(Statement);
+-
+-	if (ret != SQL_ERROR) {
+-		fprintf(stderr, "SQLExecute succeeded instead of failing! (line %d)\n", __LINE__);
+-		return 1;
+-	}
++	if (CHKPrepare((SQLCHAR *) "SELECT XXNOTCOLUMN FROM sysobjects", SQL_NTS, "SE") == SQL_SUCCESS)
++		CHKExecute("E");
+ 
+-	ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL);
+-	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Error not set (line %d)\n", __LINE__);
+-		return 1;
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	printf("err=%s\n", buf);
+ 
+ 
+diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c
+index 45f33dd..d23cea7 100644
+--- a/src/odbc/unittests/print.c
++++ b/src/odbc/unittests/print.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: print.c,v 1.19 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: print.c,v 1.20 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -15,10 +15,7 @@ static const int tds_no_dm = 0;
+ static void
+ ReadError(void)
+ {
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
+ 	printf("Message: %s\n", output);
+ }
+ 
+@@ -27,7 +24,6 @@ test(int odbc3)
+ {
+ 	SQLLEN cnamesize;
+ 	const char *query;
+-	SQLRETURN rc;
+ 
+ 	use_odbc_version3 = odbc3;
+ 
+@@ -50,33 +46,28 @@ test(int odbc3)
+ 	if (odbc3) {
+ 		CHECK_COLS(0);
+ 		CHECK_ROWS(-1);
+-		rc = SQLFetch(Statement);
+-		if (rc != SQL_ERROR)
+-			ODBC_REPORT_ERROR("Still data?");
+-		CHK(SQLMoreResults, (Statement));
++		CHKFetch("E");
++		CHKMoreResults("S");
+ 	}
+     
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+ 
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(-1);
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Still data?");
++	/* check no data */
++	CHKFetch("No");
+ 	CHECK_COLS(1);
+ 	CHECK_ROWS(1);
+ 
+-	/* SQLMoreResults return NO DATA ... */
+-	rc = SQLMoreResults(Statement);
+-	if (rc != SQL_NO_DATA && rc != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("SQLMoreResults should return NO DATA or SUCCESS WITH INFO");
+-
+-	if (tds_no_dm && !odbc3 && rc != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLMoreResults should return NO DATA");
+-
+-	if (odbc3 && rc != SQL_SUCCESS_WITH_INFO)
+-		ODBC_REPORT_ERROR("SQLMoreResults should return SUCCESS WITH INFO");
++	/* SQLMoreResults return NO DATA or SUCCESS WITH INFO ... */
++	if (tds_no_dm && !odbc3)
++		CHKMoreResults("No");
++	else if (odbc3)
++		CHKMoreResults("I");
++	else
++		CHKMoreResults("INo");
+ 
+ 	/*
+ 	 * ... but read error
+@@ -103,9 +94,7 @@ test(int odbc3)
+ 		CHECK_COLS(0);
+ 		CHECK_ROWS(-1);
+ 
+-		rc = SQLMoreResults(Statement);
+-		if (rc != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("SQLMoreResults should return NO DATA");
++		CHKMoreResults("No");
+ 	}
+ 
+ 	/* issue invalid command and test error */
+@@ -116,16 +105,10 @@ test(int odbc3)
+ 	ReadError();
+ 
+ 	/* test no data returned */
+-	if (SQLFetch(Statement) != SQL_ERROR) {
+-		printf("Row fetched ??\n");
+-		return 1;
+-	}
++	CHKFetch("E");
+ 	ReadError();
+ 
+-	if (SQLGetData(Statement, 1, SQL_C_CHAR, output, sizeof(output), &cnamesize) != SQL_ERROR) {
+-		printf("Data ??\n");
+-		return 1;
+-	}
++	CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &cnamesize, "E");
+ 	ReadError();
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index 254ac2e..e5cb613 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.12 2008/10/29 09:56:53 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.13 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -18,7 +18,7 @@ main(int argc, char *argv[])
+ 	const char *p;
+ 	SQLPOINTER ptr;
+ 	unsigned char buf[256], *pb;
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 	int type, lc, sql_type;
+ 
+ 	Connect();
+@@ -30,7 +30,7 @@ main(int argc, char *argv[])
+ 	type = SQL_C_CHAR;
+ 	lc = 1;
+ 	for (;;) {
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind));
++		CHKBindParameter(1, SQL_PARAM_INPUT, type, sql_type, 0, 0, (SQLPOINTER) 123, 0, &ind, "S");
+ 		/* length required */
+ 		ind = SQL_LEN_DATA_AT_EXEC(len * lc);
+ 
+@@ -38,10 +38,9 @@ main(int argc, char *argv[])
+ 		 * test for char 
+ 		 */
+ 
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
++		CHKPrepare((SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS, "S");
+ 
+-		if (SQLExecute(Statement) != SQL_NEED_DATA)
+-			ODBC_REPORT_ERROR("Wrong result executing statement");
++		CHKExecute("Ne");
+ 
+ 		p = test_text;
+ 		n = 5;
+@@ -55,21 +54,20 @@ main(int argc, char *argv[])
+ 			if (l < n)
+ 				n = l;
+ 			if (type == SQL_C_CHAR) {
+-				CHK(SQLPutData, (Statement, (char *) p, n));
++				CHKPutData((char *) p, n, "S");
+ 			} else {
+ 				SQLWCHAR buf[256];
+ 				int i;
+ 				for (i = 0; i < n; ++i)
+ 					buf[i] = p[i];
+-				CHK(SQLPutData, (Statement, (char *) buf, n * lc));
++				CHKPutData((char *) buf, n * lc, "S");
+ 			}
+ 			p += n;
+ 			n *= 2;
+ 		}
+-		CHK(SQLParamData, (Statement, &ptr));
++		CHKParamData(&ptr, "S");
+ 
+-		if (SQLParamData(Statement, &ptr) != SQL_ERROR)
+-			ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++		CHKParamData(&ptr, "E");
+ 
+ 		/* check state  and reset some possible buffers */
+ 		Command(Statement, "DECLARE @i INT");
+@@ -94,18 +92,16 @@ main(int argc, char *argv[])
+ 	 * test for binary 
+ 	 */
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0, 0, (SQLPOINTER) 4567, 0, &ind, "S");
+ 	ind = SQL_LEN_DATA_AT_EXEC(254);
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "UPDATE #putdata SET b = ?", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "UPDATE #putdata SET b = ?", SQL_NTS, "S");
+ 
+-	if (SQLExecute(Statement) != SQL_NEED_DATA)
+-		ODBC_REPORT_ERROR("Wrong result executing statement");
++	CHKExecute("Ne");
+ 
+ 	pb = buf;
+ 	n = 7;
+-	if (SQLParamData(Statement, &ptr) != SQL_NEED_DATA)
+-		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++	CHKParamData(&ptr, "Ne");
+ 	if (ptr != (SQLPOINTER) 4567)
+ 		ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
+ 	while (pb != (buf + 254)) {
+@@ -113,37 +109,33 @@ main(int argc, char *argv[])
+ 
+ 		if (l < n)
+ 			n = l;
+-		CHK(SQLPutData, (Statement, (char *) p, n));
++		CHKPutData((char *) p, n, "S");
+ 		pb += n;
+ 		n *= 2;
+ 	}
+-	CHK(SQLParamData, (Statement, &ptr));
++	CHKParamData(&ptr, "S");
+ 
+-	if (SQLParamData(Statement, &ptr) != SQL_ERROR)
+-		ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++	CHKParamData(&ptr, "E");
+ 
+ 	/* check state  and reset some possible buffers */
+ 	Command(Statement, "DECLARE @i2 INT");
+ 
+ 
+ 	/* test len == 0 case from ML */
+-	CHK(SQLFreeStmt, (Statement, SQL_RESET_PARAMS));
++	CHKFreeStmt(SQL_RESET_PARAMS, "S");
+ 
+ 	type = SQL_C_CHAR;
+ 	for (;;) {
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS));
++		CHKPrepare((SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS, "S");
+ 
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind));
++		CHKBindParameter(1, SQL_PARAM_INPUT, type, SQL_LONGVARCHAR, 0, 0, (PTR) 2, 0, &ind, "S");
+ 
+ 		ind = SQL_LEN_DATA_AT_EXEC(0);
+ 
+-		if ((retcode = SQLExecute(Statement)) != SQL_NEED_DATA) {
+-			printf("Wrong result executing statement (retcode=%d)\n", (int) retcode);
+-			exit(1);
+-		}
+-		while (retcode == SQL_NEED_DATA) {
+-			retcode = SQLParamData(Statement, &ptr);
+-			if (retcode == SQL_NEED_DATA) {
++		CHKExecute("Ne");
++		while (RetCode == SQL_NEED_DATA) {
++			RetCode = SQLParamData(Statement, &ptr);
++			if (RetCode == SQL_NEED_DATA) {
+ 				SQLPutData(Statement, "abc", 3);
+ 			}
+ 		}
+diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c
+index 3395ad4..82a5538 100644
+--- a/src/odbc/unittests/raiserror.c
++++ b/src/odbc/unittests/raiserror.c
+@@ -4,7 +4,7 @@
+ 
+ /* TODO add support for Sybase */
+ 
+-static char software_version[] = "$Id: raiserror.c,v 1.21 2008/02/08 09:28:04 freddy77 Exp $";
++static char software_version[] = "$Id: raiserror.c,v 1.22 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{?=call #tmp1(?,?,?)}"
+@@ -61,14 +61,8 @@ TestResult(SQLRETURN result0, int level, const char *func)
+ 	SqlState[0] = 0;
+ 	MessageText[0] = 0;
+ 	NativeError = 0;
+-	/* result = SQLError(SQL_NULL_HENV, SQL_NULL_HDBC, Statement, SqlState, &NativeError, MessageText, 1000, &TextLength); */
+-	result = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText, sizeof(MessageText),
+-			       &TextLength);
+-	printf("Func=%s Result=%d DIAG REC 1: State=%s Error=%d: %s\n", func, (int) result, SqlState, (int) NativeError, MessageText);
+-	if (!SQL_SUCCEEDED(result)) {
+-		fprintf(stderr, "SQLGetDiagRec error!\n");
+-		exit(1);
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText, sizeof(MessageText), &TextLength, "SI");
++	printf("Func=%s Result=%d DIAG REC 1: State=%s Error=%d: %s\n", func, (int) RetCode, SqlState, (int) NativeError, MessageText);
+ 
+ 	if (strstr(MessageText, "An error occurred") == NULL) {
+ 		fprintf(stderr, "Wrong error returned!\n");
+@@ -84,13 +78,11 @@ CheckData(const char *s, int line)
+ {
+ 	char buf[80];
+ 	SQLLEN ind;
+-	SQLRETURN result;
++	SQLRETURN RetCode;
+ 
+-	result = SQLGetData(Statement, 1, SQL_C_CHAR, buf, sizeof(buf), &ind);
+-	if (result != SQL_SUCCESS && result != SQL_ERROR)
+-		MY_ERROR("SQLFetch invalid result");
++	CHKGetData(1, SQL_C_CHAR, buf, sizeof(buf), &ind, "SE");
+ 
+-	if (result == SQL_ERROR) {
++	if (RetCode == SQL_ERROR) {
+ 		buf[0] = 0;
+ 		ind = 0;
+ 	}
+@@ -153,10 +145,10 @@ Test(int level)
+ 	SQLBindParameter(Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
+ 			 &cbOutString);
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	CheckData("");
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 	CheckData("Here is the first row");
+ 
+ 	result = SQLFetch(Statement);
+@@ -169,10 +161,8 @@ Test(int level)
+ 
+ 		if (result != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("SQLFetch should return NO DATA");
+-		result = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText,
+-				       sizeof(MessageText), &TextLength);
+-		if (result != SQL_NO_DATA)
+-			ODBC_REPORT_ERROR("SQLGetDiagRec should return NO DATA");
++		CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText,
++				       sizeof(MessageText), &TextLength, "No");
+ 		result = SQLMoreResults(Statement);
+ 		expected = level > 10 ? SQL_ERROR : SQL_SUCCESS_WITH_INFO;
+ 		if (result != expected)
+@@ -209,18 +199,17 @@ Test(int level)
+ 	}
+ 
+ 	if (!use_odbc_version3 || !g_nocount) {
+-		CHK(SQLMoreResults, (Statement));
++		CHKMoreResults("S");
+ 		result = SQL_SUCCESS;
+ 	}
+ 
+ 	CheckReturnCode(result, INVALID_RETURN);
+ 
+ 	CheckData("");
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 	CheckData("Here is the last row");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLFetch returned failure");
++	CHKFetch("No");
+ 	CheckData("");
+ 
+ 	if (!use_odbc_version3 || g_nocount)
+@@ -245,7 +234,6 @@ Test(int level)
+ static void
+ Test2(int nocount, int second_select)
+ {
+-	SQLRETURN result;
+ 	char sql[512];
+ 
+ 	g_nocount = nocount;
+@@ -257,9 +245,7 @@ Test2(int nocount, int second_select)
+ 
+ 	sprintf(sql, create_proc, nocount ? "     SET NOCOUNT ON\n" : "",
+ 		second_select ? "     SELECT 'Here is the last row' AS LastResult\n" : "");
+-	result = CommandWithResult(Statement, sql);
+-	if (result != SQL_SUCCESS && result != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Unable to create temporary store");
++	CHKR(CommandWithResult, (Statement, sql), "SNo");
+ 
+ 	Test(5);
+ 
+diff --git a/src/odbc/unittests/rebindpar.c b/src/odbc/unittests/rebindpar.c
+index d814b1c..87bcbea 100644
+--- a/src/odbc/unittests/rebindpar.c
++++ b/src/odbc/unittests/rebindpar.c
+@@ -2,29 +2,33 @@
+ 
+ /* Test for executing SQLExecute and rebinding parameters */
+ 
+-static char software_version[] = "$Id: rebindpar.c,v 1.7 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: rebindpar.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++#define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
++
++static HSTMT stmt;
++
+ static void
+-TestInsert(HSTMT stmt, char *buf)
++TestInsert(char *buf)
+ {
+ 	SQLLEN ind;
+ 	int l = strlen(buf);
+ 	char sql[200];
+ 
+ 	/* insert some data and test success */
+-	CHK(SQLBindParameter, (stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, l, 0, buf, l, &ind));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, l, 0, buf, l, &ind, "S");
+ 
+ 	ind = l;
+-	CHK(SQLExecute, (stmt));
++	CHKExecute("S");
+ 
++	SWAP_STMT(stmt);
+ 	sprintf(sql, "SELECT 1 FROM #tmp1 WHERE c = '%s'", buf);
+ 	Command(Statement, sql);
+-	CHK(SQLFetch, (Statement));
+-	if (SQLFetch(Statement) != SQL_NO_DATA || SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "One row expected!\n");
+-		exit(1);
+-	}
++	CHKFetch("S");
++	CHKFetch("No");
++	CHKMoreResults("No");
++	SWAP_STMT(stmt);
+ }
+ 
+ static void
+@@ -33,7 +37,6 @@ Test(int prebind)
+ 	SQLLEN ind;
+ 	int i;
+ 	char buf[100];
+-	HSTMT stmt;
+ 
+ 	/* build a string longer than 80 character (80 it's the default) */
+ 	buf[0] = 0;
+@@ -42,22 +45,25 @@ Test(int prebind)
+ 
+ 	Command(Statement, "DELETE FROM #tmp1");
+ 
+-	CHK(SQLAllocStmt, (Connection, &stmt));
++	CHKAllocStmt(&stmt, "S");
+ 
++	SWAP_STMT(stmt);
+ 	if (prebind)
+-		CHK(SQLBindParameter, (stmt, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 1, 0, buf, 1, &ind));
++		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 1, 0, buf, 1, &ind, "S");
+ 
+-	CHK(SQLPrepare, (stmt, (SQLCHAR *) "INSERT INTO #tmp1(c) VALUES(?)", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "INSERT INTO #tmp1(c) VALUES(?)", SQL_NTS, "S");
+ 
+-	/* try to insert al empty string, should not fail */
++	/* try to insert an empty string, should not fail */
+ 	/* NOTE this is currently the only test for insert a empty string using rpc */
+ 	if (db_is_microsoft())
+-		TestInsert(stmt, "");
+-	TestInsert(stmt, "a");
+-	TestInsert(stmt, "bb");
+-	TestInsert(stmt, buf);
+-
+-	CHK(SQLFreeStmt, (stmt, SQL_DROP));
++		TestInsert("");
++	TestInsert("a");
++	TestInsert("bb");
++	TestInsert(buf);
++
++	CHKFreeStmt(SQL_DROP, "S");
++	Statement = SQL_NULL_HSTMT;
++	SWAP_STMT(stmt);
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/rownumber.c b/src/odbc/unittests/rownumber.c
+index 55eddaf..83fd65c 100644
+--- a/src/odbc/unittests/rownumber.c
++++ b/src/odbc/unittests/rownumber.c
+@@ -7,21 +7,20 @@
+  * TODO make it work and add to Makefile.am
+  */
+ 
+-static char software_version[] = "$Id: rownumber.c,v 1.3 2008/02/08 09:28:04 freddy77 Exp $";
++static char software_version[] = "$Id: rownumber.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ CheckRowNum(int n, int line)
+ {
+-	SQLRETURN res;
+ 	SQLUINTEGER value;
+ 
+-	res = SQLGetStmtAttr(Statement, SQL_ATTR_ROW_NUMBER, &value, sizeof(value), NULL);
+-	if (res != SQL_SUCCESS) {
+-		if (res == SQL_ERROR && n < 0)
+-			return;
+-		ODBC_REPORT_ERROR("SQLGetStmtAttr failed");
++	if (n < 0) {
++		CHKGetStmtAttr(SQL_ATTR_ROW_NUMBER, &value, sizeof(value), NULL, "E");
++		return;
+ 	}
++
++	CHKGetStmtAttr(SQL_ATTR_ROW_NUMBER, &value, sizeof(value), NULL, "S");
+ 	if (value != n) {
+ 		fprintf(stderr, "Expected %d rows returned %d line %d\n", n, (int) value, line);
+ 		exit(1);
+@@ -32,59 +31,35 @@ CheckRowNum(int n, int line)
+ #define CHECK_ROWS(n) CheckRowNum(n,__LINE__)
+ 
+ static void
+-NextResults(SQLRETURN expected)
+-{
+-	if (SQLMoreResults(Statement) != expected) {
+-		if (expected == SQL_SUCCESS)
+-			fprintf(stderr, "Expected another recordset\n");
+-		else
+-			fprintf(stderr, "Not expected another recordset\n");
+-		exit(1);
+-	}
+-}
+-
+-static void
+-Fetch(SQLRETURN expected)
+-{
+-	if (SQLFetch(Statement) != expected) {
+-		if (expected == SQL_SUCCESS)
+-			fprintf(stderr, "Expected another record\n");
+-		else
+-			fprintf(stderr, "Not expected another record\n");
+-		exit(1);
+-	}
+-}
+-
+-static void
+ DoTest()
+ {
+ 	int n = 0;
+ 	static const char query[] = "SELECT * FROM #tmp1 ORDER BY i SELECT * FROM #tmp1 WHERE i < 3 ORDER BY i";
+ 
+ 	/* execute a batch command and check row number */
+-	CHK(SQLExecDirect, (Statement, (SQLCHAR *) query, SQL_NTS));
++	CHKExecDirect((SQLCHAR *) query, SQL_NTS, "S");
+ 
+ 	CHECK_ROWS(-1);
+ 	printf("Result %d\n", ++n);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
+ 	CHECK_ROWS(0);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
+ 	CHECK_ROWS(0);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
+ 	CHECK_ROWS(0);
+-	Fetch(SQL_NO_DATA);
++	CHKFetch("No");
+ 	CHECK_ROWS(-1);
+-	NextResults(SQL_SUCCESS);
++	CHKMoreResults("S");
+ 	CHECK_ROWS(-1);
+ 
+ 	printf("Result %d\n", ++n);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
+ 	CHECK_ROWS(0);
+-	Fetch(SQL_SUCCESS);
++	CHKFetch("S");
+ 	CHECK_ROWS(0);
+-	Fetch(SQL_NO_DATA);
++	CHKFetch("No");
+ 	CHECK_ROWS(-1);
+-	NextResults(SQL_NO_DATA);
++	CHKMoreResults("No");
+ 	CHECK_ROWS(-1);
+ }
+ 
+diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c
+index ad4b9fa..9e79bbd 100644
+--- a/src/odbc/unittests/rowset.c
++++ b/src/odbc/unittests/rowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rowset.c,v 1.3 2008/08/27 07:59:25 freddy77 Exp $";
++static char software_version[] = "$Id: rowset.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -11,24 +11,14 @@ ReadError(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+ 	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+ }
+ 
+ static void
+ test_err(int n)
+ {
+-	SQLRETURN rc;
+-
+-	rc = SQLSetStmtAttr(Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(n), 0);
+-	if (rc != SQL_ERROR) {
+-		fprintf(stderr, "SQLSetStmtAttr should fail\n");
+-		Disconnect();
+-		exit(1);
+-        }
++	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(n), 0, "E");
+ 	ReadError();
+ 	if (strcmp(odbc_sqlstate, "HY024") != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+@@ -49,13 +39,12 @@ main(int argc, char *argv[])
+ #endif
+ 	SQLUSMALLINT statuses[10];
+ 	char buf[32];
+-	SQLRETURN rc;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+ 	/* initial value should be 1 */
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ROWSET_SIZE, &len, sizeof(len), NULL));
++	CHKGetStmtAttr(SQL_ROWSET_SIZE, &len, sizeof(len), NULL, "S");
+ 	if (len != 1) {
+ 		fprintf(stderr, "len should be 1\n");
+ 		Disconnect();
+@@ -70,8 +59,8 @@ main(int argc, char *argv[])
+ 	CheckCursor();
+ 
+ 	/* set some correct values */
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0));
++	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0, "S");
++	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0, "S");
+ 
+ 	/* now check that SQLExtendedFetch works as expected */
+ 	Command(Statement, "CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
+@@ -86,16 +75,14 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	ResetStatement();
+-	CHK(SQLSetStmtOption, (Statement, SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC));
+-	rc = CommandWithResult(Statement, "SELECT * FROM #rowset ORDER BY n");
+-	if (!SQL_SUCCEEDED(rc))
+-		ODBC_REPORT_ERROR("SQLExecDirect error");
++	CHKSetStmtOption(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC, "S");
++	CHKExecDirect((SQLCHAR *) "SELECT * FROM #rowset ORDER BY n", SQL_NTS, "SI");
+ 
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, buf, sizeof(buf), &len));
++	CHKBindCol(2, SQL_C_CHAR, buf, sizeof(buf), &len, "S");
+ 
+ 	row_count = 0xdeadbeef;
+ 	memset(statuses, 0x55, sizeof(statuses));
+-	CHK(SQLExtendedFetch, (Statement, SQL_FETCH_NEXT, 1, &row_count, statuses));
++	CHKExtendedFetch(SQL_FETCH_NEXT, 1, &row_count, statuses, "S");
+ 
+ 	if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) {
+ 		fprintf(stderr, "Invalid result\n");
+diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c
+index 3b58e29..7027df1 100644
+--- a/src/odbc/unittests/rpc.c
++++ b/src/odbc/unittests/rpc.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.10 2008/02/08 08:31:19 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.11 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char procedure_sql[] = 
+@@ -41,10 +41,7 @@ init_proc(const char *name)
+ 		printf("Dropping procedure %s\n", name);
+ 		sprintf(cmd, "if exists (select 1 from sysobjects where name = '%s' and type = 'P') "
+ 				"DROP PROCEDURE %s", name, name);
+-		if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) cmd, SQL_NTS))) {
+-			CheckReturn();
+-			exit(1);
+-		}
++		CHKExecDirect((SQLCHAR *) cmd, SQL_NTS, "SI");
+ 	}
+ 
+ 	printf("Creating procedure %s\n", name);
+@@ -65,10 +62,8 @@ static void
+ Test(const char *name)
+ {
+ 	int iresults=0, data_errors=0;
+-	unsigned char sqlstate[6], msg[256];
+-	SQLRETURN erc;
+ 	int ipar=0;
+-	HSTMT stmt;
++	HSTMT Statement = SQL_NULL_HSTMT;
+ 	char call_cmd[128];
+ 	struct Argument { 
+                 SQLSMALLINT       InputOutputType;  /* fParamType */
+@@ -97,7 +92,7 @@ Test(const char *name)
+ 
+ 
+ 	printf("executing SQLAllocStmt\n");
+-	CHK(SQLAllocStmt, (Connection, &stmt));
++	CHKAllocStmt(&Statement, "S");
+ 
+ 	for( ipar=0; ipar < sizeof(args)/sizeof(args[0]); ipar++ ) {
+ 		printf("executing SQLBindParameter for parameter %d\n", 1+ipar);
+@@ -107,7 +102,7 @@ Test(const char *name)
+ 			memset(args[ipar].ParameterValuePtr, 0, args[ipar].BufferLength);
+ 			memset(args[ipar].ParameterValuePtr, 'a', args[ipar].BufferLength - 1);
+ 		}
+-		CHK(SQLBindParameter,	( stmt, 1+ipar
++		CHKBindParameter	( 1+ipar
+ 					, args[ipar].InputOutputType
+ 					, args[ipar].ValueType
+ 					, args[ipar].ParameterType
+@@ -116,19 +111,16 @@ Test(const char *name)
+ 					, args[ipar].ParameterValuePtr
+ 					, args[ipar].BufferLength
+ 					, &args[ipar].ind
+-					));
++					, "S"
++					);
+ 	}
+ 
+ 	sprintf(call_cmd, "{?=call %s(?,?,?,?,?)}", name );
+ 	printf("executing SQLPrepare: %s\n", call_cmd);
+-	CHK(SQLPrepare, (stmt, (SQLCHAR *) call_cmd, SQL_NTS));
++	CHKPrepare((SQLCHAR *) call_cmd, SQL_NTS, "S");
+ 
+ 	printf("executing SQLExecute\n");
+-	if (! SQL_SUCCEEDED(SQLExecute(stmt))) {
+-		erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+-		fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
+-		ODBC_REPORT_ERROR("Unable to execute SQLExecute\n");
+-	}
++	CHKExecute("SI");
+ 
+ 	do {
+ 		static const char dashes[] = "------------------------------";
+@@ -141,7 +133,7 @@ Test(const char *name)
+ 		SQLSMALLINT  nullable;
+ 
+ 		printf("executing SQLNumResultCols for result set %d\n", ++iresults);
+-		CHK(SQLNumResultCols, (stmt,  &ncols));
++		CHKNumResultCols(&ncols, "S");
+ 
+ 		printf("executing SQLDescribeCol for %d column%c\n", ncols, (ncols == 1? ' ' : 's'));
+ 		printf("%-5.5s %-15.15s %5.5s %5.5s %5.5s %8.8s\n", "col", "name", "type", "size", "scale", "nullable"); 
+@@ -149,34 +141,28 @@ Test(const char *name)
+ 		
+ 		for (icol=ncols; icol > 0; icol--) {
+ 			SQLULEN size;
+-			CHK(SQLDescribeCol, (stmt, icol, name, sizeof(name),
+-						    &namelen, &type, &size, &scale, &nullable));
++			CHKDescribeCol(icol, name, sizeof(name),
++				       &namelen, &type, &size, &scale, &nullable, "S");
+ 			printf("%-5d %-15s %5d %5ld %5d %8c\n", icol, name, type, (long int)size, scale, (nullable? 'Y' : 'N')); 
+ 		}
+ 
+ 		printf("executing SQLFetch...\n");
+ 		printf("\t%-30s\n\t%s\n", name, dashes);
+-		for (nrows=0; (erc = SQLFetch(stmt)) == SQL_SUCCESS; nrows++) {
++		for (nrows=0; CHKFetch("SNo") == SQL_SUCCESS; nrows++) {
+ 			const SQLINTEGER icol = 1;
+ 			char buf[60];
+ 			SQLLEN len;
+-			erc = SQLGetData( stmt
+-					, icol
++			CHKGetData( icol
+ 					, SQL_C_CHAR	/* fCType */
+ 					, buf		/* rgbValue */
+ 					, sizeof(buf)	/* cbValueMax */
+ 	                		, &len		/* pcbValue */	
++					, "SI"
+ 					);
+ 			printf("\t%-30s\t(%2d bytes)\n", buf, (int) len);
+ 		}
++		printf("done.\n");
+ 
+-		if (erc != SQL_NO_DATA_FOUND) {
+-			erc = SQLGetDiagRec(SQL_HANDLE_STMT, stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+-			fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
+-			ODBC_REPORT_ERROR("Unable to execute SQLFetch\n");
+-		} else {
+-			printf("done.\n");
+-		}
+ 		switch (iresults) {
+ 		case 1:
+ 			printf("0 rows expected, %d found\n", nrows);
+@@ -193,13 +179,8 @@ Test(const char *name)
+ 		}
+ 
+ 		printf("executing SQLMoreResults...\n");
+-	} while ((erc = SQLMoreResults(stmt)) == SQL_SUCCESS);
+-
+-	if (erc != SQL_NO_DATA_FOUND) {
+-		ODBC_REPORT_ERROR("Unable to execute SQLMoreResults\n");
+-	} else {
+-		printf("done.\n");
+-	}
++	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
++	printf("done.\n");
+ 
+ 	for( ipar=0; ipar < sizeof(args)/sizeof(args[0]); ipar++ ) {
+ 		if (args[ipar].InputOutputType == SQL_PARAM_INPUT)
+@@ -220,7 +201,8 @@ Test(const char *name)
+ 	}
+ 
+ 	printf("executing SQLFreeStmt\n");
+-	CHK(SQLFreeStmt, (stmt, SQL_DROP));
++	CHKFreeStmt(SQL_DROP, "S");
++	Statement = SQL_NULL_HSTMT;
+ 
+ 	for (ipar = 0; ipar < sizeof(args)/sizeof(args[0]); ++ipar)
+ 		if (args[ipar].BufferLength > 0)
+diff --git a/src/odbc/unittests/scroll.c b/src/odbc/unittests/scroll.c
+index f3ff03f..b5dc2a6 100644
+--- a/src/odbc/unittests/scroll.c
++++ b/src/odbc/unittests/scroll.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: scroll.c,v 1.7 2008/01/29 14:30:48 freddy77 Exp $";
++static char software_version[] = "$Id: scroll.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -45,6 +45,7 @@ main(int argc, char *argv[])
+ 	use_odbc_version3 = 1;
+ 
+ 	Connect();
++	CheckCursor();
+ 
+ 	/* create test table */
+ 	Command(Statement, "IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+@@ -57,34 +58,19 @@ main(int argc, char *argv[])
+ 
+ 	/* set cursor options */
+ 	ResetStatement();
+-	retcode = SQLSetStmtAttr(Statement, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
+-	if (retcode != SQL_SUCCESS) {
+-		char output[256];
+-		unsigned char sqlstate[6];
+-
+-		CHK(SQLGetDiagRec, (SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL));
+-		sqlstate[5] = 0;
+-		if (strcmp((const char*) sqlstate, "01S02") == 0) {
+-			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+-			Disconnect();
+-			exit(0);
+-		}
+-		ODBC_REPORT_ERROR("SQLSetStmtAttr");
+-	}
+-
+-
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0));
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0));
++	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROW_STATUS_PTR, (SQLPOINTER) statuses, 0, "S");
++	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &num_row, 0, "S");
+ 
+ 	/* */
+-	CHK(SQLExecDirect, (Statement, (SQLCHAR *) "SELECT i, c FROM #test", SQL_NTS));
++	CHKExecDirect((SQLCHAR *) "SELECT i, c FROM #test", SQL_NTS, "S");
+ 
+ 	/* bind some rows at a time */
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_ULONG, n, 0, n_len));
+-	CHK(SQLBindCol, (Statement, 2, SQL_C_CHAR, c, C_LEN, c_len));
++	CHKBindCol(1, SQL_C_ULONG, n, 0, n_len, "S");
++	CHKBindCol(2, SQL_C_CHAR, c, C_LEN, c_len, "S");
+ 
+ 	for (i_test = 0; i_test < num_tests; ++i_test) {
+ 		const TEST *t = &tests[i_test];
+diff --git a/src/odbc/unittests/t0001.c b/src/odbc/unittests/t0001.c
+index a51adea..5b4e160 100644
+--- a/src/odbc/unittests/t0001.c
++++ b/src/odbc/unittests/t0001.c
+@@ -1,13 +1,12 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.16 2008/02/08 09:28:04 freddy77 Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.17 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+ main(int argc, char *argv[])
+ {
+ 
+-	int res;
+ 	int i;
+ 
+ 	SQLLEN cnamesize;
+@@ -23,40 +22,28 @@ main(int argc, char *argv[])
+ 		"col1 varchar(30) not null,"
+ 		"col2 int not null,"
+ 		"col3 float not null," "col4 numeric(18,6) not null," "col5 datetime not null," "col6 text not null)";
+-	CHK(CommandWithResult, (Statement, command));
++	Command(Statement, command);
+ 
+ 	command = "insert #odbctestdata values ("
+ 		"'ABCDEFGHIJKLMNOP',"
+ 		"123456," "1234.56," "123456.78," "'Sep 11 2001 10:00AM'," "'just to check returned length...')";
+-	CHK(CommandWithResult, (Statement, command));
++	Command(Statement, command);
+ 
+-	CHK(CommandWithResult, (Statement, "select * from #odbctestdata"));
++	Command(Statement, "select * from #odbctestdata");
+ 
+-	res = SQLFetch(Statement);
+-	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Unable to fetch row\n");
+-		CheckReturn();
+-	}
++	CHKFetch("SI");
+ 
+ 	for (i = 1; i <= 6; i++) {
+-		CHK(SQLGetData, (Statement, i, SQL_C_CHAR, output, sizeof(output), &cnamesize));
++		CHKGetData(i, SQL_C_CHAR, output, sizeof(output), &cnamesize, "S");
+ 
+ 		printf("output data >%s< len_or_ind = %d\n", output, (int) cnamesize);
+ 		if (cnamesize != strlen((char *) output))
+ 			return 1;
+ 	}
+ 
+-	res = SQLFetch(Statement);
+-	if (res != SQL_NO_DATA) {
+-		fprintf(stderr, "Unable to fetch row\n");
+-		CheckReturn();
+-	}
++	CHKFetch("No");
+ 
+-	res = SQLCloseCursor(Statement);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to close cursor\n");
+-		CheckReturn();
+-	}
++	CHKCloseCursor("SI");
+ 
+ 	Command(Statement, "drop table #odbctestdata");
+ 
+diff --git a/src/odbc/unittests/t0002.c b/src/odbc/unittests/t0002.c
+index af7cfc3..120b515 100644
+--- a/src/odbc/unittests/t0002.c
++++ b/src/odbc/unittests/t0002.c
+@@ -1,14 +1,12 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.14 2008/02/08 09:28:04 freddy77 Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.15 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-
+-	int res;
+-	HSTMT stmt;
++	HSTMT old_Statement;
+ 
+ 	Connect();
+ 
+@@ -22,44 +20,27 @@ main(int argc, char *argv[])
+ 	 * then make another query with first select and drop this statement
+ 	 * result should not disappear (required for DBD::ODBC)
+ 	 */
++	old_Statement = Statement;
++	Statement = SQL_NULL_HSTMT;
++	CHKAllocStmt(&Statement, "S");
+ 
+-	CHK(SQLAllocStmt, (Connection, &stmt));
+-
+-	Command(stmt, "select * from #odbctestdata where 0=1");
++	Command(Statement, "select * from #odbctestdata where 0=1");
+ 
+-	if (SQLFetch(stmt) != SQL_NO_DATA) {
+-		fprintf(stderr, "Data not expected\n");
+-		exit(1);
+-	}
++	CHKFetch("No");
+ 
+-	res = SQLCloseCursor(stmt);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to close cursor\n");
+-		CheckReturn();
+-	}
++	CHKCloseCursor("SI");
+ 
+-	Command(Statement, "select * from #odbctestdata");
++	Command(old_Statement, "select * from #odbctestdata");
+ 
+ 	/* drop first statement .. data should not disappear */
+-	CHK(SQLFreeStmt, (stmt, SQL_DROP));
+-
+-	res = SQLFetch(Statement);
+-	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Unable to fetch row. Drop of previous statement discard results... bad!\n");
+-		CheckReturn();
+-	}
+-
+-	res = SQLFetch(Statement);
+-	if (res != SQL_NO_DATA) {
+-		fprintf(stderr, "Unable to fetch row\n");
+-		CheckReturn();
+-	}
+-
+-	res = SQLCloseCursor(Statement);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to close cursr\n");
+-		CheckReturn();
+-	}
++	CHKFreeStmt(SQL_DROP, "S");
++	Statement = old_Statement;
++
++	CHKFetch("SI");
++
++	CHKFetch("No");
++
++	CHKCloseCursor("SI");
+ 
+ 	Command(Statement, "drop table #odbctestdata");
+ 
+diff --git a/src/odbc/unittests/t0003.c b/src/odbc/unittests/t0003.c
+index d9e6640..8c5e115 100644
+--- a/src/odbc/unittests/t0003.c
++++ b/src/odbc/unittests/t0003.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.17 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.18 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -14,41 +14,36 @@ DoTest(int prepared)
+ 	if (!prepared) {
+ 		Command(Statement, "select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS));
+-		CHK(SQLExecute, (Statement));
++		CHKPrepare((SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
++		CHKExecute("S");
+ 	}
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Data not expected");
++	CHKFetch("No");
+ 
+-	CHK(SQLMoreResults, (Statement));
++	CHKMoreResults("S");
+ 	printf("Getting next recordset\n");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Data not expected");
++	CHKFetch("No");
+ 
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Not expected another recordset");
++	CHKMoreResults("No");
+ 
+ 	/* test that skipping a no empty result go to other result set */
+ 	Command(Statement, "insert into #odbctestdata values(123)");
+ 	if (!prepared) {
+ 		Command(Statement, "select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+-		CHK(SQLPrepare, (Statement, (SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS));
+-		CHK(SQLExecute, (Statement));
++		CHKPrepare((SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
++		CHKExecute("S");
+ 	}
+ 
+-	CHK(SQLMoreResults, (Statement));
++	CHKMoreResults("S");
+ 	printf("Getting next recordset\n");
+ 
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Data not expected");
++	CHKFetch("No");
+ 
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("Not expected another recordset");
++	CHKMoreResults("No");
+ 
+ 	Command(Statement, "drop table #odbctestdata");
+ }
+diff --git a/src/odbc/unittests/t0004.c b/src/odbc/unittests/t0004.c
+index 839fa60..2a4093d 100644
+--- a/src/odbc/unittests/t0004.c
++++ b/src/odbc/unittests/t0004.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.16 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.17 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -15,39 +15,27 @@ Test(int use_indicator)
+ 	strcpy(buf, "I don't exist");
+ 	ind = strlen(buf);
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, buf, 128, pind));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, 20, 0, buf, 128, pind, "S");
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "SELECT id, name FROM master..sysobjects WHERE name = ?", SQL_NTS));
++	CHKPrepare((SQLCHAR *) "SELECT id, name FROM master..sysobjects WHERE name = ?", SQL_NTS, "S");
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Data not expected\n");
+-		exit(1);
+-	}
++	CHKFetch("No");
+ 
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Not expected another recordset\n");
+-		exit(1);
+-	}
++	CHKMoreResults("No");
+ 
+ 	/* use same binding above */
+ 	strcpy(buf, "sysobjects");
+ 	ind = strlen(buf);
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+-	CHK(SQLFetch, (Statement));
++	CHKFetch("S");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Data not expected\n");
+-		exit(1);
+-	}
++	CHKFetch("No");
+ 
+-	if (SQLMoreResults(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Not expected another recordset\n");
+-		exit(1);
+-	}
++	CHKMoreResults("No");
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c
+index 0f90c55..6595f9c 100644
+--- a/src/odbc/unittests/tables.c
++++ b/src/odbc/unittests/tables.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: tables.c,v 1.15 2008/10/29 09:33:50 freddy77 Exp $";
++static char software_version[] = "$Id: tables.c,v 1.16 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef WIN32
+@@ -15,7 +15,7 @@ static void
+ ReadCol(int i)
+ {
+ 	strcpy(output, "NULL");
+-	CHK(SQLGetData, (Statement, i, SQL_C_CHAR, output, sizeof(output), &cnamesize));
++	CHKGetData(i, SQL_C_CHAR, output, sizeof(output), &cnamesize, "S");
+ }
+ 
+ static void
+@@ -35,14 +35,14 @@ TestName(int index, const char *expected_name)
+ 	} while(0)
+ 
+ 	/* retrieve with SQLDescribeCol */
+-	CHK(SQLDescribeCol, (Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL));
++	CHKDescribeCol(index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL, "S");
+ 	NAME_TEST;
+ 
+ 	/* retrieve with SQLColAttribute */
+-	CHK(SQLColAttribute, (Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL));
++	CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
+ 	if (db_is_microsoft())
+ 		NAME_TEST;
+-	CHK(SQLColAttribute, (Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL));
++	CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
+ 	NAME_TEST;
+ }
+ 
+@@ -57,11 +57,11 @@ static void
+ DoTest(const char *type, int row_returned)
+ {
+ 	int table_len = SQL_NULL_DATA;
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 	char table_buf[80];
+ 	int found = 0;
+ 
+-#define PARAM(x) (SQLCHAR *) (x), (x) ? strlen(x) : SQL_NULL_DATA
++#define LEN(x) (x) ? strlen(x) : SQL_NULL_DATA
+ 
+ 	if (table) {
+ 		strcpy(table_buf, table);
+@@ -70,11 +70,7 @@ DoTest(const char *type, int row_returned)
+ 	}
+ 
+ 	printf("Test type '%s' %s row\n", type ? type : "", row_returned ? "with" : "without");
+-	if (!SQL_SUCCEEDED(SQLTables(Statement, PARAM(catalog), PARAM(schema), (SQLCHAR *) table_buf, table_len, PARAM(type)))) {
+-		printf("Unable to execute statement\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHKTables((SQLCHAR *) catalog, LEN(catalog), (SQLCHAR *) schema, LEN(schema), (SQLCHAR *) table_buf, table_len, (SQLCHAR *) type, LEN(type), "SI");
+ 
+ 	/* test column name (for DBD::ODBC) */
+ 	TestName(1, use_odbc_version3 || !driver_is_freetds() ? "TABLE_CAT" : "TABLE_QUALIFIER");
+@@ -84,11 +80,7 @@ DoTest(const char *type, int row_returned)
+ 	TestName(5, "REMARKS");
+ 
+ 	if (row_returned) {
+-		if (!SQL_SUCCEEDED(SQLFetch(Statement))) {
+-			printf("Unable to fetch row\n");
+-			CheckReturn();
+-			exit(1);
+-		}
++		CHKFetch("SI");
+ 
+ 		if (!expect) {
+ 			ReadCol(1);
+@@ -114,8 +106,7 @@ DoTest(const char *type, int row_returned)
+ 		if (strcmp(output, expect) == 0)
+ 			found = 1;
+ 	}
+-	ret = SQLFetch(Statement);
+-	while (ret == SQL_SUCCESS && row_returned > 1) {
++	while (CHKFetch("SNo") == SQL_SUCCESS && row_returned > 1) {
+ 		if (expect) {
+ 			ReadCol(expect_col);
+ 			if (strcmp(output, expect) == 0)
+@@ -123,12 +114,10 @@ DoTest(const char *type, int row_returned)
+ 		}
+ 		if (row_returned < 2)
+ 			break;
+-		ret = SQLFetch(Statement);
+ 	}
+ 
+-	if (ret != SQL_NO_DATA) {
++	if (RetCode != SQL_NO_DATA) {
+ 		printf("Unexpected data\n");
+-		CheckReturn();
+ 		exit(1);
+ 	}
+ 
+@@ -137,11 +126,7 @@ DoTest(const char *type, int row_returned)
+ 		exit(1);
+ 	}
+ 
+-	if (!SQL_SUCCEEDED(SQLCloseCursor(Statement))) {
+-		printf("Unable to close cursr\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHKCloseCursor("SI");
+ 	expect = NULL;
+ 	expect_col = 3;
+ }
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index 4078cd8..9a42ab7 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.5 2008/02/13 08:52:09 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -33,7 +33,7 @@ check_ipd_params(void)
+ static void
+ set_ipd_params1(SQLULEN *ptr)
+ {
+-	CHK(SQLSetStmtAttr,(Statement, SQL_ATTR_PARAMS_PROCESSED_PTR, ptr, 0));
++	CHKSetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR, ptr, 0, "S");
+ }
+ 
+ static void
+@@ -100,8 +100,8 @@ test_params(void)
+ 		(*p)(&len);
+ 		check_ipd_params();
+ 
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
+-		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens));
++		CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
++		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
+ 
+ 		Command(Statement, "INSERT INTO #tmp1(i) VALUES(?)");
+ 		SQLMoreResults(Statement);
+@@ -150,7 +150,7 @@ check_ird_params(void)
+ static void
+ set_ird_params1(SQLULEN *ptr)
+ {
+-	CHK(SQLSetStmtAttr,(Statement, SQL_ATTR_ROWS_FETCHED_PTR, ptr, 0));
++	CHKSetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, ptr, 0, "S");
+ }
+ 
+ static void
+@@ -205,17 +205,17 @@ test_rows(void)
+ 			(*p)(&len);
+ 		check_ird_params();
+ 
+-//		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
+-//		CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens));
++//		CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
++//		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
+ 
+ 		CHK(SQLBindCol, (Statement, 1, SQL_C_ULONG, ids, 0, id_lens));
+ 		if (*p) {
+-			CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
++			CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 
+ 			Command(Statement, "SELECT DISTINCT i FROM #tmp1");
+ 			SQLFetch(Statement);
+ 		} else {
+-			CHK(SQLSetStmtAttr, (Statement, SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0));
++			CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 			Command(Statement, "SELECT DISTINCT i FROM #tmp1");
+ 			CHK(SQLExtendedFetch, (Statement, SQL_FETCH_NEXT, 0, &len, NULL));
+ 		}
+diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c
+index 96c28f5..3cc3926 100644
+--- a/src/odbc/unittests/testodbc.c
++++ b/src/odbc/unittests/testodbc.c
+@@ -10,7 +10,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: testodbc.c,v 1.12 2008/02/08 10:20:23 freddy77 Exp $";
++static char software_version[] = "$Id: testodbc.c,v 1.13 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef DEBUG
+@@ -138,11 +138,11 @@ TestRawODBCPreparedQuery(void)
+ 
+ 	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd, "S");
+ 
+-	CHK(SQLPrepare, (Statement, queryString, SQL_NTS));
++	CHKPrepare(queryString, SQL_NTS, "S");
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+ 	count = 0;
+ 
+@@ -209,9 +209,9 @@ TestRawODBCDirectQuery(void)
+ 
+ 	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd, "S");
+ 
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHKExecDirect(queryString, SQL_NTS, "S");
+ 
+ 	count = 0;
+ 
+@@ -291,7 +291,7 @@ TestRawODBCGuid(void)
+ 
+ 	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age ) \
+                          VALUES ( 'Fang', 'Mike', 'dog', 'm', 12 );");
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHKExecDirect(queryString, SQL_NTS, "S");
+ 
+ 	AB_PRINT(("Insert row 2"));
+ 
+@@ -304,10 +304,10 @@ TestRawODBCGuid(void)
+ 
+ 	lenOrInd = 0;
+ 	age = 3;
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &age, 0, &lenOrInd));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &age, 0, &lenOrInd, "S");
+ 
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+-	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
++	CHKExecDirect(queryString, SQL_NTS, "S");
++	CHKFreeStmt(SQL_CLOSE, "S");
+ 
+ 	AB_PRINT(("Insert row 3"));
+ 	/*
+@@ -319,8 +319,8 @@ TestRawODBCGuid(void)
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "87654321-4321-4321-4321-123456789abc");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd));
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd, "S");
++	CHKExecDirect(queryString, SQL_NTS, "S");
+ 
+ 	AB_PRINT(("Insert row 4"));
+ 	/*
+@@ -332,8 +332,8 @@ TestRawODBCGuid(void)
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 36, 0, guid, 0, &lenOrInd));
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, 36, 0, guid, 0, &lenOrInd, "S");
++	CHKExecDirect(queryString, SQL_NTS, "S");
+ 
+ 	AB_PRINT(("Insert row 5"));
+ 	/*
+@@ -357,7 +357,7 @@ TestRawODBCGuid(void)
+ 	lenOrInd = 16;
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd, "S");
+ 	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("Insert row 5 failed"));
+@@ -369,11 +369,11 @@ TestRawODBCGuid(void)
+ 	 */
+ 	AB_PRINT(("retrieving name and guid"));
+ 	strcpy((char *) (queryString), "SELECT name, guid FROM #pet");
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHKExecDirect(queryString, SQL_NTS, "S");
+ 	while (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		count++;
+-		CHK(SQLGetData, (Statement, 1, SQL_CHAR, name, 20, 0));
+-		CHK(SQLGetData, (Statement, 2, SQL_CHAR, guid, 37, 0));
++		CHKGetData(1, SQL_CHAR, name, 20, 0, "S");
++		CHKGetData(2, SQL_CHAR, guid, 37, 0, "S");
+ 
+ 		AB_PRINT(("name: %-10s guid: %s", name, guid));
+ 	}
+@@ -382,8 +382,7 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state if we try SELECT again).
+ 	 */
+-	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
+-	CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
++	ResetStatement();
+ 
+ 
+ 	/*
+@@ -392,11 +391,11 @@ TestRawODBCGuid(void)
+ 
+ 	AB_PRINT(("retrieving name and guid again"));
+ 	strcpy((char *) (queryString), "SELECT name, guid FROM #pet");
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
+-	while (SQLFetch(Statement) == SQL_SUCCESS) {
++	CHKExecDirect(queryString, SQL_NTS, "S");
++	while (CHKFetch("SNo") == SQL_SUCCESS) {
+ 		count++;
+-		CHK(SQLGetData, (Statement, 1, SQL_CHAR, name, 20, 0));
+-		CHK(SQLGetData, (Statement, 2, SQL_GUID, &sqlguid, 16, 0));
++		CHKGetData(1, SQL_CHAR, name, 20, 0, "S");
++		CHKGetData(2, SQL_GUID, &sqlguid, 16, 0, "S");
+ 
+ 		AB_PRINT(("%-10s %08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
+ 			  name,
+@@ -410,8 +409,7 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state if we try SELECT again).
+ 	 */
+-	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
+-	CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
++	ResetStatement();
+ 
+ 	/*
+ 	 * Now retrieve rows via stored procedure passing GUID as param.
+@@ -422,12 +420,12 @@ TestRawODBCGuid(void)
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "87654321-4321-4321-4321-123456789abc");
+ 
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd));
+-	CHK(SQLExecDirect, (Statement, queryString, SQL_NTS));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd, "S");
++	CHKExecDirect(queryString, SQL_NTS, "S");
+ 	while (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		count++;
+-		CHK(SQLGetData, (Statement, 1, SQL_CHAR, name, 20, 0));
+-		CHK(SQLGetData, (Statement, 2, SQL_CHAR, guid, 37, 0));
++		CHKGetData(1, SQL_CHAR, name, 20, 0, "S");
++		CHKGetData(2, SQL_CHAR, guid, 37, 0, "S");
+ 
+ 		AB_PRINT(("%-10s %s", name, guid));
+ 	}
+@@ -436,8 +434,7 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state after a previous SELECT has occurred).
+ 	 */
+-	CHK(SQLFreeStmt, (Statement, SQL_CLOSE));
+-	CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
++	ResetStatement();
+ 
+ 	/* cleanup */
+ 	CommandWithResult(Statement, "DROP PROC GetGUIDRows");
+diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c
+index f8a7ddf..5e86031 100644
+--- a/src/odbc/unittests/timeout.c
++++ b/src/odbc/unittests/timeout.c
+@@ -3,19 +3,19 @@
+ 
+ /* Test timeout of query */
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.8 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.9 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ AutoCommit(int onoff)
+ {
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0));
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0, "S");
+ }
+ 
+ static void
+ EndTransaction(SQLSMALLINT type)
+ {
+-	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, type));
++	CHKEndTran(SQL_HANDLE_DBC, Connection, type, "S");
+ }
+ 
+ int
+@@ -50,15 +50,13 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 
+ 	i = 1;
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &i, 0, NULL));
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &i, 0, NULL, "S");
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) "update test_timeout set t = 'bad' where n = ?", SQL_NTS));
+-	ret = SQLExecute(Statement);
+-	if (ret != SQL_ERROR)
+-		ODBC_REPORT_ERROR("SQLExecute success ??");
++	CHKPrepare((SQLCHAR *) "update test_timeout set t = 'bad' where n = ?", SQL_NTS, "S");
++	CHKExecute("E");
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+ 	/* TODO should return error S1T00 Timeout expired, test error message */
+diff --git a/src/odbc/unittests/timeout2.c b/src/odbc/unittests/timeout2.c
+index 1c61565..0d5802d 100644
+--- a/src/odbc/unittests/timeout2.c
++++ b/src/odbc/unittests/timeout2.c
+@@ -14,7 +14,7 @@
+  * Test from Ou Liu, cf "Query Time Out", 2006-08-08
+  */
+ 
+-static char software_version[] = "$Id: timeout2.c,v 1.5 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: timeout2.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if defined(__MINGW32__) || defined(WIN32)
+@@ -24,7 +24,6 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int
+ main(int argc, char *argv[])
+ {
+-	SQLRETURN ret;
+ 	int i;
+ 
+ 	Connect();
+@@ -36,17 +35,15 @@ main(int argc, char *argv[])
+ 
+ 		printf("Loop %d\n", i);
+ 
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER));
++		CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER, "S");
+ 
+-		CHK(SQLPrepare, (Statement, (SQLCHAR*) "select * from #timeout", SQL_NTS));
+-		CHK(SQLExecute, (Statement));
++		CHKPrepare((SQLCHAR*) "select * from #timeout", SQL_NTS, "S");
++		CHKExecute("S");
+ 
+ 		do {
+-			while ((ret=SQLFetch(Statement)) == SQL_SUCCESS)
++			while (CHKFetch("SNo") == SQL_SUCCESS)
+ 				;
+-			assert(ret == SQL_NO_DATA);
+-		} while ((ret = SQLMoreResults(Statement)) == SQL_SUCCESS);
+-		assert(ret == SQL_NO_DATA);
++		} while (CHKMoreResults("SNo") == SQL_SUCCESS);
+ 
+ 		if (i == 0) {
+ 			printf("Sleep 15 seconds to test if timeout occurs\n");
+diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c
+index 8fdeff3..ae15217 100644
+--- a/src/odbc/unittests/timeout3.c
++++ b/src/odbc/unittests/timeout3.c
+@@ -40,7 +40,7 @@
+ 	test connection timeout
+ */
+ 
+-static char software_version[] = "$Id: timeout3.c,v 1.7 2008/02/08 09:28:05 freddy77 Exp $";
++static char software_version[] = "$Id: timeout3.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -48,18 +48,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	if (SQLAllocEnv(&Environment) != SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to allocate env\n");
+-		exit(1);
+-	}
+-
++	CHKR(SQLAllocEnv, (&Environment), "S");
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-
+-	if (SQLAllocConnect(Environment, &Connection) != SQL_SUCCESS) {
+-		fprintf(stderr, "Unable to allocate connection\n");
+-		SQLFreeEnv(Environment);
+-		exit(1);
+-	}
++	CHKR(SQLAllocConnect, (Environment, &Connection), "S");
+ }
+ 
+ static pthread_t      fake_thread;
+@@ -128,7 +119,6 @@ fake_thread_proc(void * arg)
+ int
+ main(int argc, char *argv[])
+ {
+-	int res;
+ 	char tmp[2048];
+ 	char sqlstate[6];
+ 	SQLSMALLINT len;
+@@ -167,31 +157,19 @@ main(int argc, char *argv[])
+ 	printf("Fake server binded at port %d\n", port);
+ 
+ 	init_connect();
+-	res = SQLSetConnectAttr(Connection, SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER));
+-	if (!SQL_SUCCEEDED(res))
+-		ODBC_REPORT_ERROR("SQLSetConnectAttr error");
+-	res = SQLSetConnectAttr(Connection, SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER));
+-	if (!SQL_SUCCEEDED(res))
+-		ODBC_REPORT_ERROR("SQLSetConnectAttr error");
++	CHKSetConnectAttr(SQL_ATTR_CONNECTION_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER), "SI");
++	CHKSetConnectAttr(SQL_ATTR_LOGIN_TIMEOUT, (SQLPOINTER) 10, sizeof(SQLINTEGER), "SI");
+ 
+ 	/* this is expected to work with unixODBC */
+ 	printf("try to connect to our port just to check connection timeout\n");
+ 	sprintf(tmp, "DRIVER=FreeTDS;SERVER=127.0.0.1;Port=%d;TDS_Version=7.0;UID=test;PWD=test;DATABASE=tempdb;", port);
+ 	start_time = time(NULL);
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "SQLDriverConnect should fail (res=%d)\n", (int) res);
+-		return 1;
+-	}
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "E");
+ 	end_time = time(NULL);
+ 
+ 	strcpy(sqlstate, "XXXXX");
+ 	tmp[0] = 0;
+-	res = SQLGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) tmp, sizeof(tmp), NULL);
+-	if (!SQL_SUCCEEDED(res)) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		return 1;
+-	}
++	CHKGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) tmp, sizeof(tmp), NULL, "SI");
+ 	Disconnect();
+ 	CLOSESOCKET(fake_sock);
+ 	pthread_join(fake_thread, NULL);
+diff --git a/src/odbc/unittests/timeout4.c b/src/odbc/unittests/timeout4.c
+index be9c6f9..14e3edd 100644
+--- a/src/odbc/unittests/timeout4.c
++++ b/src/odbc/unittests/timeout4.c
+@@ -39,7 +39,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: timeout4.c,v 1.2 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: timeout4.c,v 1.3 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -80,7 +80,7 @@ static int
+ Test(int direct)
+ {
+ 	char buf[256];
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 	char sqlstate[6];
+ 	time_t start_time, end_time;
+ 
+@@ -91,28 +91,19 @@ Test(int direct)
+ 		return 1;
+ 	}
+ 
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER));
++	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 10, SQL_IS_UINTEGER, "S");
+ 
+ 	alarm(30);
+ 	start_time = time(NULL);
+ 	if (direct)
+-		ret = SQLExecDirect(Statement, (SQLCHAR *) "SELECT 1", SQL_NTS);
++		CHKExecDirect((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
+ 	else
+-		ret = SQLPrepare(Statement, (SQLCHAR *) "SELECT 1", SQL_NTS);
++		CHKPrepare((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
+ 	end_time = time(NULL);
+ 	alarm(0);
+-	if (ret != SQL_ERROR) {
+-		fprintf(stderr, "Error expected\n");
+-		return 1;
+-	}
+ 
+ 	strcpy(sqlstate, "XXXXX");
+-	ret = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL);
+-	if (ret != SQL_SUCCESS && ret != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Error not set\n");
+-		Disconnect();
+-		return 1;
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	sqlstate[5] = 0;
+ 	printf("Message: %s - %s\n", sqlstate, buf);
+ 	if (strcmp(sqlstate, "HYT00") || !strstr(buf, "Timeout")) {
+diff --git a/src/odbc/unittests/transaction.c b/src/odbc/unittests/transaction.c
+index e7b507a..a7408a9 100644
+--- a/src/odbc/unittests/transaction.c
++++ b/src/odbc/unittests/transaction.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: transaction.c,v 1.13 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: transaction.c,v 1.14 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int
+@@ -35,35 +35,35 @@ Test(int discard_test)
+ 	Command(Statement, createErrorProcedure);
+ 
+ 	/* Start transaction */
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0));
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
+ 
+ 	/* Insert a value */
+ 	Command(Statement, "EXEC testinsert 1");
+ 
+ 	/* we should be able to read row count */
+-	CHK(SQLRowCount, (Statement, &rows));
++	CHKRowCount(&rows, "S");
+ 
+ 	/* Commit transaction */
+-	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, SQL_COMMIT));
++	CHKEndTran(SQL_HANDLE_DBC, Connection, SQL_COMMIT, "S");
+ 
+ 	SQLCloseCursor(Statement);
+ 
+ 	/* Start transaction */
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0));
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
+ 
+ 	/* Insert another value */
+ 	Command(Statement, "EXEC testinsert 2");
+ 
+ 	/* Roll back transaction */
+-	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, SQL_ROLLBACK));
++	CHKEndTran(SQL_HANDLE_DBC, Connection, SQL_ROLLBACK, "S");
+ 
+ 	/* TODO test row inserted */
+ 
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0));
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0, "S");
+ 
+ 	/* generate an error */
+ 	Command(Statement, "EXEC testerror");
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len));
++	CHKBindCol(1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len, "S");
+ 
+ 	while ((result = SQLFetch(Statement)) == SQL_SUCCESS) {
+ 		printf("\t%ld\n", (long int) out_buf);
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index 8c54082..25f3dda 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.4 2008/03/18 08:22:23 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -14,25 +14,20 @@ ReadError(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	if (!SQL_SUCCEEDED
+-	    (SQLGetDiagRec
+-	     (SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL))) {
+-		printf("SQLGetDiagRec should not fail\n");
+-		exit(1);
+-	}
++	CHKGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+ 	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+ }
+ 
+ static void
+ AutoCommit(int onoff)
+ {
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0));
++	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(onoff), 0, "S");
+ }
+ 
+ static void
+ EndTransaction(SQLSMALLINT type)
+ {
+-	CHK(SQLEndTran, (SQL_HANDLE_DBC, Connection, type));
++	CHKEndTran(SQL_HANDLE_DBC, Connection, type, "S");
+ }
+ 
+ #define SWAP(t,a,b) do { t xyz = a; a = b; b = xyz; } while(0)
+@@ -61,10 +56,8 @@ CheckDirtyRead(void)
+ 		return 0;	/* no dirty read */
+ 	}
+ 
+-	CHK(SQLFetch, (Statement));
+-	ret = SQLFetch(Statement);
+-	if (ret != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("other rows ??");
++	CHKFetch("S");
++	CHKFetch("No");
+ 	SQLMoreResults(Statement);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+@@ -79,7 +72,7 @@ CheckNonrepeatableRead(void)
+ 
+ 	/* transaction 2 read a row */
+ 	SWAP_CONN();
+-	CHK(CommandWithResult, (Statement, "SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1"));
++	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
+ 	SQLMoreResults(Statement);
+ 
+ 	/* transaction 1 change a row and commit */
+@@ -99,10 +92,8 @@ CheckNonrepeatableRead(void)
+ 	/* second transaction try to fetch commited row */
+ 	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
+ 
+-	CHK(SQLFetch, (Statement));
+-	ret = SQLFetch(Statement);
+-	if (ret != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("other rows ??");
++	CHKFetch("S");
++	CHKFetch("No");
+ 	SQLMoreResults(Statement);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+@@ -118,7 +109,7 @@ CheckPhantom(void)
+ 
+ 	/* transaction 2 read a row */
+ 	SWAP_CONN();
+-	CHK(CommandWithResult, (Statement, "SELECT * FROM test_transaction WHERE t = 'initial'"));
++	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial'");
+ 	SQLMoreResults(Statement);
+ 
+ 	/* transaction 1 insert a row that match critera */
+@@ -138,11 +129,9 @@ CheckPhantom(void)
+ 	/* second transaction try to fetch commited row */
+ 	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial'");
+ 
+-	CHK(SQLFetch, (Statement));
+-	CHK(SQLFetch, (Statement));
+-	ret = SQLFetch(Statement);
+-	if (ret != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("other rows ??");
++	CHKFetch("S");
++	CHKFetch("S");
++	CHKFetch("No");
+ 	SQLMoreResults(Statement);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+@@ -158,7 +147,7 @@ static int global_txn;
+ static void
+ my_attrs(void)
+ {
+-	CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(global_txn), 0));
++	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(global_txn), 0, "S");
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ }
+ 
+@@ -181,9 +170,9 @@ Test(int txn, const char *expected)
+ 	if (test_with_connect) {
+ 		Disconnect();
+ 		ConnectWithTxn(txn);
+-		CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++		CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 	} else {
+-		CHK(SQLSetConnectAttr, (Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0));
++		CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(txn), 0, "S");
+ 	}
+ 	SWAP_CONN();
+ 
+@@ -219,7 +208,7 @@ main(int argc, char *argv[])
+ 	Command(Statement, "IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
+ 	Command(Statement, "CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
+ 
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
+@@ -258,7 +247,7 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	CHK(SQLSetStmtAttr, (Statement, SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0));
++	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 
+ 	SWAP_CONN();
+diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c
+index c9539c9..b15c930 100644
+--- a/src/odbc/unittests/typeinfo.c
++++ b/src/odbc/unittests/typeinfo.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: typeinfo.c,v 1.9 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: typeinfo.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -20,30 +20,28 @@ TestName(int index, const char *expected_name)
+ 	} while(0)
+ 
+ 	/* retrieve with SQLDescribeCol */
+-	CHK(SQLDescribeCol, (Statement, index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL));
++	CHKDescribeCol(index, (SQLCHAR *) name, sizeof(name), &len, &type, NULL, NULL, NULL, "S");
+ 	NAME_TEST;
+ 
+ 	/* retrieve with SQLColAttribute */
+-	CHK(SQLColAttribute, (Statement, index, SQL_DESC_NAME, name, sizeof(name), &len, NULL));
++	CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
+ 	if (db_is_microsoft())
+ 		NAME_TEST;
+-	CHK(SQLColAttribute, (Statement, index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL));
++	CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
+ 	NAME_TEST;
+ }
+ 
+ static void
+ FlushStatement(void)
+ {
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 
+-	while ((retcode = SQLFetch(Statement)) == SQL_SUCCESS);
+-	if (retcode != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLFetch failed");
++	while (CHKFetch("SNo") == SQL_SUCCESS)
++		;
+ 
+ 	/* Sybase store procedure seems to return extra empty results */
+-	while ((retcode = SQLMoreResults(Statement)) == SQL_SUCCESS);
+-	if (retcode != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLMoreResults failed");
++	while (CHKMoreResults("SNo") == SQL_SUCCESS)
++		;
+ }
+ 
+ static void
+@@ -51,12 +49,12 @@ CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int l
+ {
+ 	SQLSMALLINT out_type;
+ 	SQLLEN ind;
++	SQLRETURN RetCode;
+ 
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 2, SQL_C_SSHORT, &out_type, 0, &ind)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	if (!SQL_SUCCEEDED(SQLGetTypeInfo(Statement, type)))
+-		ODBC_REPORT_ERROR("SQLGetTypeInfo failed");
+-	switch (SQLFetch(Statement)) {
++	CHKBindCol(2, SQL_C_SSHORT, &out_type, 0, &ind, "SI");
++	CHKGetTypeInfo(type, "SI");
++	CHKFetch("SNo");
++	switch (RetCode) {
+ 	case SQL_SUCCESS:
+ 		if (expected == SQL_UNKNOWN_TYPE) {
+ 			fprintf(stderr, "Data not expected (type %d - %s) line %d\n", type, string_type, line);
+@@ -76,8 +74,6 @@ CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int l
+ 			exit(1);
+ 		}
+ 		break;
+-	default:
+-		ODBC_REPORT_ERROR("SQLFetch failed");
+ 	}
+ 
+ 	SQLFreeStmt(Statement, SQL_UNBIND);
+@@ -101,8 +97,7 @@ DoTest(int version3)
+ 	printf("Using ODBC version %d\n", version3 ? 3 : 2);
+ 
+ 	/* test column name */
+-	if (!SQL_SUCCEEDED(SQLGetTypeInfo(Statement, SQL_ALL_TYPES)))
+-		ODBC_REPORT_ERROR("SQLGetTypeInfo failed");
++	CHKGetTypeInfo(SQL_ALL_TYPES, "SI");
+ 	TestName(1, "TYPE_NAME");
+ 	TestName(2, "DATA_TYPE");
+ 	TestName(3, version3 ? "COLUMN_SIZE" : "PRECISION");
+@@ -150,23 +145,15 @@ DoTest(int version3)
+ 	/* varchar/nvarchar before sysname */
+ 
+ 	/* test binding (not all column, required for Oracle) */
+-	if (!SQL_SUCCEEDED(SQLGetTypeInfo(Statement, SQL_ALL_TYPES)))
+-		ODBC_REPORT_ERROR("SQLGetTypeInfo failed");
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 1, SQL_C_CHAR, name, sizeof(name), &ind1)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 2, SQL_C_SSHORT, &type, 0, &ind2)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 3, SQL_C_SLONG, &col_size, 0, &ind3)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 6, SQL_C_CHAR, params, sizeof(params), &ind4)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 10, SQL_C_SSHORT, &is_unsigned, 0, &ind5)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	if (!SQL_SUCCEEDED(SQLBindCol(Statement, 14, SQL_C_SSHORT, &min_scale, 0, &ind6)))
+-		ODBC_REPORT_ERROR("SQLBindCol failed");
+-	while ((retcode = SQLFetch(Statement)) == SQL_SUCCESS);
+-	if (retcode != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLFetch failed");
++	CHKGetTypeInfo(SQL_ALL_TYPES, "SI");
++	CHKBindCol(1, SQL_C_CHAR, name, sizeof(name), &ind1, "SI");
++	CHKBindCol(2, SQL_C_SSHORT, &type, 0, &ind2, "SI");
++	CHKBindCol(3, SQL_C_SLONG, &col_size, 0, &ind3, "SI");
++	CHKBindCol(6, SQL_C_CHAR, params, sizeof(params), &ind4, "SI");
++	CHKBindCol(10, SQL_C_SSHORT, &is_unsigned, 0, &ind5, "SI");
++	CHKBindCol(14, SQL_C_SSHORT, &min_scale, 0, &ind6, "SI");
++	while (CHKFetch("SNo") == SQL_SUCCESS)
++		;
+ 	SQLFreeStmt(Statement, SQL_UNBIND);
+ 	FlushStatement();
+ 
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 31f57d6..328914f 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.7 2008/10/31 14:35:23 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -17,26 +17,21 @@ init_connect(void)
+ static void
+ CheckNoRow(const char *query)
+ {
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 
+-	retcode = SQLExecDirect(Statement, (SQLCHAR *) query, SQL_NTS);
+-	if (retcode == SQL_NO_DATA)
++	CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
++	if (RetCode == SQL_NO_DATA)
+ 		return;
+ 
+-	if (!SQL_SUCCEEDED(retcode))
+-		ODBC_REPORT_ERROR("SQLExecDirect");
+-
+ 	do {
+ 		SQLSMALLINT cols;
+ 
+-		retcode = SQLNumResultCols(Statement, &cols);
+-		if (retcode != SQL_SUCCESS || cols != 0) {
++		CHKNumResultCols(&cols, "S");
++		if (cols != 0) {
+ 			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
+ 			exit(1);
+ 		}
+-	} while ((retcode = SQLMoreResults(Statement)) == SQL_SUCCESS);
+-	if (retcode != SQL_NO_DATA)
+-		ODBC_REPORT_ERROR("SQLMoreResults");
++	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
+ }
+ 
+ /* test table name, it contains two japanese characters */
+@@ -77,9 +72,9 @@ TestBinding(int minimun)
+ 
+ 	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+ 	sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) tmp, SQL_NTS));
+-	CHK(SQLBindParameter, (Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG,
+-		SQL_INTEGER, 0, 0, &n, 0, &n_len));
++	CHKPrepare((SQLCHAR *) tmp, SQL_NTS, "S");
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG,
++		SQL_INTEGER, 0, 0, &n, 0, &n_len, "S");
+ 	n_len = sizeof(n);
+ 	
+ 	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
+@@ -87,16 +82,16 @@ TestBinding(int minimun)
+ 		int len;
+ 
+ 		len = minimun ? (strlen(strings_hex[p-strings]) - 2) /4 : 40;
+-		CHK(SQLBindParameter, (Statement, 2, SQL_PARAM_INPUT, SQL_C_CHAR,
+-			SQL_WCHAR, len, 0, (void *) p[0], 0, &s1_len));
++		CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR,
++			SQL_WCHAR, len, 0, (void *) p[0], 0, &s1_len, "S");
+ 		len = minimun ? (strlen(strings_hex[p+1-strings]) - 2) /4 : 40;
+ 		/* FIXME this with SQL_VARCHAR produce wrong protocol data */
+-		CHK(SQLBindParameter, (Statement, 3, SQL_PARAM_INPUT, SQL_C_CHAR,
+-			SQL_WVARCHAR, len, 0, (void *) p[1], 0, &s2_len));
++		CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_CHAR,
++			SQL_WVARCHAR, len, 0, (void *) p[1], 0, &s2_len, "S");
+ 		s1_len = strlen(p[0]);
+ 		s2_len = strlen(p[1]);
+ 		printf("insert #%d\n", (int) n);
+-		CHK(SQLExecute, (Statement));
++		CHKExecute("S");
+ 	}
+ 
+ 	/* check rows */
+@@ -111,7 +106,6 @@ TestBinding(int minimun)
+ int
+ main(int argc, char *argv[])
+ {
+-	int res;
+ 	SQLSMALLINT len;
+ 	const char * const*p;
+ 	SQLINTEGER n;
+@@ -122,12 +116,7 @@ main(int argc, char *argv[])
+ 	/* connect string using DSN */
+ 	init_connect();
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+-		CheckReturn();
+-		return 1;
+-	}
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
+ 	if (!driver_is_freetds()) {
+ 		Disconnect();
+ 		printf("Driver is not FreeTDS, exiting\n");
+@@ -140,7 +129,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	CHK(SQLAllocStmt, (Connection, &Statement));
++	CHKAllocStmt(&Statement, "S");
+ 
+ 	/* create test table */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index 7203a40..7e18402 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.5 2008/10/31 14:35:23 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -37,7 +37,6 @@ main(int argc, char *argv[])
+ 	char tmp[128];
+ 	char out[32];
+ 	SQLLEN n_len;
+-	int res;
+ 	SQLSMALLINT len;
+ 	const char * const*p;
+ 	int n;
+@@ -48,12 +47,7 @@ main(int argc, char *argv[])
+ 	/* connect string using DSN */
+ 	init_connect();
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
+-	res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT);
+-	if (!SQL_SUCCEEDED(res)) {
+-		fprintf(stderr, "Unable to open data source (ret=%d)\n", res);
+-		CheckReturn();
+-		return 1;
+-	}
++	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
+ 	if (!driver_is_freetds()) {
+ 		Disconnect();
+ 		printf("Driver is not FreeTDS, exiting\n");
+@@ -66,7 +60,7 @@ main(int argc, char *argv[])
+ 		return 0;
+ 	}
+ 
+-	CHK(SQLAllocStmt, (Connection, &Statement));
++	CHKAllocStmt(&Statement, "S");
+ 
+ 	/* create test table */
+ 	Command(Statement, "CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
+@@ -81,9 +75,9 @@ main(int argc, char *argv[])
+ 	Command(Statement, "SELECT v FROM #tmpHebrew");
+ 
+ 	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+-	CHK(SQLBindCol, (Statement, 1, SQL_C_CHAR, out, sizeof(out), &n_len));
++	CHKBindCol(1, SQL_C_CHAR, out, sizeof(out), &n_len, "S");
+ 	for (n = 0, p = strings; p[n]; ++n) {
+-		CHK(SQLFetch, (Statement));
++		CHKFetch("S");
+ 		if (n_len != strlen(p[n]) || strcmp(p[n], out) != 0) {
+ 			fprintf(stderr, "Wrong row %d %s\n", n, out);
+ 			Disconnect();
+diff --git a/src/odbc/unittests/warning.c b/src/odbc/unittests/warning.c
+index 741a250..b1fd195 100644
+--- a/src/odbc/unittests/warning.c
++++ b/src/odbc/unittests/warning.c
+@@ -14,7 +14,7 @@
+  * inside recordset
+  * Sybase do not return warning but test works the same
+  */
+-static char software_version[] = "$Id: warning.c,v 1.6 2008/01/29 14:30:49 freddy77 Exp $";
++static char software_version[] = "$Id: warning.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char one_null_with_warning[] = "select max(a) as foo from (select convert(int, null) as a) as test";
+@@ -28,23 +28,15 @@ static const int tds_no_dm = 0;
+ static void
+ Test(const char *query)
+ {
+-	int res;
++	SQLRETURN RetCode;
+ 
+-	CHK(SQLPrepare, (Statement, (SQLCHAR *) query, SQL_NTS));
++	CHKPrepare((SQLCHAR *) query, SQL_NTS, "S");
+ 
+-	CHK(SQLExecute, (Statement));
++	CHKExecute("S");
+ 
+-	res = SQLFetch(Statement);
+-	if (res != SQL_SUCCESS && res != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Unable to fetch row.\n");
+-		CheckReturn();
+-		exit(1);
+-	}
++	CHKFetch("SI");
+ 
+-	if (SQLFetch(Statement) != SQL_NO_DATA) {
+-		fprintf(stderr, "Warning was returned as a result row -- bad!\n");
+-		exit(1);
+-	}
++	CHKFetch("No");
+ 
+ 	/*
+ 	 * Microsoft SQL Server 2000 provides a diagnostic record
+@@ -57,10 +49,7 @@ Test(const char *query)
+ 	if (db_is_microsoft() && tds_no_dm) {
+ 		SQLCHAR output[256];
+ 
+-		if (!SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL))) {
+-			fprintf(stderr, "SQLGetDiagRec should not fail\n");
+-			exit(1);
+-		}
++		CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
+ 		printf("Message: %s\n", (char *) output);
+ 	}
+ 
+diff --git a/src/odbc/unittests/wchar.c b/src/odbc/unittests/wchar.c
+index 92bb084..d3698e7 100644
+--- a/src/odbc/unittests/wchar.c
++++ b/src/odbc/unittests/wchar.c
+@@ -2,7 +2,7 @@
+ 
+ /* test SQL_C_DEFAULT with NCHAR type */
+ 
+-static char software_version[] = "$Id: wchar.c,v 1.1 2008/02/05 10:03:57 freddy77 Exp $";
++static char software_version[] = "$Id: wchar.c,v 1.2 2008/11/04 10:59:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,16 +12,15 @@ main(int argc, char *argv[])
+ 	SQLLEN ind;
+ 	int failed = 0;
+ 
+-	/* TODO remove if not neeeded */
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	SQLBindCol(Statement, 1, SQL_C_DEFAULT, buf, 100, &ind);
++	CHKBindCol(1, SQL_C_DEFAULT, buf, 100, &ind, "S");
+ 	Command(Statement, "SELECT CONVERT(NCHAR(10), 'Pippo 123')");
+ 
+ 	/* get data */
+ 	memset(buf, 0, sizeof(buf));
+-	SQLFetch(Statement);
++	CHKFetch("S");
+ 
+ 	SQLMoreResults(Statement);
+ 	SQLMoreResults(Statement);
+
+commit 9f2dc2a95f95cf52236ae0c5f41d8ef9e41ba2a8
+Author: freddy77 <freddy77>
+Date:   Tue Nov 4 14:46:17 2008 +0000
+
+    more odbc tests restyling
+
+diff --git a/ChangeLog b/ChangeLog
+index 3df21ec..091ffe0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,35 @@
++Tue Nov 04 15:43:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
++	* src/odbc/unittests/attributes.c src/odbc/unittests/binary_test.c:
++	* src/odbc/unittests/blob1.c src/odbc/unittests/cancel.c:
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/compute.c src/odbc/unittests/const_params.c:
++	* src/odbc/unittests/convert_error.c src/odbc/unittests/cursor1.c:
++	* src/odbc/unittests/cursor2.c src/odbc/unittests/cursor3.c:
++	* src/odbc/unittests/cursor4.c src/odbc/unittests/cursor5.c:
++	* src/odbc/unittests/cursor6.c src/odbc/unittests/cursor7.c:
++	* src/odbc/unittests/data.c src/odbc/unittests/date.c:
++	* src/odbc/unittests/describecol.c src/odbc/unittests/earlybind.c:
++	* src/odbc/unittests/error.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/funccall.c src/odbc/unittests/genparams.c:
++	* src/odbc/unittests/getdata.c src/odbc/unittests/hidden.c:
++	* src/odbc/unittests/insert_speed.c src/odbc/unittests/moreandcount.c:
++	* src/odbc/unittests/norowset.c src/odbc/unittests/paramcore.c:
++	* src/odbc/unittests/params.c src/odbc/unittests/prepare_results.c:
++	* src/odbc/unittests/preperror.c src/odbc/unittests/print.c:
++	* src/odbc/unittests/putdata.c src/odbc/unittests/raiserror.c:
++	* src/odbc/unittests/rebindpar.c src/odbc/unittests/rownumber.c:
++	* src/odbc/unittests/rowset.c src/odbc/unittests/rpc.c:
++	* src/odbc/unittests/scroll.c src/odbc/unittests/t0001.c:
++	* src/odbc/unittests/t0002.c src/odbc/unittests/t0003.c:
++	* src/odbc/unittests/test64.c src/odbc/unittests/testodbc.c:
++	* src/odbc/unittests/timeout.c src/odbc/unittests/timeout2.c:
++	* src/odbc/unittests/transaction.c src/odbc/unittests/transaction2.c:
++	* src/odbc/unittests/typeinfo.c src/odbc/unittests/utf8.c:
++	* src/odbc/unittests/utf8_2.c src/odbc/unittests/warning.c:
++	* src/odbc/unittests/wchar.c:
++	- more restyling
++
+ Tue Nov 04 11:56:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/array_out.c src/odbc/unittests/binary_test.c:
+ 	* src/odbc/unittests/blob1.c src/odbc/unittests/cancel.c:
+@@ -848,4 +880,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2647 2008/11/04 10:59:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2648 2008/11/04 14:46:17 freddy77 Exp $
+diff --git a/src/odbc/unittests/array.c b/src/odbc/unittests/array.c
+index 9aa638a..9b0fd8d 100644
+--- a/src/odbc/unittests/array.c
++++ b/src/odbc/unittests/array.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array.c,v 1.14 2007/11/26 06:25:11 freddy77 Exp $";
++static char software_version[] = "$Id: array.c,v 1.15 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -41,7 +41,7 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ 	ResetStatement();
+ 
+ 	CommandWithResult(Statement, "drop table #tmp1");
+-	Command(Statement, "create table #tmp1 (id tinyint, value char(20))");
++	Command("create table #tmp1 (id tinyint, value char(20))");
+ 
+ 	SQLSetStmtAttr(Statement, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
+ 	SQLSetStmtAttr(Statement, SQL_ATTR_PARAMSET_SIZE, (void *) ARRAY_SIZE, 0);
+diff --git a/src/odbc/unittests/array_out.c b/src/odbc/unittests/array_out.c
+index 5117d65..1c8c8d5 100644
+--- a/src/odbc/unittests/array_out.c
++++ b/src/odbc/unittests/array_out.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array_out.c,v 1.13 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: array_out.c,v 1.14 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -18,7 +18,7 @@ typedef struct
+ } Record;
+ 
+ static void
+-query_test(SQLRETURN expected, const char *expected_status)
++query_test(const char* expected, const char *expected_status)
+ {
+ #define ARRAY_SIZE 10
+ 
+@@ -30,7 +30,7 @@ query_test(SQLRETURN expected, const char *expected_status)
+ 	int desc_len = trunc ? 4 : 51;
+ 	int rec_size = 0;
+ 	Record *rec = NULL;
+-	RETCODE ret;
++	RETCODE RetCode;
+ 	char status[20];
+ 
+ 	assert(Statement != SQL_NULL_HSTMT);
+@@ -76,9 +76,7 @@ query_test(SQLRETURN expected, const char *expected_status)
+ 
+ 	CHKExecDirect((SQLCHAR *) test_query, SQL_NTS, "S");
+ 
+-	ret = SQLFetch(Statement);
+-	if (ret != expected)
+-		ODBC_REPORT_ERROR("SQLFetch invalid result");
++	CHKFetch(expected);
+ 
+ 	assert(processed <= ARRAY_SIZE);
+ 
+@@ -138,34 +136,34 @@ main(int argc, char *argv[])
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #odbc_test(i INT, t TEXT)");
++	Command("CREATE TABLE #odbc_test(i INT, t TEXT)");
+ 	for (i = 0; i < 10; ++i) {
+ 		char buf[128];
+ 
+ 		sprintf(buf, "INSERT INTO #odbc_test(i, t) VALUES(%d, '%crow number %d')", i + 1, 'a' + i, i * 13);
+-		Command(Statement, buf);
++		Command(buf);
+ 	}
+ 
+ 	ResetStatement();
+ 
+ 	test_query = "SELECT * FROM #odbc_test ORDER BY i";
+ 	printf("test line %d\n", __LINE__);
+-	query_test(SQL_SUCCESS, "VVVVVVVVVV");
++	query_test("S", "VVVVVVVVVV");
+ 
+ 	test_query = "SELECT * FROM #odbc_test WHERE i < 7 ORDER BY i";
+ 	printf("test line %d\n", __LINE__);
+-	query_test(SQL_SUCCESS, "VVVVVV");
++	query_test("S", "VVVVVV");
+ 
+ 	/* binding row */
+ 	test_query = "SELECT * FROM #odbc_test ORDER BY i";
+ 	record_bind = 1;
+ 	printf("test line %d\n", __LINE__);
+-	query_test(SQL_SUCCESS, "VVVVVVVVVV");
++	query_test("S", "VVVVVVVVVV");
+ 
+ 	/* row and truncation */
+ 	trunc = 1;
+ 	printf("test line %d\n", __LINE__);
+-	query_test(SQL_SUCCESS_WITH_INFO, "!!!!!!!!!!");
++	query_test("I", "!!!!!!!!!!");
+ 
+ 	/* TODO bind offset, SQLGetData, no bind, error */
+ 
+diff --git a/src/odbc/unittests/attributes.c b/src/odbc/unittests/attributes.c
+index af07ad0..5e80352 100644
+--- a/src/odbc/unittests/attributes.c
++++ b/src/odbc/unittests/attributes.c
+@@ -5,7 +5,7 @@
+  * SQLSetStmtAttr
+  */
+ 
+-static char software_version[] = "$Id: attributes.c,v 1.4 2007/12/31 10:06:50 freddy77 Exp $";
++static char software_version[] = "$Id: attributes.c,v 1.5 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -278,7 +278,7 @@ main(int argc, char *argv[])
+ 	Connect();
+ 	/* TODO find another way */
+ 	CheckCursor();
+-	Command(Statement, "SET TEXTSIZE 4096");
++	Command("SET TEXTSIZE 4096");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 
+@@ -311,7 +311,7 @@ main(int argc, char *argv[])
+ 				use_odbc_version3 = odbc3;
+ 				Disconnect();
+ 				Connect();
+-				Command(Statement, "SET TEXTSIZE 4096");
++				Command("SET TEXTSIZE 4096");
+ 				SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 			}
+ 			continue;
+diff --git a/src/odbc/unittests/binary_test.c b/src/odbc/unittests/binary_test.c
+index f32e0b9..87f5123 100644
+--- a/src/odbc/unittests/binary_test.c
++++ b/src/odbc/unittests/binary_test.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: binary_test.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: binary_test.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define ERR_BUF_SIZE 256
+@@ -42,7 +42,7 @@ clean_up(void)
+ static int
+ test_insert(void *buf, SQLLEN buflen)
+ {
+-	SQLHSTMT old_Statement;
++	SQLHSTMT Statement = SQL_NULL_HSTMT;
+ 	SQLLEN strlen_or_ind;
+ 	const char *qstr = "insert into " TEST_TABLE_NAME " values (?)";
+ 
+@@ -50,8 +50,6 @@ test_insert(void *buf, SQLLEN buflen)
+ 	assert(Environment);
+ 
+ 	/* allocate new statement handle */
+-	old_Statement = Statement;
+-	Statement = SQL_NULL_HSTMT;
+ 	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "SI");
+ 
+ 	/* execute query */
+@@ -64,10 +62,9 @@ test_insert(void *buf, SQLLEN buflen)
+ 	CHKExecute("SI");
+ 
+ 	/* this command shouldn't fail */
+-	Command(Statement, "DECLARE @i INT");
++	Command("DECLARE @i INT");
+ 
+ 	SQLFreeHandle(SQL_HANDLE_STMT, Statement);
+-	Statement = old_Statement;
+ 	return 0;
+ }
+ 
+@@ -75,7 +72,7 @@ test_insert(void *buf, SQLLEN buflen)
+ static int
+ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ {
+-	SQLHSTMT old_Statement;
++	SQLHSTMT Statement = SQL_NULL_HSTMT;
+ 	SQLLEN strlen_or_ind = 0;
+ 	const char *qstr = "select * from " TEST_TABLE_NAME;
+ 
+@@ -83,8 +80,6 @@ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ 	assert(Environment);
+ 
+ 	/* allocate new statement handle */
+-	old_Statement = Statement;
+-	Statement = SQL_NULL_HSTMT;
+ 	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "SI");
+ 
+ 	/* execute query */
+@@ -102,7 +97,6 @@ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ 	CHKFetch("No");
+ 
+ 	SQLFreeHandle(SQL_HANDLE_STMT, Statement);
+-	Statement = old_Statement;
+ 	return 0;
+ }
+ 
+@@ -119,8 +113,8 @@ main(int argc, char **argv)
+ 
+ 	Connect();
+ 
+-	Command(Statement, "create table " TEST_TABLE_NAME " (im IMAGE)");
+-	Command(Statement, "SET TEXTSIZE 1000000");
++	Command("create table " TEST_TABLE_NAME " (im IMAGE)");
++	Command("SET TEXTSIZE 1000000");
+ 
+ 	/* populate test buffer with ramp */
+ 	for (i = 0; i < TEST_BUF_LEN; i++) {
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index eea40ee..66b64ea 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.11 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -159,7 +159,6 @@ int
+ main(int argc, char **argv)
+ {
+ 	SQLRETURN RetCode;
+-	SQLHSTMT m_hstmt = NULL;
+ 	SQLHSTMT old_Statement = SQL_NULL_HSTMT;
+ 	int i;
+ 
+@@ -176,16 +175,16 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )");
++	Command("CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )");
++
++	old_Statement = Statement;
++	Statement = SQL_NULL_HSTMT;
+ 
+ 	/* Insert rows ... */
+ 
+ 	for (i = 0; i < cnt; i++) {
+ 
+-		m_hstmt = NULL;
+-		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &m_hstmt, "S");
+-		old_Statement = Statement;
+-		Statement = m_hstmt;
++		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
+ 
+ 		CHKPrepare((SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS, "S");
+ 
+@@ -209,11 +208,11 @@ main(int argc, char **argv)
+ 		
+ 
+ 		printf(">> insert... %d\n", i);
+-		CHKR(SQLExecute, (m_hstmt), "SINe");
++		CHKExecute("SINe");
+ 		while (RetCode == SQL_NEED_DATA) {
+ 			char *p;
+ 
+-			CHKR(SQLParamData, (m_hstmt, (SQLPOINTER) & p), "SINe");
++			CHKParamData((SQLPOINTER) & p, "SINe");
+ 			printf(">> SQLParamData: ptr = %p  RetCode = %d\n", (void *) p, RetCode);
+ 			if (RetCode == SQL_NEED_DATA) {
+ 				if (p == buf3) {
+@@ -234,18 +233,15 @@ main(int argc, char **argv)
+ 			}
+ 		}
+ 
+-		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt, "S");
+-		Statement = old_Statement;
++		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
++		Statement = SQL_NULL_HSTMT;
+ 	}
+ 
+ 	/* Now fetch rows ... */
+ 
+ 	for (i = 0; i < cnt; i++) {
+ 
+-		m_hstmt = NULL;
+-		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &m_hstmt));
+-		old_Statement = Statement;
+-		Statement = m_hstmt;
++		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
+ 
+ 		if (db_is_microsoft()) {
+ 			CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
+@@ -271,16 +267,18 @@ main(int argc, char **argv)
+ 		printf(">> fetch... %d\n", i);
+ 
+ 		RetCode = readBlob(1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 1");
++		CHECK_RCODE(SQL_HANDLE_STMT, Statement, "readBlob 1");
+ 		RetCode = readBlob(2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 2");
++		CHECK_RCODE(SQL_HANDLE_STMT, Statement, "readBlob 2");
+ 		RetCode = readBlobAsChar(3, i);
+-		CHECK_RCODE(SQL_HANDLE_STMT, m_hstmt, "readBlob 3 as SQL_C_CHAR");
++		CHECK_RCODE(SQL_HANDLE_STMT, Statement, "readBlob 3 as SQL_C_CHAR");
+ 
+ 		CHKCloseCursor("S");
+-		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) m_hstmt, "S");
+-		Statement = old_Statement;
++		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
++		Statement = SQL_NULL_HSTMT;
+ 	}
++	
++	Statement = old_Statement;
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 2d2b543..b7c7ab0 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -78,7 +78,7 @@ main(int argc, char **argv)
+ 
+ 	ResetStatement();
+ 
+-	Command(Statement, "SELECT name FROM sysobjects WHERE 0=1");
++	Command("SELECT name FROM sysobjects WHERE 0=1");
+ 
+ 	Disconnect();
+ 	return 0;
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 2ae6150..3c18426 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.49 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.50 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -205,15 +205,12 @@ Connect(void)
+ 		CheckReturn();
+ 	}
+ 
+-	CHK(SQLAllocStmt, (Connection, &Statement));
++	CHKAllocStmt(&Statement, "S");
+ 
+ 	sprintf(command, "use %s", DATABASE);
+ 	printf("%s\n", command);
+ 
+-	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) command, SQL_NTS))) {
+-		printf("Unable to execute statement\n");
+-		CheckReturn();
+-	}
++	CHKExecDirect((SQLCHAR *) command, SQL_NTS, "SI");
+ 
+ #ifndef TDS_NO_DM
+ 	/* unixODBC seems to require it */
+@@ -243,19 +240,6 @@ Disconnect(void)
+ 	return 0;
+ }
+ 
+-void
+-Command(HSTMT stmt, const char *command)
+-{
+-	int result = 0;
+-
+-	printf("%s\n", command);
+-	result = SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS);
+-	if (result != SQL_SUCCESS && result != SQL_NO_DATA) {
+-		fprintf(stderr, "Unable to execute statement\n");
+-		CheckReturn();
+-	}
+-}
+-
+ SQLRETURN
+ CommandWithResult(HSTMT stmt, const char *command)
+ {
+@@ -327,16 +311,13 @@ void
+ CheckCols(int n, int line, const char * file)
+ {
+ 	SQLSMALLINT cols;
+-	SQLRETURN res;
++	SQLRETURN RetCode;
+ 
+-	res = SQLNumResultCols(Statement, &cols);
+-	if (res != SQL_SUCCESS) {
+-		if (res == SQL_ERROR && n < 0)
+-			return;
+-		fprintf(stderr, "%s:%d: Unable to get column numbers\n", file, line);
+-		CheckReturn();
++	if (n < 0) {
++		CHKNumResultCols(&cols, "E");
++		return;
+ 	}
+-
++	CHKNumResultCols(&cols, "S");
+ 	if (cols != n) {
+ 		fprintf(stderr, "%s:%d: Expected %d columns returned %d\n", file, line, n, (int) cols);
+ 		Disconnect();
+@@ -348,16 +329,14 @@ void
+ CheckRows(int n, int line, const char * file)
+ {
+ 	SQLLEN rows;
+-	SQLRETURN res;
++	SQLRETURN RetCode;
+ 
+-	res = SQLRowCount(Statement, &rows);
+-	if (res != SQL_SUCCESS) {
+-		if (res == SQL_ERROR && n < -1)
+-			return;
+-		fprintf(stderr, "%s:%d: Unable to get row\n", file, line);
+-		CheckReturn();
++	if (n < -1) {
++		CHKRowCount(&rows, "E");
++		return;
+ 	}
+ 
++	CHKRowCount(&rows, "S");
+ 	if (rows != n) {
+ 		fprintf(stderr, "%s:%d: Expected %d rows returned %d\n", file, line, n, (int) rows);
+ 		Disconnect();
+@@ -370,7 +349,7 @@ ResetStatement(void)
+ {
+ 	SQLFreeStmt(Statement, SQL_DROP);
+ 	Statement = SQL_NULL_HSTMT;
+-	CHK(SQLAllocStmt, (Connection, &Statement));
++	CHKAllocStmt(&Statement, "S");
+ }
+ 
+ void
+@@ -383,7 +362,7 @@ CheckCursor(void)
+ 		char output[256];
+ 		unsigned char sqlstate[6];
+ 
+-		CHK(SQLGetDiagRec, (SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL));
++		CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL, "S");
+ 		sqlstate[5] = 0;
+ 		if (strcmp((const char*) sqlstate, "01S02") == 0) {
+ 			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+@@ -442,3 +421,12 @@ AllocHandleErrType(SQLSMALLINT type)
+ 	}
+ 	return 0;
+ }
++
++#undef Command
++SQLRETURN
++Command(HSTMT stmt, const char *command, const char *file, int line)
++{
++	printf("%s\n", command);
++	return CheckRes(file, line, SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS), SQL_HANDLE_STMT, stmt, "Command", "SNo");
++}
++
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 3e6ac46..dc2ba24 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.25 2008/11/04 10:59:02 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.26 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -120,6 +120,8 @@ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 	CHKR2(SQLNumResultCols, (Statement,a), SQL_HANDLE_STMT, Statement, res)
+ #define CHKParamData(a,res) \
+ 	CHKR2(SQLParamData, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++#define CHKParamOptions(a,b,res) \
++	CHKR2(SQLParamOptions, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
+ #define CHKPrepare(a,b,res) \
+ 	CHKR2(SQLPrepare, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
+ #define CHKPutData(a,b,res) \
+@@ -141,7 +143,8 @@ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 
+ int Connect(void);
+ int Disconnect(void);
+-void Command(HSTMT stmt, const char *command);
++SQLRETURN Command(HSTMT stmt, const char *command, const char *file, int line);
++#define Command(cmd) (RetCode=Command(Statement, cmd, __FILE__, __LINE__))
+ SQLRETURN CommandWithResult(HSTMT stmt, const char *command);
+ int db_is_microsoft(void);
+ const char *db_version(void);
+diff --git a/src/odbc/unittests/compute.c b/src/odbc/unittests/compute.c
+index 20bca06..1ade523 100644
+--- a/src/odbc/unittests/compute.c
++++ b/src/odbc/unittests/compute.c
+@@ -9,7 +9,7 @@
+  * and declared in odbcss.h
+  */
+ 
+-static char software_version[] = "$Id: compute.c,v 1.11 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: compute.c,v 1.12 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char col1[256], col2[256];
+@@ -78,12 +78,12 @@ main(int argc, char *argv[])
+ {
+ 	Connect();
+ 
+-	Command(Statement, "create table #tmp1 (c varchar(20), i int)");
+-	Command(Statement, "insert into #tmp1 values('pippo', 12)");
+-	Command(Statement, "insert into #tmp1 values('pippo', 34)");
+-	Command(Statement, "insert into #tmp1 values('pluto', 1)");
+-	Command(Statement, "insert into #tmp1 values('pluto', 2)");
+-	Command(Statement, "insert into #tmp1 values('pluto', 3)");
++	Command("create table #tmp1 (c varchar(20), i int)");
++	Command("insert into #tmp1 values('pippo', 12)");
++	Command("insert into #tmp1 values('pippo', 34)");
++	Command("insert into #tmp1 values('pluto', 1)");
++	Command("insert into #tmp1 values('pluto', 2)");
++	Command("insert into #tmp1 values('pluto', 3)");
+ 
+ 
+ 	/* 
+@@ -95,7 +95,7 @@ main(int argc, char *argv[])
+ 	/* select * from #tmp1 compute sum(i) */
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+-	Command(Statement, "select * from #tmp1 order by c, i compute sum(i)");
++	Command("select * from #tmp1 order by c, i compute sum(i)");
+ 	CheckFetch("c", "pippo", "12");
+ 	CheckFetch("c", "pippo", "34");
+ 	CheckFetch("c", "pluto", "1");
+@@ -118,7 +118,7 @@ main(int argc, char *argv[])
+ 	/* select * from #tmp1 order by c compute sum(i) by c */
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+-	Command(Statement, "select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
++	Command("select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
+ 	CheckFetch("mao", "pippo", "12");
+ 	CheckFetch("mao", "pippo", "34");
+ 	CHKFetch("No");
+@@ -160,7 +160,7 @@ main(int argc, char *argv[])
+ 	/* select * from #tmp1 where i = 2 compute min(i) */
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+-	Command(Statement, "select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
++	Command("select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
+ 	CheckFetch("c", "pippo", "34");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+diff --git a/src/odbc/unittests/const_params.c b/src/odbc/unittests/const_params.c
+index 92bbbf2..7b9b225 100644
+--- a/src/odbc/unittests/const_params.c
++++ b/src/odbc/unittests/const_params.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?,123,'foo')} syntax and run */
+ 
+-static char software_version[] = "$Id: const_params.c,v 1.15 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: const_params.c,v 1.16 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -17,7 +17,7 @@ main(int argc, char *argv[])
+ 	if (CommandWithResult(Statement, "drop proc const_param") != SQL_SUCCESS)
+ 		printf("Unable to execute statement\n");
+ 
+-	Command(Statement, "create proc const_param @in1 int, @in2 int, @in3 datetime, @in4 varchar(10), @out int output as\n"
++	Command("create proc const_param @in1 int, @in2 int, @in3 datetime, @in4 varchar(10), @out int output as\n"
+ 		"begin\n"
+ 		" set nocount on\n"
+ 		" select @out = 7654321\n"
+@@ -43,7 +43,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* just to reset some possible buffers */
+-	Command(Statement, "DECLARE @i INT");
++	Command("DECLARE @i INT");
+ 
+ 	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind,  "S");
+ 	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2, "S");
+@@ -67,9 +67,9 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 
+-	Command(Statement, "IF OBJECT_ID('const_param') IS NOT NULL DROP PROC const_param");
++	Command("IF OBJECT_ID('const_param') IS NOT NULL DROP PROC const_param");
+ 
+-	Command(Statement, "create proc const_param @in1 float, @in2 varbinary(100) as\n"
++	Command("create proc const_param @in1 float, @in2 varbinary(100) as\n"
+ 		"begin\n"
+ 		" if @in1 <> 12.5 or @in2 <> 0x0102030405060708\n"
+ 		"  return 12345\n"
+@@ -88,9 +88,9 @@ main(int argc, char *argv[])
+ 		return 1;
+ 	}
+ 
+-	Command(Statement, "drop proc const_param");
++	Command("drop proc const_param");
+ 
+-	Command(Statement, "create proc const_param @in varchar(20) as\n"
++	Command("create proc const_param @in varchar(20) as\n"
+ 		"begin\n"
+ 		" if @in = 'value' select 8421\n"
+ 		" select 1248\n"
+@@ -98,7 +98,7 @@ main(int argc, char *argv[])
+ 
+ 	/* catch problem reported by Peter Deacon */
+ 	output = 0xdeadbeef;
+-	Command(Statement, "{CALL const_param('value')}");
++	Command("{CALL const_param('value')}");
+ 	CHKBindCol(1, SQL_C_SLONG, &output, 0, &ind, "S");
+ 	SQLFetch(Statement);
+ 
+@@ -109,7 +109,7 @@ main(int argc, char *argv[])
+ 
+ 	ResetStatement();
+ 
+-	Command(Statement, "drop proc const_param");
++	Command("drop proc const_param");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/convert_error.c b/src/odbc/unittests/convert_error.c
+index 676adf0..0310c84 100644
+--- a/src/odbc/unittests/convert_error.c
++++ b/src/odbc/unittests/convert_error.c
+@@ -4,7 +4,7 @@
+  */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: convert_error.c,v 1.9 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: convert_error.c,v 1.10 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int test_num = 0;
+@@ -37,7 +37,7 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "create table #test_output (id int, msg text)");
++	Command("create table #test_output (id int, msg text)");
+ 
+ 	Test("?", SQL_INTEGER, "?", SQL_LONGVARCHAR);
+ 	Test("123", SQL_INTEGER, "?", SQL_LONGVARCHAR);
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index e19fb2c..f282a19 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.17 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.18 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
+@@ -47,14 +47,14 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 	SQLRETURN RetCode;
+ 
+ 	/* create test table */
+-	Command(Statement, "IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+-	Command(Statement, create_sql);
++	Command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
++	Command(create_sql);
+ 	for (i = 1; i <= 6; ++i) {
+ 		char sql_buf[80], data[10];
+ 		memset(data, 'a' + (i - 1), sizeof(data));
+ 		data[i] = 0;
+ 		sprintf(sql_buf, insert_sql, data, i);
+-		Command(Statement, sql_buf);
++		Command(sql_buf);
+ 	}
+ 
+ 	/* set cursor options */
+@@ -149,8 +149,8 @@ static void
+ Test(int use_sql)
+ {
+ 	CommandWithResult(Statement, "DROP TABLE #a");
+-	Command(Statement, "CREATE TABLE #a(x int)");
+-	Command(Statement, "INSERT INTO #a VALUES(123)");
++	Command("CREATE TABLE #a(x int)");
++	Command("INSERT INTO #a VALUES(123)");
+ 	Test0(use_sql, "CREATE TABLE #test(i int, c varchar(6))", "INSERT INTO #test(c, i) VALUES('%s', %d)", "SELECT x AS i, c FROM #test, #a");
+ 
+ 	Test0(use_sql, "CREATE TABLE #test(i int, c varchar(6))", "INSERT INTO #test(c, i) VALUES('%s', %d)", "SELECT i, c FROM #test");
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index 9d261f6..8a9cd6c 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursor do not give error for statement that do not return rows  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.6 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -14,7 +14,7 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #cursor2_test (i INT)");
++	Command("CREATE TABLE #cursor2_test (i INT)");
+ 
+ 	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE,  (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
+ 	if (retcode != SQL_SUCCESS) {
+@@ -31,7 +31,7 @@ main(int argc, char *argv[])
+ 	ResetStatement();
+ 
+ 	/* this should not fail or return warnings */
+-	Command(Statement, "DROP TABLE #cursor2_test");
++	Command("DROP TABLE #cursor2_test");
+ 
+ 	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "No");
+ 
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index abe3513..b0d621b 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,7 +1,7 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -18,11 +18,11 @@ main(int argc, char **argv)
+ 
+ 	CheckCursor();
+ 
+-	Command(Statement, "CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+-	Command(Statement, "INSERT INTO #t1 VALUES (1, 'aaa')");
+-	Command(Statement, "INSERT INTO #t1 VALUES (2, 'bbbbb')");
+-	Command(Statement, "INSERT INTO #t1 VALUES (3, 'ccccccccc')");
+-	Command(Statement, "INSERT INTO #t1 VALUES (4, 'dd')");
++	Command("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
++	Command("INSERT INTO #t1 VALUES (1, 'aaa')");
++	Command("INSERT INTO #t1 VALUES (2, 'bbbbb')");
++	Command("INSERT INTO #t1 VALUES (3, 'ccccccccc')");
++	Command("INSERT INTO #t1 VALUES (4, 'dd')");
+ 
+ 	old_Statement = Statement;
+ 
+diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c
+index 9f228b5..8a34220 100755
+--- a/src/odbc/unittests/cursor4.c
++++ b/src/odbc/unittests/cursor4.c
+@@ -5,19 +5,17 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ exec_direct(const char *stmt)
+ {
+-	SQLHSTMT old_Statement = Statement;
++	SQLHSTMT Statement = SQL_NULL_HSTMT;
+ 
+-	Statement = SQL_NULL_HSTMT;
+ 	CHKAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & Statement, "S");
+-	Command(Statement, stmt);
++	Command(stmt);
+ 	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+-	Statement = old_Statement;
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index ea8d459..b394ec0 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLINTEGER v_int_3;
+@@ -31,10 +31,10 @@ main(int argc, char **argv)
+ 
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER, "S");
+ 
+-	Command(Statement, "create table #mytab1 (k int, c char(30))");
+-	Command(Statement, "insert into #mytab1 values (1,'aaa')");
+-	Command(Statement, "insert into #mytab1 values (2,'bbb')");
+-	Command(Statement, "insert into #mytab1 values (3,'ccc')");
++	Command("create table #mytab1 (k int, c char(30))");
++	Command("insert into #mytab1 values (1,'aaa')");
++	Command("insert into #mytab1 values (2,'bbb')");
++	Command("insert into #mytab1 values (3,'ccc')");
+ 
+ 	ResetStatement();
+ /*	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0, "S");	*/
+diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c
+index 6f3e431..6a05f29 100755
+--- a/src/odbc/unittests/cursor6.c
++++ b/src/odbc/unittests/cursor6.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with no binded columns */
+ 
+-static char software_version[] = "$Id: cursor6.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor6.c,v 1.5 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int bind_all = 0;
+@@ -79,10 +79,10 @@ static void Init(void)
+ 	int i;
+ 	char sql[128];
+ 
+-	Command(Statement, "CREATE TABLE #cursor6_test (i INT, c VARCHAR(20))");
++	Command("CREATE TABLE #cursor6_test (i INT, c VARCHAR(20))");
+ 	for (i = 1; i <= 10; ++i) {
+ 		sprintf(sql, "INSERT INTO #cursor6_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
+-		Command(Statement, sql);
++		Command(sql);
+ 	}
+ 
+ }
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index 02cac03..6aaf64d 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.7 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -71,10 +71,10 @@ Init(void)
+ 
+ 	printf("\n\nCreating table #cursor7_test with 12 records.\n");
+ 
+-	Command(Statement, "\tCREATE TABLE #cursor7_test (i INT, c VARCHAR(20))");
++	Command("\tCREATE TABLE #cursor7_test (i INT, c VARCHAR(20))");
+ 	for (i = 1; i <= 12; ++i) {
+ 		sprintf(sql, "\tINSERT INTO #cursor7_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
+-		Command(Statement, sql);
++		Command(sql);
+ 	}
+ 
+ }
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 557453b..0d38b0b 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.25 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.26 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -35,7 +35,7 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 	sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
+ 	if (strncmp(value_to_convert, "0x", 2) == 0)
+ 		sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
+-	Command(Statement, sbuf);
++	Command(sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+diff --git a/src/odbc/unittests/date.c b/src/odbc/unittests/date.c
+index 1b1075c..3941e9e 100644
+--- a/src/odbc/unittests/date.c
++++ b/src/odbc/unittests/date.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: date.c,v 1.11 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: date.c,v 1.12 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -16,7 +16,7 @@ DoTest(int n)
+ 
+ 	TIMESTAMP_STRUCT ts;
+ 
+-	Command(Statement, "select convert(datetime, '2002-12-27 18:43:21')");
++	Command("select convert(datetime, '2002-12-27 18:43:21')");
+ 
+ 	CHKFetch("SI");
+ 	CHKDescribeCol(1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable, "S");
+diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c
+index 234e45a..b521dd5 100644
+--- a/src/odbc/unittests/describecol.c
++++ b/src/odbc/unittests/describecol.c
+@@ -6,7 +6,7 @@
+  * test what say SQLDescribeCol about precision using some type
+  */
+ 
+-static char software_version[] = "$Id: describecol.c,v 1.15 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: describecol.c,v 1.16 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -211,7 +211,7 @@ main(int argc, char *argv[])
+ 	get_attr_t get_attr_p = get_attr_none;
+ 
+ 	Connect();
+-	Command(Statement, "SET TEXTSIZE 4096");
++	Command("SET TEXTSIZE 4096");
+ 
+ 	SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 
+@@ -244,7 +244,7 @@ main(int argc, char *argv[])
+ 				use_odbc_version3 = odbc3;
+ 				Disconnect();
+ 				Connect();
+-				Command(Statement, "SET TEXTSIZE 4096");
++				Command("SET TEXTSIZE 4096");
+ 				SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 			}
+ 		}
+diff --git a/src/odbc/unittests/earlybind.c b/src/odbc/unittests/earlybind.c
+index 80a1893..e931d29 100644
+--- a/src/odbc/unittests/earlybind.c
++++ b/src/odbc/unittests/earlybind.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: earlybind.c,v 1.3 2006/03/23 14:53:44 freddy77 Exp $";
++static char software_version[] = "$Id: earlybind.c,v 1.4 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,15 +12,15 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #test(id INT, name VARCHAR(100))");
+-	Command(Statement, "INSERT INTO #test(id, name) VALUES(8, 'sysobjects')");
++	Command("CREATE TABLE #test(id INT, name VARCHAR(100))");
++	Command("INSERT INTO #test(id, name) VALUES(8, 'sysobjects')");
+ 
+ 	/* bind before select */
+ 	SQLBindCol(Statement, 1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1);
+ 	SQLBindCol(Statement, 2, SQL_C_CHAR, name, sizeof(name), &ind2);
+ 
+ 	/* do select */
+-	Command(Statement, "SELECT id, name FROM #test WHERE name = 'sysobjects' SELECT 123, 'foo'");
++	Command("SELECT id, name FROM #test WHERE name = 'sysobjects' SELECT 123, 'foo'");
+ 
+ 	/* get results */
+ 	id = -1;
+@@ -52,7 +52,7 @@ main(int argc, char *argv[])
+ 	SQLMoreResults(Statement);
+ 
+ 	/* other select */
+-	Command(Statement, "SELECT 321, 'minni'");
++	Command("SELECT 321, 'minni'");
+ 
+ 	/* get results */
+ 	id = -1;
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index 1475b6b..153bdd1 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.6 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -24,12 +24,12 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	/* create a test table */
+-	Command(Statement, "create table #tmp (i int)");
+-	Command(Statement, "insert into #tmp values(3)");
+-	Command(Statement, "insert into #tmp values(4)");
+-	Command(Statement, "insert into #tmp values(5)");
+-	Command(Statement, "insert into #tmp values(6)");
+-	Command(Statement, "insert into #tmp values(7)");
++	Command("create table #tmp (i int)");
++	Command("insert into #tmp values(3)");
++	Command("insert into #tmp values(4)");
++	Command("insert into #tmp values(5)");
++	Command("insert into #tmp values(6)");
++	Command("insert into #tmp values(7)");
+ 
+ 	/* issue our command */
+ 	retcode = CommandWithResult(Statement, "select 100 / (i - 5) from #tmp order by i");
+@@ -60,8 +60,9 @@ main(int argc, char *argv[])
+ 
+ 	CHKAllocStmt(&stmt, "S");
+ 
+-	Command(Statement, "SELECT * FROM sysobjects");
++	Command("SELECT * FROM sysobjects");
+ 
++	/* a statement is already active so you get error */
+ 	CHKR(CommandWithResult, (stmt, "SELECT * FROM sysobjects"), "E");
+ 
+ 	tmp_stmt = Statement;
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 7908880..3e8422e 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -50,7 +50,7 @@
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+@@ -313,7 +313,7 @@ main(int argc, char **argv)
+ 	Connect();
+ 
+ 	/* real test */
+-	Command(Statement, "CREATE TABLE #test(i int, c varchar(40))");
++	Command("CREATE TABLE #test(i int, c varchar(40))");
+ 
+ 	ResetStatement();
+ 
+diff --git a/src/odbc/unittests/funccall.c b/src/odbc/unittests/funccall.c
+index d5a1323..43b62bd 100644
+--- a/src/odbc/unittests/funccall.c
++++ b/src/odbc/unittests/funccall.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?)} syntax and run */
+ 
+-static char software_version[] = "$Id: funccall.c,v 1.16 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: funccall.c,v 1.17 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -15,9 +15,9 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");
++	Command("IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");
+ 
+-	Command(Statement, "create proc simpleresult @i int as begin return @i end");
++	Command("create proc simpleresult @i int as begin return @i end");
+ 
+ 	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
+ 	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+@@ -41,7 +41,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* just to reset some possible buffers */
+-	Command(Statement, "DECLARE @i INT");
++	Command("DECLARE @i INT");
+ 
+ 	/* same test but with SQLExecDirect and same bindings */
+ 	input = 567;
+@@ -57,16 +57,15 @@ main(int argc, char *argv[])
+ 	/* should return "Invalid cursor state" */
+ 	CHKFetch("E");
+ 
+-	Command(Statement, "drop proc simpleresult");
++	Command("drop proc simpleresult");
+ 
+-	Command(Statement, "IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");
++	Command("IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");
+ 
+ 	/* force cursor close */
+ 	SQLCloseCursor(Statement);
+ 
+ 	/* test output parameter */
+-	Command(Statement,
+-		"create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
++	Command("create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
+ 
+ 	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind,  "S");
+ 	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2, "S");
+@@ -91,23 +90,20 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* should return "Invalid cursor state" */
+-	if (SQLFetch(Statement) != SQL_ERROR) {
+-		fprintf(stderr, "Data not expected\n");
+-		exit(1);
+-	}
++	CHKFetch("E");
+ 
+-	Command(Statement, "drop proc simpleresult2");
++	Command("drop proc simpleresult2");
+ 
+ 	/*
+ 	 * test from shiv kumar
+ 	 * Cfr ML 2006-11-21 "specifying a 0 for the StrLen_or_IndPtr in the
+ 	 * SQLBindParameter call is not working on AIX"
+ 	 */
+-	Command(Statement, "IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");
++	Command("IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");
+ 
+ 	ResetStatement();
+ 
+-	Command(Statement, "create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
++	Command("create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
+ 	SQLCloseCursor(Statement);
+ 
+ 	CHKPrepare((SQLCHAR *) "{ ? = CALL rpc_read ( ?, ? ) }" , SQL_NTS, "S");
+@@ -128,7 +124,7 @@ main(int argc, char *argv[])
+ 	CHKFetch("No");
+ 
+ 	ResetStatement();
+-	Command(Statement, "drop proc rpc_read");
++	Command("drop proc rpc_read");
+ 
+ 	/*
+ 	 * Test from Joao Amaral
+@@ -141,8 +137,8 @@ main(int argc, char *argv[])
+ 
+ 		ResetStatement();
+ 
+-		Command(Statement, "IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
+-		Command(Statement, "create proc sp_test @res int output as set @res = 456");
++		Command("IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
++		Command("create proc sp_test @res int output as set @res = 456");
+ 
+ 		ResetStatement();
+ 
+@@ -156,7 +152,7 @@ main(int argc, char *argv[])
+ 			fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
+ 			return 1;
+ 		}
+-		Command(Statement, "drop proc sp_test");
++		Command("drop proc sp_test");
+ 	}
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index bb0b542..75a9483 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.37 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.38 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -45,12 +45,12 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 	ResetStatement();
+ 
+ 	/* build store procedure to test */
+-	Command(Statement, "IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
++	Command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
+ 	sep = "'";
+ 	if (strncmp(value_to_convert, "0x", 2) == 0)
+ 		sep = "";
+ 	sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, %s%s%s)", type, type, sep, value_to_convert, sep);
+-	Command(Statement, sbuf);
++	Command(sbuf);
+ 	memset(out_buf, 0, sizeof(out_buf));
+ 
+ 	if (use_cursors) {
+@@ -108,7 +108,7 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 		fprintf(stderr, "Wrong result\n  Got: %s\n  Expected: %s\n", sbuf, expected);
+ 		exit(1);
+ 	}
+-	Command(Statement, "drop proc spTestProc");
++	Command("drop proc spTestProc");
+ }
+ 
+ static char check_truncation = 0;
+@@ -135,7 +135,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	if (value_len >= 2 && strncmp(value_to_convert, "0x", 2) == 0)
+ 		sep = "";
+ 	sprintf(sbuf, "SELECT CONVERT(%s, %s%.*s%s)", type, sep, (int) value_len, value_to_convert, sep);
+-	Command(Statement, sbuf);
++	Command(sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHKFetch("SI");
+ 	CHKFetch("No");
+@@ -148,7 +148,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	/* create a table with a column of that type */
+ 	ResetStatement();
+ 	sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s)", param_type);
+-	Command(Statement, sbuf);
++	Command(sbuf);
+ 
+ 	if (use_cursors) {
+ 		ResetStatement();
+@@ -187,14 +187,14 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		if (strncmp(expected, "0x", 2) == 0)
+ 			sep = "";
+ 		sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+-		Command(Statement, sbuf);
++		Command(sbuf);
+ 
+ 		CHKFetch("S");
+ 		CHKFetch("No");
+ 		CHKMoreResults("No");
+ 	}
+ 	check_truncation = 0;
+-	Command(Statement, "DROP TABLE #tmp_insert");
++	Command("DROP TABLE #tmp_insert");
+ }
+ 
+ static int big_endian = 1;
+@@ -248,7 +248,7 @@ AllTests(void)
+ 	m = ltime->tm_mon + 1;
+ 	d = ltime->tm_mday;
+ 	/* server concept of data can be different so try ask to server */
+-	Command(Statement, "SELECT GETDATE()");
++	Command("SELECT GETDATE()");
+ 	SQLBindCol(Statement, 1, SQL_C_CHAR, date, sizeof(date), NULL);
+ 	if (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		int a, b, c;
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index b570f7a..76f169f 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.9 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.10 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -26,7 +26,7 @@ test_err(const char *data, int c_type, const char *state)
+ 	char *buf = (char *) malloc(buf_size);
+ 
+ 	sprintf(sql, "SELECT '%s'", data);
+-	Command(Statement, sql);
++	Command(sql);
+ 	SQLFetch(Statement);
+ 	CHKGetData(1, c_type, buf, buf_size, &ind, "E");
+ 	free(buf);
+@@ -75,7 +75,7 @@ main(int argc, char *argv[])
+ 
+ 	for (;;) {
+ 		/* TODO test with VARCHAR too */
+-		Command(Statement, "SELECT CONVERT(TEXT,'Prova')");
++		Command("SELECT CONVERT(TEXT,'Prova')");
+ 
+ 		CHKFetch("S");
+ 
+@@ -97,7 +97,7 @@ main(int argc, char *argv[])
+ 		ResetStatement();
+ 
+ 		/* test with varchar, not blob but variable */
+-		Command(Statement, "SELECT CONVERT(VARCHAR(100), 'Other test')");
++		Command("SELECT CONVERT(VARCHAR(100), 'Other test')");
+ 
+ 		CHKFetch("S");
+ 
+@@ -123,7 +123,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* test with fixed length */
+-	Command(Statement, "SELECT CONVERT(INT, 12345)");
++	Command("SELECT CONVERT(INT, 12345)");
+ 
+ 	CHKFetch("S");
+ 
+@@ -165,7 +165,7 @@ main(int argc, char *argv[])
+ 		type = SQL_C_CHAR;
+ 
+ 		for (;;) {
+-			Command(Statement, "SELECT CONVERT(TEXT,'')");
++			Command("SELECT CONVERT(TEXT,'')");
+ 
+ 			CHKFetch("S");
+ 
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+index c106b7b..61a11c9 100755
+--- a/src/odbc/unittests/hidden.c
++++ b/src/odbc/unittests/hidden.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.7 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -15,13 +15,13 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #t1 ( k INT, c CHAR(10), vc VARCHAR(10) )");
+-	Command(Statement, "CREATE TABLE #tmp1 (i NUMERIC(10,0) IDENTITY PRIMARY KEY, b VARCHAR(20) NULL, c INT NOT NULL)");
++	Command("CREATE TABLE #t1 ( k INT, c CHAR(10), vc VARCHAR(10) )");
++	Command("CREATE TABLE #tmp1 (i NUMERIC(10,0) IDENTITY PRIMARY KEY, b VARCHAR(20) NULL, c INT NOT NULL)");
+ 
+ 	/* test hidden column with FOR BROWSE */
+ 	ResetStatement();
+ 
+-	Command(Statement, "SELECT c, b FROM #tmp1");
++	Command("SELECT c, b FROM #tmp1");
+ 
+ 	CHKNumResultCols(&cnt, "S");
+ 
+diff --git a/src/odbc/unittests/insert_speed.c b/src/odbc/unittests/insert_speed.c
+index 6fa5cbc..31bc2eb 100644
+--- a/src/odbc/unittests/insert_speed.c
++++ b/src/odbc/unittests/insert_speed.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: insert_speed.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: insert_speed.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SQL_QUERY_LENGTH 80
+@@ -66,15 +66,15 @@ main(int argc, char **argv)
+ 	Connect();
+ 
+ 	CommandWithResult(Statement, "DROP TABLE test");
+-	Command(Statement, "CREATE TABLE test(i int, c varchar(40))");
++	Command("CREATE TABLE test(i int, c varchar(40))");
+ 
+ 	insert_test_man();
+ 
+-	Command(Statement, "DELETE FROM test");
++	Command("DELETE FROM test");
+ 
+ 	insert_test_auto();
+ 
+-	Command(Statement, "DROP TABLE test");
++	Command("DROP TABLE test");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/moreandcount.c b/src/odbc/unittests/moreandcount.c
+index 4ecf7af..db65f84 100644
+--- a/src/odbc/unittests/moreandcount.c
++++ b/src/odbc/unittests/moreandcount.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults and SQLRowCount on batch */
+ 
+-static char software_version[] = "$Id: moreandcount.c,v 1.16 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: moreandcount.c,v 1.17 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -86,11 +86,11 @@ main(int argc, char *argv[])
+ {
+ 	Connect();
+ 
+-	Command(Statement, "create table #tmp1 (i int)");
+-	Command(Statement, "create table #tmp2 (i int)");
+-	Command(Statement, "insert into #tmp1 values(1)");
+-	Command(Statement, "insert into #tmp1 values(2)");
+-	Command(Statement, "insert into #tmp1 values(5)");
++	Command("create table #tmp1 (i int)");
++	Command("create table #tmp2 (i int)");
++	Command("insert into #tmp1 values(1)");
++	Command("insert into #tmp1 values(2)");
++	Command("insert into #tmp1 values(5)");
+ 
+ 	printf("Use direct statement\n");
+ 	DoTest(0);
+diff --git a/src/odbc/unittests/norowset.c b/src/odbc/unittests/norowset.c
+index 9a2117d..cbe7d9e 100644
+--- a/src/odbc/unittests/norowset.c
++++ b/src/odbc/unittests/norowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: norowset.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: norowset.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Test that a select following a store procedure execution return results */
+@@ -15,12 +15,12 @@ main(int argc, char *argv[])
+ 
+ 	CommandWithResult(Statement, "drop proc sp_norowset_test");
+ 
+-	Command(Statement, "create proc sp_norowset_test as begin declare @i int end");
++	Command("create proc sp_norowset_test as begin declare @i int end");
+ 
+-	Command(Statement, "exec sp_norowset_test");
++	Command("exec sp_norowset_test");
+ 
+ 	/* note, mssql 2005 seems to not return row for tempdb, use always master */
+-	Command(Statement, "select name from master..sysobjects where name = 'sysobjects'");
++	Command("select name from master..sysobjects where name = 'sysobjects'");
+ 	CHKFetch("S");
+ 
+ 	CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &dataSize, "S");
+@@ -34,7 +34,7 @@ main(int argc, char *argv[])
+ 
+ 	CHKMoreResults("No");
+ 
+-	Command(Statement, "drop proc sp_norowset_test");
++	Command("drop proc sp_norowset_test");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/paramcore.c b/src/odbc/unittests/paramcore.c
+index 5d69ae3..b179b1a 100644
+--- a/src/odbc/unittests/paramcore.c
++++ b/src/odbc/unittests/paramcore.c
+@@ -4,7 +4,7 @@
+  * Try to make core dump using SQLBindParameter
+  */
+ 
+-static char software_version[] = "$Id: paramcore.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: paramcore.c,v 1.6 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{call sp_paramcore_test(?)}"
+@@ -36,7 +36,7 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	CommandWithResult(Statement, "drop proc sp_paramcore_test");
+-	Command(Statement, "create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");
++	Command("create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");
+ 
+ 	/* here we pass a NULL buffer for input SQL_NTS */
+ 	SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb);
+@@ -56,8 +56,8 @@ main(int argc, char *argv[])
+ 	ReadError();
+ 	ResetStatement();
+ 
+-	Command(Statement, "drop proc sp_paramcore_test");
+-	Command(Statement, "create proc sp_paramcore_test @s numeric(10,2) output as select @s = 12345.6");
++	Command("drop proc sp_paramcore_test");
++	Command("create proc sp_paramcore_test @s numeric(10,2) output as select @s = 12345.6");
+ 	ResetStatement();
+ 
+ #if 0	/* this fails even on native platforms */
+@@ -72,7 +72,7 @@ main(int argc, char *argv[])
+ 	ResetStatement();
+ #endif
+ 
+-	Command(Statement, "drop proc sp_paramcore_test");
++	Command("drop proc sp_paramcore_test");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c
+index 9b17a27..9acd9b0 100644
+--- a/src/odbc/unittests/params.c
++++ b/src/odbc/unittests/params.c
+@@ -3,7 +3,7 @@
+ /* Test for store procedure and params */
+ /* Test from Tom Rogers */
+ 
+-static char software_version[] = "$Id: params.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: params.c,v 1.11 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* SP definition */
+@@ -33,10 +33,10 @@ Test(int bind_before)
+ 	Connect();
+ 
+ 	/* drop proc */
+-	Command(Statement, "IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
++	Command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
+ 
+ 	/* create proc */
+-	Command(Statement, sp_define);
++	Command(sp_define);
+ 
+ 	if (!bind_before)
+ 		CHKPrepare((SQLCHAR *) SP_TEXT, strlen(SP_TEXT), "S");
+@@ -55,7 +55,7 @@ Test(int bind_before)
+ 
+ 	CHKExecute("S");
+ 
+-	Command(Statement, "DROP PROC spTestProc");
++	Command("DROP PROC spTestProc");
+ 
+ 	printf("Output:\n");
+ 	printf("   Return Code = %d\n", (int) ReturnCode);
+diff --git a/src/odbc/unittests/prepare_results.c b/src/odbc/unittests/prepare_results.c
+index da1549e..bcf3993 100644
+--- a/src/odbc/unittests/prepare_results.c
++++ b/src/odbc/unittests/prepare_results.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for data format returned from SQLPrepare */
+ 
+-static char software_version[] = "$Id: prepare_results.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: prepare_results.c,v 1.11 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -14,10 +14,10 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "create table #odbctestdata (i int, c char(20), n numeric(34,12) )");
++	Command("create table #odbctestdata (i int, c char(20), n numeric(34,12) )");
+ 
+ 	/* reset state */
+-	Command(Statement, "select * from #odbctestdata");
++	Command("select * from #odbctestdata");
+ 	SQLFetch(Statement);
+ 	SQLMoreResults(Statement);
+ 
+@@ -63,7 +63,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* TODO test SQLDescribeParam (when implemented) */
+-	Command(Statement, "drop table #odbctestdata");
++	Command("drop table #odbctestdata");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/preperror.c b/src/odbc/unittests/preperror.c
+index e3966bb..a6b0a71 100644
+--- a/src/odbc/unittests/preperror.c
++++ b/src/odbc/unittests/preperror.c
+@@ -2,7 +2,7 @@
+ 
+ /* test error on prepared statement, from Nathaniel Talbott test */
+ 
+-static char software_version[] = "$Id: preperror.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: preperror.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -14,7 +14,7 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #urls ( recdate DATETIME ) ");
++	Command("CREATE TABLE #urls ( recdate DATETIME ) ");
+ 
+ 	/* test implicit conversion error */
+ 	CHKExecDirect((SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( '2003-10-1 10:11:1 0' )", SQL_NTS, "E");
+diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c
+index d23cea7..9ba83ae 100644
+--- a/src/odbc/unittests/print.c
++++ b/src/odbc/unittests/print.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: print.c,v 1.20 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: print.c,v 1.21 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -32,10 +32,7 @@ test(int odbc3)
+ 	/* issue print statement and test message returned */
+ 	output[0] = 0;
+ 	query = "print 'START' select count(*) from sysobjects where name='sysobjects' print 'END'";
+-	if (CommandWithResult(Statement, query) != SQL_SUCCESS_WITH_INFO) {
+-		printf("SQLExecDirect should return SQL_SUCCESS_WITH_INFO\n");
+-		return 1;
+-	}
++	CHKR(CommandWithResult, (Statement, query), "I");
+ 	ReadError();
+ 	if (!strstr((char *) output, "START")) {
+ 		printf("Message invalid\n");
+@@ -98,10 +95,7 @@ test(int odbc3)
+ 	}
+ 
+ 	/* issue invalid command and test error */
+-	if (CommandWithResult(Statement, "SELECT donotexistsfield FROM donotexiststable") != SQL_ERROR) {
+-		printf("SQLExecDirect returned strange results\n");
+-		return 1;
+-	}
++	CHKR(CommandWithResult, (Statement, "SELECT donotexistsfield FROM donotexiststable"), "E");
+ 	ReadError();
+ 
+ 	/* test no data returned */
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index e5cb613..1598231 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.13 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.14 2008/11/04 14:46:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -24,7 +24,7 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	/* create table to hold data */
+-	Command(Statement, "CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
++	Command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
+ 
+ 	sql_type = SQL_LONGVARCHAR;
+ 	type = SQL_C_CHAR;
+@@ -44,8 +44,7 @@ main(int argc, char *argv[])
+ 
+ 		p = test_text;
+ 		n = 5;
+-		if (SQLParamData(Statement, &ptr) != SQL_NEED_DATA)
+-			ODBC_REPORT_ERROR("Wrong result from SQLParamData");
++		CHKParamData(&ptr, "Ne");
+ 		if (ptr != (SQLPOINTER) 123)
+ 			ODBC_REPORT_ERROR("Wrong pointer from SQLParamData");
+ 		while (*p) {
+@@ -70,7 +69,7 @@ main(int argc, char *argv[])
+ 		CHKParamData(&ptr, "E");
+ 
+ 		/* check state  and reset some possible buffers */
+-		Command(Statement, "DECLARE @i INT");
++		Command("DECLARE @i INT");
+ 
+ 		if (sql_type == SQL_LONGVARCHAR && db_is_microsoft() && db_version_int() >= 0x08000000u) {
+ 			sql_type = SQL_WLONGVARCHAR;
+@@ -118,7 +117,7 @@ main(int argc, char *argv[])
+ 	CHKParamData(&ptr, "E");
+ 
+ 	/* check state  and reset some possible buffers */
+-	Command(Statement, "DECLARE @i2 INT");
++	Command("DECLARE @i2 INT");
+ 
+ 
+ 	/* test len == 0 case from ML */
+diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c
+index 82a5538..0321b2f 100644
+--- a/src/odbc/unittests/raiserror.c
++++ b/src/odbc/unittests/raiserror.c
+@@ -4,7 +4,7 @@
+ 
+ /* TODO add support for Sybase */
+ 
+-static char software_version[] = "$Id: raiserror.c,v 1.22 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: raiserror.c,v 1.23 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{?=call #tmp1(?,?,?)}"
+@@ -251,7 +251,7 @@ Test2(int nocount, int second_select)
+ 
+ 	Test(11);
+ 
+-	Command(Statement, "DROP PROC #tmp1");
++	Command("DROP PROC #tmp1");
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/rebindpar.c b/src/odbc/unittests/rebindpar.c
+index 87bcbea..bb184a7 100644
+--- a/src/odbc/unittests/rebindpar.c
++++ b/src/odbc/unittests/rebindpar.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for executing SQLExecute and rebinding parameters */
+ 
+-static char software_version[] = "$Id: rebindpar.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: rebindpar.c,v 1.9 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
+@@ -24,7 +24,7 @@ TestInsert(char *buf)
+ 
+ 	SWAP_STMT(stmt);
+ 	sprintf(sql, "SELECT 1 FROM #tmp1 WHERE c = '%s'", buf);
+-	Command(Statement, sql);
++	Command(sql);
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+ 	CHKMoreResults("No");
+@@ -43,7 +43,7 @@ Test(int prebind)
+ 	for (i = 0; i < 21; ++i)
+ 		strcat(buf, "miao");
+ 
+-	Command(Statement, "DELETE FROM #tmp1");
++	Command("DELETE FROM #tmp1");
+ 
+ 	CHKAllocStmt(&stmt, "S");
+ 
+@@ -71,7 +71,7 @@ main(int argc, char *argv[])
+ {
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #tmp1 (c VARCHAR(200))");
++	Command("CREATE TABLE #tmp1 (c VARCHAR(200))");
+ 
+ 	Test(1);
+ 	Test(0);
+diff --git a/src/odbc/unittests/rownumber.c b/src/odbc/unittests/rownumber.c
+index 83fd65c..0ccae96 100644
+--- a/src/odbc/unittests/rownumber.c
++++ b/src/odbc/unittests/rownumber.c
+@@ -7,7 +7,7 @@
+  * TODO make it work and add to Makefile.am
+  */
+ 
+-static char software_version[] = "$Id: rownumber.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: rownumber.c,v 1.5 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -70,11 +70,11 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "create table #tmp1 (i int)");
+-	Command(Statement, "create table #tmp2 (i int)");
+-	Command(Statement, "insert into #tmp1 values(1)");
+-	Command(Statement, "insert into #tmp1 values(2)");
+-	Command(Statement, "insert into #tmp1 values(5)");
++	Command("create table #tmp1 (i int)");
++	Command("create table #tmp2 (i int)");
++	Command("insert into #tmp1 values(1)");
++	Command("insert into #tmp1 values(2)");
++	Command("insert into #tmp1 values(5)");
+ 
+ 	DoTest();
+ 
+diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c
+index 9e79bbd..215fbe0 100644
+--- a/src/odbc/unittests/rowset.c
++++ b/src/odbc/unittests/rowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rowset.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: rowset.c,v 1.5 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -24,7 +24,7 @@ test_err(int n)
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+ 		Disconnect();
+ 		exit(1);
+-        }
++	}
+ }
+ 
+ int
+@@ -63,7 +63,7 @@ main(int argc, char *argv[])
+ 	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0, "S");
+ 
+ 	/* now check that SQLExtendedFetch works as expected */
+-	Command(Statement, "CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
++	Command("CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
+ 	for (i = 0; i < 10; ++i) {
+ 		char s[10];
+ 		char sql[128];
+@@ -71,7 +71,7 @@ main(int argc, char *argv[])
+ 		memset(s, 'a' + i, 9);
+ 		s[9] = 0;
+ 		sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s);
+-		Command(Statement, sql);
++		Command(sql);
+ 	}
+ 
+ 	ResetStatement();
+diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c
+index 7027df1..405a0ca 100644
+--- a/src/odbc/unittests/rpc.c
++++ b/src/odbc/unittests/rpc.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.11 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.12 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char procedure_sql[] = 
+@@ -32,7 +32,7 @@ static const char procedure_sql[] =
+ 		"END \n";
+ 
+ 
+-static int
++static void
+ init_proc(const char *name)
+ {
+ 	static char cmd[4096];
+@@ -47,15 +47,8 @@ init_proc(const char *name)
+ 	printf("Creating procedure %s\n", name);
+ 	sprintf(cmd, procedure_sql, name);
+ 
+-	if (!SQL_SUCCEEDED(SQLExecDirect(Statement, (SQLCHAR *) cmd, SQL_NTS))) {
+-		if (name[0] == '#')
+-			printf("Failed to create procedure %s. Wrong permission or not MSSQL.\n", name);
+-		else
+-			printf("Failed to create procedure %s. Wrong permission.\n", name);
+-		CheckReturn();
+-		exit(1);
+-	}
+-	return 0;
++	/* create procedure. Fails if wrong permission or not MSSQL */
++	CHKExecDirect((SQLCHAR *) cmd, SQL_NTS, "SI");
+ }
+ 
+ static void
+@@ -231,7 +224,7 @@ main(int argc, char *argv[])
+ 	Test(proc_name);
+ 	
+ 	printf("dropping procedure\n");
+-	Command(Statement, drop_proc);
++	Command(drop_proc);
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/scroll.c b/src/odbc/unittests/scroll.c
+index b5dc2a6..d87e29d 100644
+--- a/src/odbc/unittests/scroll.c
++++ b/src/odbc/unittests/scroll.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: scroll.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: scroll.c,v 1.9 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -18,7 +18,6 @@ main(int argc, char *argv[])
+ 	SQLUSMALLINT statuses[ROWS];
+ 	SQLUSMALLINT i;
+ 	SQLULEN num_row;
+-	SQLRETURN retcode;
+ 	int i_test;
+ 
+ 	typedef struct _test
+@@ -48,13 +47,13 @@ main(int argc, char *argv[])
+ 	CheckCursor();
+ 
+ 	/* create test table */
+-	Command(Statement, "IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+-	Command(Statement, "CREATE TABLE #test(i int, c varchar(6))");
+-	Command(Statement, "INSERT INTO #test(i, c) VALUES(1, 'a')");
+-	Command(Statement, "INSERT INTO #test(i, c) VALUES(2, 'bb')");
+-	Command(Statement, "INSERT INTO #test(i, c) VALUES(3, 'ccc')");
+-	Command(Statement, "INSERT INTO #test(i, c) VALUES(4, 'dddd')");
+-	Command(Statement, "INSERT INTO #test(i, c) VALUES(5, 'eeeee')");
++	Command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
++	Command("CREATE TABLE #test(i int, c varchar(6))");
++	Command("INSERT INTO #test(i, c) VALUES(1, 'a')");
++	Command("INSERT INTO #test(i, c) VALUES(2, 'bb')");
++	Command("INSERT INTO #test(i, c) VALUES(3, 'ccc')");
++	Command("INSERT INTO #test(i, c) VALUES(4, 'dddd')");
++	Command("INSERT INTO #test(i, c) VALUES(5, 'eeeee')");
+ 
+ 	/* set cursor options */
+ 	ResetStatement();
+@@ -77,8 +76,11 @@ main(int argc, char *argv[])
+ 
+ 		printf("Test %d\n", i_test + 1);
+ 
+-		retcode = SQLFetchScroll(Statement, t->type, t->irow);
+-		if (retcode == SQL_SUCCESS) {
++		if (t->start == -1) {
++			CHKFetchScroll(t->type, t->irow, "No");
++		} else {
++			CHKFetchScroll(t->type, t->irow, "S");
++
+ 			if (t->start < 1) {
+ 				fprintf(stderr, "Rows not expected\n");
+ 				exit(1);
+@@ -107,14 +109,7 @@ main(int argc, char *argv[])
+ 					exit(1);
+ 				}
+ 			}
+-			continue;
+ 		}
+-
+-		if (retcode == SQL_NO_DATA && t->start == -1)
+-			continue;
+-
+-		fprintf(stderr, "retcode = %d\n", retcode);
+-		ODBC_REPORT_ERROR("SQLFetchScroll");
+ 	}
+ 
+ 	ResetStatement();
+diff --git a/src/odbc/unittests/t0001.c b/src/odbc/unittests/t0001.c
+index 5b4e160..4872809 100644
+--- a/src/odbc/unittests/t0001.c
++++ b/src/odbc/unittests/t0001.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.17 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.18 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -16,20 +16,20 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
++	Command("if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
+ 
+ 	command = "create table #odbctestdata ("
+ 		"col1 varchar(30) not null,"
+ 		"col2 int not null,"
+ 		"col3 float not null," "col4 numeric(18,6) not null," "col5 datetime not null," "col6 text not null)";
+-	Command(Statement, command);
++	Command(command);
+ 
+ 	command = "insert #odbctestdata values ("
+ 		"'ABCDEFGHIJKLMNOP',"
+ 		"123456," "1234.56," "123456.78," "'Sep 11 2001 10:00AM'," "'just to check returned length...')";
+-	Command(Statement, command);
++	Command(command);
+ 
+-	Command(Statement, "select * from #odbctestdata");
++	Command("select * from #odbctestdata");
+ 
+ 	CHKFetch("SI");
+ 
+@@ -45,7 +45,7 @@ main(int argc, char *argv[])
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	Command(Statement, "drop table #odbctestdata");
++	Command("drop table #odbctestdata");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/t0002.c b/src/odbc/unittests/t0002.c
+index 120b515..c89628c 100644
+--- a/src/odbc/unittests/t0002.c
++++ b/src/odbc/unittests/t0002.c
+@@ -1,8 +1,10 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.15 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.16 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++#define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -10,10 +12,10 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
++	Command("if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
+ 
+-	Command(Statement, "create table #odbctestdata (i int)");
+-	Command(Statement, "insert #odbctestdata values (123)");
++	Command("create table #odbctestdata (i int)");
++	Command("insert #odbctestdata values (123)");
+ 
+ 	/*
+ 	 * now we allocate another statement, select, get all results
+@@ -24,13 +26,15 @@ main(int argc, char *argv[])
+ 	Statement = SQL_NULL_HSTMT;
+ 	CHKAllocStmt(&Statement, "S");
+ 
+-	Command(Statement, "select * from #odbctestdata where 0=1");
++	Command("select * from #odbctestdata where 0=1");
+ 
+ 	CHKFetch("No");
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	Command(old_Statement, "select * from #odbctestdata");
++	SWAP_STMT(old_Statement);
++	Command("select * from #odbctestdata");
++	SWAP_STMT(old_Statement);
+ 
+ 	/* drop first statement .. data should not disappear */
+ 	CHKFreeStmt(SQL_DROP, "S");
+@@ -42,7 +46,7 @@ main(int argc, char *argv[])
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	Command(Statement, "drop table #odbctestdata");
++	Command("drop table #odbctestdata");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/t0003.c b/src/odbc/unittests/t0003.c
+index 8c5e115..2a0e9f5 100644
+--- a/src/odbc/unittests/t0003.c
++++ b/src/odbc/unittests/t0003.c
+@@ -2,17 +2,17 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.18 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.19 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ DoTest(int prepared)
+ {
+-	Command(Statement, "create table #odbctestdata (i int)");
++	Command("create table #odbctestdata (i int)");
+ 
+ 	/* test that 2 empty result set are returned correctly */
+ 	if (!prepared) {
+-		Command(Statement, "select * from #odbctestdata select * from #odbctestdata");
++		Command("select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+ 		CHKPrepare((SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
+ 		CHKExecute("S");
+@@ -28,9 +28,9 @@ DoTest(int prepared)
+ 	CHKMoreResults("No");
+ 
+ 	/* test that skipping a no empty result go to other result set */
+-	Command(Statement, "insert into #odbctestdata values(123)");
++	Command("insert into #odbctestdata values(123)");
+ 	if (!prepared) {
+-		Command(Statement, "select * from #odbctestdata select * from #odbctestdata");
++		Command("select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+ 		CHKPrepare((SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
+ 		CHKExecute("S");
+@@ -45,7 +45,7 @@ DoTest(int prepared)
+ 
+ 	CHKMoreResults("No");
+ 
+-	Command(Statement, "drop table #odbctestdata");
++	Command("drop table #odbctestdata");
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index 9a42ab7..6a99d5e 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.7 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -17,10 +17,10 @@ check_ipd_params(void)
+ 	SQLHDESC desc;
+ 	SQLINTEGER ind;
+ 
+-	CHK(SQLGetStmtAttr,(Statement, SQL_ATTR_PARAMS_PROCESSED_PTR, &ptr, sizeof(ptr), NULL));
++	CHKGetStmtAttr(SQL_ATTR_PARAMS_PROCESSED_PTR, &ptr, sizeof(ptr), NULL, "S");
+ 
+ 	/* get IPD */
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind));
++	CHKGetStmtAttr(SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+ 	CHK(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
+ 
+@@ -43,7 +43,7 @@ set_ipd_params2(SQLULEN *ptr)
+ 	SQLINTEGER ind;
+ 
+ 	/* get IPD */
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind));
++	CHKGetStmtAttr(SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+ 	CHK(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0));
+ }
+@@ -51,7 +51,7 @@ set_ipd_params2(SQLULEN *ptr)
+ static void
+ set_ipd_params3(SQLULEN *ptr)
+ {
+-	CHK(SQLParamOptions, (Statement, 2, ptr));
++	CHKParamOptions(2, ptr, "S");
+ }
+ 
+ typedef void (*rows_set_t)(SQLULEN*);
+@@ -103,7 +103,7 @@ test_params(void)
+ 		CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
+ 
+-		Command(Statement, "INSERT INTO #tmp1(i) VALUES(?)");
++		Command("INSERT INTO #tmp1(i) VALUES(?)");
+ 		SQLMoreResults(Statement);
+ 		for (n = 0; n < ARRAY_SIZE; ++n)
+ 			SQLMoreResults(Statement);
+@@ -134,10 +134,10 @@ check_ird_params(void)
+ 	SQLHDESC desc;
+ 	SQLINTEGER ind;
+ 
+-	CHK(SQLGetStmtAttr,(Statement, SQL_ATTR_ROWS_FETCHED_PTR, &ptr, sizeof(ptr), NULL));
++	CHKGetStmtAttr(SQL_ATTR_ROWS_FETCHED_PTR, &ptr, sizeof(ptr), NULL, "S");
+ 
+ 	/* get IRD */
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind));
++	CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+ 	CHK(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
+ 
+@@ -160,7 +160,7 @@ set_ird_params2(SQLULEN *ptr)
+ 	SQLINTEGER ind;
+ 
+ 	/* get IRD */
+-	CHK(SQLGetStmtAttr, (Statement, SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind));
++	CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+ 	CHK(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0));
+ }
+@@ -208,16 +208,16 @@ test_rows(void)
+ //		CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ //		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
+ 
+-		CHK(SQLBindCol, (Statement, 1, SQL_C_ULONG, ids, 0, id_lens));
++		CHKBindCol(1, SQL_C_ULONG, ids, 0, id_lens, "S");
+ 		if (*p) {
+ 			CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 
+-			Command(Statement, "SELECT DISTINCT i FROM #tmp1");
++			Command("SELECT DISTINCT i FROM #tmp1");
+ 			SQLFetch(Statement);
+ 		} else {
+ 			CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+-			Command(Statement, "SELECT DISTINCT i FROM #tmp1");
+-			CHK(SQLExtendedFetch, (Statement, SQL_FETCH_NEXT, 0, &len, NULL));
++			Command("SELECT DISTINCT i FROM #tmp1");
++			CHKExtendedFetch(SQL_FETCH_NEXT, 0, &len, NULL, "S");
+ 		}
+ 		SQLMoreResults(Statement);
+ 
+@@ -244,7 +244,7 @@ main(void)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command(Statement, "create table #tmp1 (i int)");
++	Command("create table #tmp1 (i int)");
+ 
+ 	test_params();
+ 	test_rows();
+diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c
+index 3cc3926..6b80e8e 100644
+--- a/src/odbc/unittests/testodbc.c
++++ b/src/odbc/unittests/testodbc.c
+@@ -10,7 +10,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: testodbc.c,v 1.13 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: testodbc.c,v 1.14 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef DEBUG
+@@ -37,74 +37,12 @@ typedef struct
+ } DbTestEntry;
+ 
+ /*
+- * Output ODBC errors.
+- */
+-static void
+-DispODBCErrs(void)
+-{
+-	SQLCHAR buffer[256];
+-	SQLCHAR sqlState[16];
+-
+-	/* Statement errors */
+-	if (Statement) {
+-		while (SQLError(Environment, Connection, Statement, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
+-			AB_ERROR(("%s, SQLSTATE=%s", buffer, sqlState));
+-		}
+-	}
+-
+-	/* Connection errors */
+-	while (SQLError(Environment, Connection, SQL_NULL_HSTMT, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
+-		AB_ERROR(("%s, SQLSTATE=%s", buffer, sqlState));
+-	}
+-
+-	/* Environmental errors */
+-	while (SQLError(Environment, SQL_NULL_HDBC, SQL_NULL_HSTMT, sqlState, 0, buffer, sizeof(buffer), 0) == SQL_SUCCESS) {
+-		AB_ERROR(("%s, SQLSTATE=%s", buffer, sqlState));
+-	}
+-}
+-
+-/*
+- * Output ODBC diagnostics. Only used for 'raw' ODBC tests.
+- */
+-static void
+-DispODBCDiags(void)
+-{
+-	SQLSMALLINT recNumber;
+-	SQLCHAR sqlState[10];
+-	SQLINTEGER nativeError = -99;
+-	SQLCHAR messageText[500];
+-	SQLSMALLINT bufferLength = 500;
+-	SQLSMALLINT textLength = -99;
+-	SQLRETURN status;
+-
+-	recNumber = 1;
+-
+-	AB_FUNCT(("DispODBCDiags (in)"));
+-
+-	do {
+-		status = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, recNumber,
+-				       sqlState, &nativeError, messageText, bufferLength, &textLength);
+-		if (status != SQL_SUCCESS) {
+-			/* No data mean normal end of iteration. Anything else is error. */
+-			if (status != SQL_NO_DATA) {
+-				AB_ERROR(("SQLGetDiagRec status is %d", status));
+-			}
+-			break;
+-		}
+-		printf("DIAG #%d, sqlState=%s, nativeError=%d, message=%s\n", recNumber, sqlState, (int) nativeError, messageText);
+-		recNumber++;
+-	} while (status == SQL_SUCCESS);
+-
+-	AB_FUNCT(("DispODBCDiags (out)"));
+-}
+-
+-/*
+  * Test that makes a parameterized ODBC query using SQLPrepare and SQLExecute
+  */
+ static int
+ TestRawODBCPreparedQuery(void)
+ {
+-	SQLCHAR queryString[200];
++	SQLCHAR *queryString;
+ 	SQLLEN lenOrInd = 0;
+ 	SQLSMALLINT supplierId = 4;
+ 	int count;
+@@ -117,7 +55,7 @@ TestRawODBCPreparedQuery(void)
+ 
+ 	/* MAKE QUERY */
+ 
+-	Command(Statement, "CREATE TABLE #Products ("
++	Command("CREATE TABLE #Products ("
+ 		"ProductID int NOT NULL ,"
+ 		"ProductName varchar (40) ,"
+ 		"SupplierID int NULL ,"
+@@ -136,7 +74,7 @@ TestRawODBCPreparedQuery(void)
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(12,'Queso Manchego La Pastora',5,4,'10 - 500 g pkgs.',38.00,86,0,0,0)");
+ 	while (SQLMoreResults(Statement) == SQL_SUCCESS);
+ 
+-	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
++	queryString = (SQLCHAR *) "SELECT * FROM #Products WHERE SupplierID = ?";
+ 
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd, "S");
+ 
+@@ -175,7 +113,6 @@ TestRawODBCPreparedQuery(void)
+ static int
+ TestRawODBCDirectQuery(void)
+ {
+-	SQLCHAR queryString[200];
+ 	SQLLEN lenOrInd = 0;
+ 	SQLSMALLINT supplierId = 1;
+ 	int count;
+@@ -188,7 +125,7 @@ TestRawODBCDirectQuery(void)
+ 
+ 	/* MAKE QUERY */
+ 
+-	Command(Statement, "CREATE TABLE #Products ("
++	Command("CREATE TABLE #Products ("
+ 		"ProductID int NOT NULL ,"
+ 		"ProductName varchar (40) ,"
+ 		"SupplierID int NULL ,"
+@@ -207,11 +144,9 @@ TestRawODBCDirectQuery(void)
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(5,'Chef Anton''s Gumbo Mix',2,2,'36 boxes',21.35,0,0,0,1) ");
+ 	while (SQLMoreResults(Statement) == SQL_SUCCESS);
+ 
+-	strcpy((char *) queryString, "SELECT * FROM #Products WHERE SupplierID = ?");
+-
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd, "S");
+ 
+-	CHKExecDirect(queryString, SQL_NTS, "S");
++	CHKExecDirect((SQLCHAR *) "SELECT * FROM #Products WHERE SupplierID = ?", SQL_NTS, "S");
+ 
+ 	count = 0;
+ 
+@@ -247,7 +182,7 @@ TestRawODBCGuid(void)
+ {
+ 	SQLRETURN status;
+ 
+-	SQLCHAR queryString[300];
++	SQLCHAR *queryString;
+ 	SQLLEN lenOrInd;
+ 	SQLSMALLINT age;
+ 	SQLCHAR guid[40];
+@@ -267,30 +202,22 @@ TestRawODBCGuid(void)
+ 
+ 	AB_PRINT(("Creating #pet table"));
+ 
+-	strcpy((char *) (queryString), "CREATE TABLE #pet (name VARCHAR(20), owner VARCHAR(20), "
+-	       "species VARCHAR(20), sex CHAR(1), age INTEGER, " "guid UNIQUEIDENTIFIER DEFAULT NEWID() ); ");
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS && status != SQL_NO_DATA) {
+-		AB_ERROR(("Create table failed"));
+-		goto odbcfail;
+-	}
++	queryString = (SQLCHAR *) "CREATE TABLE #pet (name VARCHAR(20), owner VARCHAR(20), "
++	       "species VARCHAR(20), sex CHAR(1), age INTEGER, " "guid UNIQUEIDENTIFIER DEFAULT NEWID() ); ";
++	CHKExecDirect(queryString, SQL_NTS, "SNo");
+ 
+ 	CommandWithResult(Statement, "DROP PROC GetGUIDRows");
+ 
+ 	AB_PRINT(("Creating stored proc GetGUIDRows"));
+ 
+-	strcpy((char *) (queryString), "CREATE PROCEDURE GetGUIDRows (@guidpar uniqueidentifier) AS \
+-                SELECT name, guid FROM #pet WHERE guid = @guidpar");
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
+-	if (status != SQL_SUCCESS && status != SQL_NO_DATA) {
+-		AB_ERROR(("Create procedure failed"));
+-		goto odbcfail;
+-	}
++	queryString = (SQLCHAR *) "CREATE PROCEDURE GetGUIDRows (@guidpar uniqueidentifier) AS \
++                SELECT name, guid FROM #pet WHERE guid = @guidpar";
++	CHKExecDirect(queryString, SQL_NTS, "SNo");
+ 
+ 	AB_PRINT(("Insert row 1"));
+ 
+-	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age ) \
+-                         VALUES ( 'Fang', 'Mike', 'dog', 'm', 12 );");
++	queryString = (SQLCHAR *) "INSERT INTO #pet( name, owner, species, sex, age ) \
++                         VALUES ( 'Fang', 'Mike', 'dog', 'm', 12 );";
+ 	CHKExecDirect(queryString, SQL_NTS, "S");
+ 
+ 	AB_PRINT(("Insert row 2"));
+@@ -298,9 +225,9 @@ TestRawODBCGuid(void)
+ 	/*
+ 	 * Ok - new row with explicit GUID, but parameterised age.
+ 	 */
+-	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
++	queryString = (SQLCHAR *) "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
+                          VALUES ( 'Splash', 'Dan', 'fish', 'm', ?, \
+-                         '12345678-1234-1234-1234-123456789012' );");
++                         '12345678-1234-1234-1234-123456789012' );";
+ 
+ 	lenOrInd = 0;
+ 	age = 3;
+@@ -313,8 +240,8 @@ TestRawODBCGuid(void)
+ 	/*
+ 	 * Ok - new row with parameterised GUID.
+ 	 */
+-	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
+-                         VALUES ( 'Woof', 'Tom', 'cat', 'f', 2, ? );");
++	queryString = (SQLCHAR *) "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
++                         VALUES ( 'Woof', 'Tom', 'cat', 'f', 2, ? );";
+ 
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "87654321-4321-4321-4321-123456789abc");
+@@ -326,8 +253,8 @@ TestRawODBCGuid(void)
+ 	/*
+ 	 * Ok - new row with parameterised GUID.
+ 	 */
+-	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
+-                         VALUES ( 'Spike', 'Diane', 'pig', 'f', 4, ? );");
++	queryString = (SQLCHAR *) "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
++                         VALUES ( 'Spike', 'Diane', 'pig', 'f', 4, ? );";
+ 
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+@@ -339,8 +266,8 @@ TestRawODBCGuid(void)
+ 	/*
+ 	 * Ok - new row with parameterised GUID.
+ 	 */
+-	strcpy((char *) (queryString), "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
+-                         VALUES ( 'Fluffy', 'Sam', 'dragon', 'm', 16, ? );");
++	queryString = (SQLCHAR *) "INSERT INTO #pet( name, owner, species, sex, age, guid ) \
++                         VALUES ( 'Fluffy', 'Sam', 'dragon', 'm', 16, ? );";
+ 
+ 	sqlguid.Data1 = 0xaabbccdd;
+ 	sqlguid.Data2 = 0xeeff;
+@@ -368,7 +295,7 @@ TestRawODBCGuid(void)
+ 	 * Now retrieve rows - especially GUID column values.
+ 	 */
+ 	AB_PRINT(("retrieving name and guid"));
+-	strcpy((char *) (queryString), "SELECT name, guid FROM #pet");
++	queryString = (SQLCHAR *) "SELECT name, guid FROM #pet";
+ 	CHKExecDirect(queryString, SQL_NTS, "S");
+ 	while (SQLFetch(Statement) == SQL_SUCCESS) {
+ 		count++;
+@@ -390,7 +317,7 @@ TestRawODBCGuid(void)
+ 	 */
+ 
+ 	AB_PRINT(("retrieving name and guid again"));
+-	strcpy((char *) (queryString), "SELECT name, guid FROM #pet");
++	queryString = (SQLCHAR *) "SELECT name, guid FROM #pet";
+ 	CHKExecDirect(queryString, SQL_NTS, "S");
+ 	while (CHKFetch("SNo") == SQL_SUCCESS) {
+ 		count++;
+@@ -416,7 +343,7 @@ TestRawODBCGuid(void)
+ 	 */
+ 	AB_PRINT(("retrieving name and guid"));
+ 
+-	strcpy((char *) (queryString), "{call GetGUIDRows(?)}");
++	queryString = (SQLCHAR *) "{call GetGUIDRows(?)}";
+ 	lenOrInd = SQL_NTS;
+ 	strcpy((char *) (guid), "87654321-4321-4321-4321-123456789abc");
+ 
+@@ -445,12 +372,6 @@ TestRawODBCGuid(void)
+ 
+ 	AB_FUNCT(("TestRawODBCGuid (out): ok"));
+ 	return TRUE;
+-
+-      odbcfail:
+-	DispODBCErrs();
+-	DispODBCDiags();
+-	AB_FUNCT(("TestRawODBCGuid (out): error"));
+-	return FALSE;
+ }
+ 
+ /**
+@@ -507,9 +428,7 @@ main(int argc, char *argv[])
+ {
+ 	use_odbc_version3 = 1;
+ 
+-	if (RunTests()) {
++	if (RunTests())
+ 		return 0;	/* Success */
+-	} else {
+-		return 1;	/* Error code */
+-	}
++	return 1;	/* Error code */
+ }
+diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c
+index 5e86031..5a820aa 100644
+--- a/src/odbc/unittests/timeout.c
++++ b/src/odbc/unittests/timeout.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test timeout of query */
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.9 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.10 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -31,13 +31,13 @@ main(int argc, char *argv[])
+ 
+ 	/* here we can't use temporary table cause we use two connection */
+ 	CommandWithResult(Statement, "drop table test_timeout");
+-	Command(Statement, "create table test_timeout(n numeric(18,0) primary key, t varchar(30))");
++	Command("create table test_timeout(n numeric(18,0) primary key, t varchar(30))");
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 
+-	Command(Statement, "insert into test_timeout(n, t) values(1, 'initial')");
++	Command("insert into test_timeout(n, t) values(1, 'initial')");
+ 	EndTransaction(SQL_COMMIT);
+ 
+-	Command(Statement, "update test_timeout set t = 'second' where n = 1");
++	Command("update test_timeout set t = 'second' where n = 1");
+ 
+ 	/* save this connection and do another */
+ 	env = Environment;
+@@ -76,7 +76,7 @@ main(int argc, char *argv[])
+ 
+ 	/* Sybase do not accept DROP TABLE during a transaction */
+ 	AutoCommit(SQL_AUTOCOMMIT_ON);
+-	Command(Statement, "drop table test_timeout");
++	Command("drop table test_timeout");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/timeout2.c b/src/odbc/unittests/timeout2.c
+index 0d5802d..a5f8f26 100644
+--- a/src/odbc/unittests/timeout2.c
++++ b/src/odbc/unittests/timeout2.c
+@@ -14,7 +14,7 @@
+  * Test from Ou Liu, cf "Query Time Out", 2006-08-08
+  */
+ 
+-static char software_version[] = "$Id: timeout2.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: timeout2.c,v 1.7 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if defined(__MINGW32__) || defined(WIN32)
+@@ -28,8 +28,8 @@ main(int argc, char *argv[])
+ 
+ 	Connect();
+ 
+-	Command(Statement, "create table #timeout(i int)");
+-	Command(Statement, "insert into #timeout values(1)");
++	Command("create table #timeout(i int)");
++	Command("insert into #timeout values(1)");
+ 
+ 	for (i = 0; i < 2; ++i) {
+ 
+diff --git a/src/odbc/unittests/transaction.c b/src/odbc/unittests/transaction.c
+index a7408a9..d90a685 100644
+--- a/src/odbc/unittests/transaction.c
++++ b/src/odbc/unittests/transaction.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: transaction.c,v 1.14 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: transaction.c,v 1.15 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int
+@@ -8,7 +8,7 @@ Test(int discard_test)
+ {
+ 	SQLINTEGER out_buf;
+ 	SQLLEN out_len;
+-	int result = 0;
++	SQLRETURN RetCode;
+ 	SQLLEN rows;
+ 	int retcode = 0;
+ 	char buf[512];
+@@ -27,18 +27,18 @@ Test(int discard_test)
+ 	/* create stored proc */
+ 	CommandWithResult(Statement, "DROP PROCEDURE testinsert");
+ 
+-	Command(Statement, createProcedure);
++	Command(createProcedure);
+ 
+ 	/* create stored proc that generates an error */
+ 	CommandWithResult(Statement, "DROP PROCEDURE testerror");
+ 
+-	Command(Statement, createErrorProcedure);
++	Command(createErrorProcedure);
+ 
+ 	/* Start transaction */
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
+ 
+ 	/* Insert a value */
+-	Command(Statement, "EXEC testinsert 1");
++	Command("EXEC testinsert 1");
+ 
+ 	/* we should be able to read row count */
+ 	CHKRowCount(&rows, "S");
+@@ -52,7 +52,7 @@ Test(int discard_test)
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
+ 
+ 	/* Insert another value */
+-	Command(Statement, "EXEC testinsert 2");
++	Command("EXEC testinsert 2");
+ 
+ 	/* Roll back transaction */
+ 	CHKEndTran(SQL_HANDLE_DBC, Connection, SQL_ROLLBACK, "S");
+@@ -62,10 +62,10 @@ Test(int discard_test)
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0, "S");
+ 
+ 	/* generate an error */
+-	Command(Statement, "EXEC testerror");
++	Command("EXEC testerror");
+ 	CHKBindCol(1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len, "S");
+ 
+-	while ((result = SQLFetch(Statement)) == SQL_SUCCESS) {
++	while (CHKFetch("SNo") == SQL_SUCCESS) {
+ 		printf("\t%ld\n", (long int) out_buf);
+ 		if (out_buf != 1) {
+ 			fprintf(stderr, "error: expected to select 1 got %ld\n", (long int) out_buf);
+@@ -74,35 +74,12 @@ Test(int discard_test)
+ 		}
+ 	}
+ 
+-	if (result != SQL_NO_DATA) {
+-		ODBC_REPORT_ERROR("error: SQLFetch: testerror");
+-		goto cleanup;
+-	}
+-
+-	result = SQLMoreResults(Statement);
+-	printf("SQLMoreResults returned %d\n", result);
+-
+-	if (result != SQL_ERROR) {
+-		fprintf(stderr, "SQLMoreResults should return error\n");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHKMoreResults("E");
+ 
+-	result = SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *)buf, sizeof(buf), NULL);
+-	if (result != SQL_SUCCESS && result != SQL_SUCCESS_WITH_INFO) {
+-		fprintf(stderr, "Error not set (line %d)\n", __LINE__);
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *)buf, sizeof(buf), NULL, "SI");
+ 	printf("err=%s\n", buf);
+ 
+-	result = SQLMoreResults(Statement);
+-	printf("SQLMoreResults returned %d\n", result);
+-	if (result != SQL_NO_DATA) {
+-		fprintf(stderr, "SQLMoreResults should return error");
+-		retcode = 1;
+-		goto cleanup;
+-	}
++	CHKMoreResults("No");
+ 
+       cleanup:
+ 	/* drop table */
+@@ -121,7 +98,7 @@ main(int argc, char *argv[])
+ 
+ 	/* create table */
+ 	CommandWithResult(Statement, "DROP TABLE TestTransaction");
+-	Command(Statement, "CREATE TABLE TestTransaction ( value INT )");
++	Command("CREATE TABLE TestTransaction ( value INT )");
+ 
+ 	if (!retcode)
+ 		retcode = Test(1);
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index 25f3dda..b6a9ee4 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.6 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -40,16 +40,16 @@ static HSTMT stmt = SQL_NULL_HSTMT;
+ static int
+ CheckDirtyRead(void)
+ {
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 
+ 	/* transaction 1 try to change a row but not commit */
+-	Command(Statement, "UPDATE test_transaction SET t = 'second' WHERE n = 1");
++	Command("UPDATE test_transaction SET t = 'second' WHERE n = 1");
+ 
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch uncommited row */
+-	ret = CommandWithResult(Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
+-	if (ret == SQL_ERROR) {
++	CHKR(CommandWithResult, (Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1"), "SE");
++	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+ 		EndTransaction(SQL_ROLLBACK);
+@@ -68,17 +68,17 @@ CheckDirtyRead(void)
+ static int
+ CheckNonrepeatableRead(void)
+ {
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 
+ 	/* transaction 2 read a row */
+ 	SWAP_CONN();
+-	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
++	Command("SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
+ 	SQLMoreResults(Statement);
+ 
+ 	/* transaction 1 change a row and commit */
+ 	SWAP_CONN();
+-	ret = CommandWithResult(Statement, "UPDATE test_transaction SET t = 'second' WHERE n = 1");
+-	if (ret == SQL_ERROR) {
++	CHKR(CommandWithResult, (Statement, "UPDATE test_transaction SET t = 'second' WHERE n = 1"), "SE");
++	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+ 		EndTransaction(SQL_ROLLBACK);
+@@ -90,14 +90,14 @@ CheckNonrepeatableRead(void)
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch commited row */
+-	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
++	Command("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
+ 
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+ 	SQLMoreResults(Statement);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+-	Command(Statement, "UPDATE test_transaction SET t = 'initial' WHERE n = 1");
++	Command("UPDATE test_transaction SET t = 'initial' WHERE n = 1");
+ 	EndTransaction(SQL_COMMIT);
+ 	return 1;
+ }
+@@ -105,17 +105,17 @@ CheckNonrepeatableRead(void)
+ static int
+ CheckPhantom(void)
+ {
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 
+ 	/* transaction 2 read a row */
+ 	SWAP_CONN();
+-	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial'");
++	Command("SELECT * FROM test_transaction WHERE t = 'initial'");
+ 	SQLMoreResults(Statement);
+ 
+ 	/* transaction 1 insert a row that match critera */
+ 	SWAP_CONN();
+-	ret = CommandWithResult(Statement, "INSERT INTO test_transaction(n, t) VALUES(2, 'initial')");
+-	if (ret == SQL_ERROR) {
++	CHKR(CommandWithResult, (Statement, "INSERT INTO test_transaction(n, t) VALUES(2, 'initial')"), "SE");
++	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+ 		EndTransaction(SQL_ROLLBACK);
+@@ -127,7 +127,7 @@ CheckPhantom(void)
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch commited row */
+-	Command(Statement, "SELECT * FROM test_transaction WHERE t = 'initial'");
++	Command("SELECT * FROM test_transaction WHERE t = 'initial'");
+ 
+ 	CHKFetch("S");
+ 	CHKFetch("S");
+@@ -135,7 +135,7 @@ CheckPhantom(void)
+ 	SQLMoreResults(Statement);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+-	Command(Statement, "DELETE test_transaction WHERE n = 2");
++	Command("DELETE test_transaction WHERE n = 2");
+ 	EndTransaction(SQL_COMMIT);
+ 	return 1;
+ }
+@@ -190,34 +190,34 @@ Test(int txn, const char *expected)
+ int
+ main(int argc, char *argv[])
+ {
+-	SQLRETURN ret;
++	SQLRETURN RetCode;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+ 	/* Invalid argument value */
+-	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0);
++	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0, "E");
+ 	ReadError();
+-	if (ret != SQL_ERROR || strcmp(odbc_sqlstate, "HY024") != 0) {
++	if (strcmp(odbc_sqlstate, "HY024") != 0) {
+ 		Disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+ 	}
+ 
+ 	/* here we can't use temporary table cause we use two connection */
+-	Command(Statement, "IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
+-	Command(Statement, "CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
++	Command("IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
++	Command("CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
+ 
+ 	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+-	Command(Statement, "INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
++	Command("INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
+ 
+ #ifdef ENABLE_DEVELOPING
+ 	/* test setting with active transaction "Operation invalid at this time" */
+-	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0);
++	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E");
+ 	ReadError();
+-	if (ret != SQL_ERROR || strcmp(odbc_sqlstate, "HY011") != 0) {
++	if (strcmp(odbc_sqlstate, "HY011") != 0) {
+ 		Disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+@@ -226,12 +226,12 @@ main(int argc, char *argv[])
+ 
+ 	EndTransaction(SQL_COMMIT);
+ 
+-	Command(Statement, "SELECT * FROM test_transaction");
++	Command("SELECT * FROM test_transaction");
+ 
+ 	/* test setting with pending data */
+-	ret = SQLSetConnectAttr(Connection, SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0);
++	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E");
+ 	ReadError();
+-	if (ret != SQL_ERROR || strcmp(odbc_sqlstate, "HY011") != 0) {
++	if (strcmp(odbc_sqlstate, "HY011") != 0) {
+ 		Disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+@@ -272,7 +272,7 @@ main(int argc, char *argv[])
+ 
+ 	/* Sybase do not accept DROP TABLE during a transaction */
+ 	AutoCommit(SQL_AUTOCOMMIT_ON);
+-	Command(Statement, "DROP TABLE test_transaction");
++	Command("DROP TABLE test_transaction");
+ 
+ 	Disconnect();
+ 	return 0;
+diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c
+index b15c930..038ac5c 100644
+--- a/src/odbc/unittests/typeinfo.c
++++ b/src/odbc/unittests/typeinfo.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: typeinfo.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: typeinfo.c,v 1.11 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -88,7 +88,7 @@ DoTest(int version3)
+ 	SQLSMALLINT type, is_unsigned;
+ 	SQLINTEGER col_size, min_scale;
+ 	SQLLEN ind1, ind2, ind3, ind4, ind5, ind6;
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 	int date_time_supported = 0;
+ 
+ 	use_odbc_version3 = version3;
+@@ -124,8 +124,8 @@ DoTest(int version3)
+ 	/* numeric type for data */
+ 
+ 	/* test for date/time support */
+-	retcode = CommandWithResult(Statement, "select cast(getdate() as date)");
+-	if (retcode == SQL_SUCCESS)
++	RetCode = CommandWithResult(Statement, "select cast(getdate() as date)");
++	if (RetCode == SQL_SUCCESS)
+ 		date_time_supported = 1;
+ 	SQLCloseCursor(Statement);
+ 
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 328914f..e0e6cc6 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.9 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -68,7 +68,7 @@ TestBinding(int minimun)
+ 	SQLLEN n_len;
+ 
+ 	sprintf(tmp, "DELETE FROM %s", table_name);
+-	Command(Statement, tmp);
++	Command(tmp);
+ 
+ 	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+ 	sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
+@@ -133,14 +133,14 @@ main(int argc, char *argv[])
+ 
+ 	/* create test table */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+-	Command(Statement, tmp);
++	Command(tmp);
+ 	sprintf(tmp, "CREATE TABLE %s (k int, c NCHAR(10), vc NVARCHAR(10))", table_name);
+-	Command(Statement, tmp);
++	Command(tmp);
+ 
+ 	/* insert with INSERT statements */
+ 	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
+ 		sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, (int) n, p[0], p[1]);
+-		Command(Statement, tmp);
++		Command(tmp);
+ 	}
+ 
+ 	/* check rows */
+@@ -155,7 +155,7 @@ main(int argc, char *argv[])
+ 
+ 	/* cleanup */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+-	Command(Statement, tmp);
++	Command(tmp);
+ 
+ 	Disconnect();
+ 	printf("Done.\n");
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index 7e18402..4304fe5 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.7 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -63,16 +63,16 @@ main(int argc, char *argv[])
+ 	CHKAllocStmt(&Statement, "S");
+ 
+ 	/* create test table */
+-	Command(Statement, "CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
++	Command("CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
+ 
+ 	/* insert with INSERT statements */
+ 	for (n = 0, p = strings_hex; p[n]; ++n) {
+ 		sprintf(tmp, "INSERT INTO #tmpHebrew VALUES(%d, CAST(%s AS NVARCHAR(10)))", n+1, p[n]);
+-		Command(Statement, tmp);
++		Command(tmp);
+ 	}
+ 
+ 	/* test conversions in libTDS */
+-	Command(Statement, "SELECT v FROM #tmpHebrew");
++	Command("SELECT v FROM #tmpHebrew");
+ 
+ 	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+ 	CHKBindCol(1, SQL_C_CHAR, out, sizeof(out), &n_len, "S");
+diff --git a/src/odbc/unittests/warning.c b/src/odbc/unittests/warning.c
+index b1fd195..8a0d866 100644
+--- a/src/odbc/unittests/warning.c
++++ b/src/odbc/unittests/warning.c
+@@ -14,7 +14,7 @@
+  * inside recordset
+  * Sybase do not return warning but test works the same
+  */
+-static char software_version[] = "$Id: warning.c,v 1.7 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: warning.c,v 1.8 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char one_null_with_warning[] = "select max(a) as foo from (select convert(int, null) as a) as test";
+@@ -61,8 +61,8 @@ main(void)
+ {
+ 	Connect();
+ 
+-	Command(Statement, "CREATE TABLE #warning(name varchar(20), value int null)");
+-	Command(Statement, "INSERT INTO #warning VALUES('a', NULL)");
++	Command("CREATE TABLE #warning(name varchar(20), value int null)");
++	Command("INSERT INTO #warning VALUES('a', NULL)");
+ 
+ 	Test(one_null_with_warning);
+ 	Test("SELECT SUM(value) FROM #warning");
+diff --git a/src/odbc/unittests/wchar.c b/src/odbc/unittests/wchar.c
+index d3698e7..a4f5eef 100644
+--- a/src/odbc/unittests/wchar.c
++++ b/src/odbc/unittests/wchar.c
+@@ -2,7 +2,7 @@
+ 
+ /* test SQL_C_DEFAULT with NCHAR type */
+ 
+-static char software_version[] = "$Id: wchar.c,v 1.2 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: wchar.c,v 1.3 2008/11/04 14:46:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -16,7 +16,7 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	CHKBindCol(1, SQL_C_DEFAULT, buf, 100, &ind, "S");
+-	Command(Statement, "SELECT CONVERT(NCHAR(10), 'Pippo 123')");
++	Command("SELECT CONVERT(NCHAR(10), 'Pippo 123')");
+ 
+ 	/* get data */
+ 	memset(buf, 0, sizeof(buf));
+
+commit 6797d560d94c615923f43bcb2f8f0d4255944eed
+Author: freddy77 <freddy77>
+Date:   Tue Nov 4 15:24:49 2008 +0000
+
+    fix SQLGetData with cursors
+
+diff --git a/ChangeLog b/ChangeLog
+index 091ffe0..bda5fab 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Nov 04 16:24:24 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/cursor3.c:
++	- fix SQLGetData with cursors
++
+ Tue Nov 04 15:43:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
+ 	* src/odbc/unittests/attributes.c src/odbc/unittests/binary_test.c:
+@@ -880,4 +884,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2648 2008/11/04 14:46:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2649 2008/11/04 15:24:49 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 62a1a75..06b19dc 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.503 2008/10/27 14:23:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.504 2008/11/04 15:24:49 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4648,6 +4648,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ {
+ 	/* TODO cursors fetch row if needed ?? */
+ 	TDSCOLUMN *colinfo;
++	TDSRESULTINFO *resinfo;
+ 	TDSSOCKET *tds;
+ 	TDS_CHAR *src;
+ 	int srclen;
+@@ -4682,15 +4683,18 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	tds = stmt->dbc->tds_socket;
+ 	context = stmt->dbc->env->tds_ctx;
+ 
+-	if (!tds->current_results) {
++	resinfo = tds->current_results;
++	if (stmt->cursor && stmt->cursor->res_info)
++		resinfo = stmt->cursor->res_info;
++	if (!resinfo) {
+ 		odbc_errs_add(&stmt->errs, "HY010", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+-	if (icol <= 0 || icol > tds->current_results->num_cols) {
++	if (icol <= 0 || icol > resinfo->num_cols) {
+ 		odbc_errs_add(&stmt->errs, "07009", "Column out of range");
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+-	colinfo = tds->current_results->columns[icol - 1];
++	colinfo = resinfo->columns[icol - 1];
+ 
+ 	if (colinfo->column_cur_size < 0) {
+ 		/* TODO check what should happen if pcbValue was NULL */
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index b0d621b..f55ae7d 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,7 +1,7 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.9 2008/11/04 15:24:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -48,10 +48,10 @@ main(int argc, char **argv)
+ 	CHKSetCursorName((SQLCHAR *) "c2", SQL_NTS, "S");
+ 
+ 	Statement = stmt1;
+-	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1", SQL_NTS, "S");
++	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1 ORDER BY k", SQL_NTS, "S");
+ 
+ 	Statement = stmt2;
+-	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1", SQL_NTS, "S");
++	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1 ORDER BY k DESC", SQL_NTS, "S");
+ 
+ 	Statement = stmt1;
+ 	CHKExecute("S");
+@@ -71,6 +71,24 @@ main(int argc, char **argv)
+ 	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+ 	printf(">> Fetch from 2: [%s]\n", buff);
+ 
++	/*
++	 * this should check a problem with SQLGetData 
++	 * fetch a data on stmt2 than fetch on stmt1 and try to get data on first one
++	 */
++	CHKFetch("S");	/* "ccccccccc" */
++	Statement = stmt1;
++	CHKFetch("S");  /* "bbbbb" */
++	Statement = stmt2;
++	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
++	printf(">> Fetch from 2: [%s]\n", buff);
++	if (strcmp(buff, "ccccccccc") != 0)
++		ODBC_REPORT_ERROR("Invalid results from SQLGetData");
++	Statement = stmt1;
++	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
++	printf(">> Fetch from 1: [%s]\n", buff);
++	if (strcmp(buff, "bbbbb") != 0)
++		ODBC_REPORT_ERROR("Invalid results from SQLGetData");
++
+ 	Statement = stmt1;
+ 	CHKCloseCursor("SI");
+ 	Statement = stmt2;
+
+commit 123b4f5598c5dfabf3038154170f6b9012b1e1d1
+Author: freddy77 <freddy77>
+Date:   Wed Nov 5 14:27:49 2008 +0000
+
+    fix problem for too dynamics reported
+
+diff --git a/ChangeLog b/ChangeLog
+index bda5fab..317bb9f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Nov 05 15:26:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/toodynamic.c(added) include/tds.h:
++	* src/tds/mem.c src/tds/query.c src/tds/unittests/Makefile.am:
++	- fix problem for too dynamics reported by Man Min Yan
++
+ Tue Nov 04 16:24:24 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/cursor3.c:
+ 	- fix SQLGetData with cursors
+@@ -884,4 +889,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2649 2008/11/04 15:24:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2650 2008/11/05 14:27:49 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 8e3b812..9f33cb4 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.296 2008/10/17 09:38:10 freddy77 Exp $ */
++/* $Id: tds.h,v 1.297 2008/11/05 14:27:49 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1463,7 +1463,6 @@ int tds_submit_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn);
+ int tds_send_cancel(TDSSOCKET * tds);
+ const char *tds_next_placeholder(const char *start);
+ int tds_count_placeholders(const char *query);
+-int tds_get_dynid(TDSSOCKET * tds, char **id);
+ int tds_submit_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn);
+ int tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params);
+ int tds_submit_optioncmd(TDSSOCKET * tds, TDS_OPTION_CMD command, TDS_OPTION option, TDS_OPTION_ARG *param, TDS_INT param_size);
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 2059a66..6680130 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.180 2008/10/17 09:38:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.181 2008/11/05 14:27:49 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -81,6 +81,42 @@ static void tds_free_compute_result(TDSCOMPUTEINFO * comp_info);
+  * @{
+  */
+ 
++static volatile int inc_num = 1;
++
++/**
++ * Get an id for dynamic query based on TDS information
++ * \param tds state information for the socket and the TDS protocol
++ * \return TDS_FAIL or TDS_SUCCEED
++ */
++static char *
++tds_get_dynid(TDSSOCKET * tds, char *id)
++{
++	unsigned long n;
++	int i;
++	char *p;
++	char c;
++
++	CHECK_TDS_EXTRA(tds);
++
++	inc_num = (inc_num + 1) & 0xffff;
++	/* some version of Sybase require length <= 10, so we code id */
++	n = (unsigned long) (TDS_INTPTR) tds;
++	p = id;
++	*p++ = (char) ('a' + (n % 26u));
++	n /= 26u;
++	for (i = 0; i < 9; ++i) {
++		c = (char) ('0' + (n % 36u));
++		*p++ = (c < ('0' + 10)) ? c : c + ('a' - '0' - 10);
++		/* printf("%d -> %d(%c)\n",n%36u,p[-1],p[-1]); */
++		n /= 36u;
++		if (i == 4)
++			n += 3u * inc_num;
++	}
++	*p++ = 0;
++	return id;
++}
++
++
+ /**
+  * \fn TDSDYNAMIC *tds_alloc_dynamic(TDSSOCKET *tds, const char *id)
+  * \brief Allocate a dynamic statement.
+@@ -94,13 +130,23 @@ TDSDYNAMIC *
+ tds_alloc_dynamic(TDSSOCKET * tds, const char *id)
+ {
+ 	TDSDYNAMIC *dyn, *curr;
++	char tmp_id[30];
+ 
+-	/* check to see if id already exists (shouldn't) */
+-	for (curr = tds->dyns; curr != NULL; curr = curr->next)
+-		if (!strcmp(curr->id, id)) {
+-			/* id already exists! just return it */
+-			return curr;
++	if (id) {
++		/* check to see if id already exists (shouldn't) */
++		if (tds_lookup_dynamic(tds, id))
++			return NULL;
++	} else {
++		unsigned int n;
++		id = tmp_id;
++
++		for (n = 0;;) {
++			if (!tds_lookup_dynamic(tds, tds_get_dynid(tds, tmp_id)))
++				break;
++			if (++n == 256)
++				return NULL;
+ 		}
++	}
+ 
+ 	dyn = (TDSDYNAMIC *) calloc(1, sizeof(TDSDYNAMIC));
+ 	if (!dyn)
+diff --git a/src/tds/query.c b/src/tds/query.c
+index b62fe5c..059aa75 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.227 2008/09/08 19:22:44 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.228 2008/11/05 14:27:49 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
+@@ -1012,16 +1012,7 @@ tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMI
+ 		return TDS_FAIL;
+ 
+ 	/* allocate a structure for this thing */
+-	if (!id) {
+-		char *tmp_id = NULL;
+-
+-		if (tds_get_dynid(tds, &tmp_id) == TDS_FAIL)
+-			return TDS_FAIL;
+-		dyn = tds_alloc_dynamic(tds, tmp_id);
+-		free(tmp_id);
+-	} else {
+-		dyn = tds_alloc_dynamic(tds, id);
+-	}
++	dyn = tds_alloc_dynamic(tds, id);
+ 	if (!dyn)
+ 		return TDS_FAIL;
+ 	
+@@ -1146,7 +1137,6 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ {
+ 	int query_len;
+ 	TDSCOLUMN *param;
+-	char *tmp_id = NULL;
+ 	TDSDYNAMIC *dyn;
+ 	int id_len;
+ 
+@@ -1210,10 +1200,7 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ 	}
+ 
+ 	/* allocate a structure for this thing */
+-	if (tds_get_dynid(tds, &tmp_id) == TDS_FAIL)
+-		return TDS_FAIL;
+-	dyn = tds_alloc_dynamic(tds, tmp_id);
+-	free(tmp_id);
++	dyn = tds_alloc_dynamic(tds, NULL);
+ 
+ 	if (!dyn)
+ 		return TDS_FAIL;
+@@ -1763,43 +1750,6 @@ tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags)
+ 	}
+ }
+ 
+-static volatile int inc_num = 1;
+-
+-/**
+- * Get an id for dynamic query based on TDS information
+- * \param tds state information for the socket and the TDS protocol
+- * \return TDS_FAIL or TDS_SUCCEED
+- */
+-int
+-tds_get_dynid(TDSSOCKET * tds, char **id)
+-{
+-	unsigned long n;
+-	int i;
+-	char *p;
+-	char c;
+-
+-	CHECK_TDS_EXTRA(tds);
+-
+-	inc_num = (inc_num + 1) & 0xffff;
+-	/* some version of Sybase require length <= 10, so we code id */
+-	n = (unsigned long) (TDS_INTPTR) tds;
+-	if (!(p = (char *) malloc(16)))
+-		return TDS_FAIL;
+-	*id = p;
+-	*p++ = (char) ('a' + (n % 26u));
+-	n /= 26u;
+-	for (i = 0; i < 9; ++i) {
+-		c = (char) ('0' + (n % 36u));
+-		*p++ = (c < ('0' + 10)) ? c : c + ('a' - '0' - 10);
+-		/* printf("%d -> %d(%c)\n",n%36u,p[-1],p[-1]); */
+-		n /= 36u;
+-		if (i == 4)
+-			n += 3u * inc_num;
+-	}
+-	*p++ = 0;
+-	return TDS_SUCCEED;
+-}
+-
+ /**
+  * Send a unprepare request for a prepared query
+  * \param tds state information for the socket and the TDS protocol
+diff --git a/src/tds/unittests/.cvsignore b/src/tds/unittests/.cvsignore
+index eb6aa08..6c1a32c 100644
+--- a/src/tds/unittests/.cvsignore
++++ b/src/tds/unittests/.cvsignore
+@@ -20,3 +20,4 @@ utf8_2
+ utf8_3
+ numeric
+ iconv_fread
++toodynamic
+diff --git a/src/tds/unittests/Makefile.am b/src/tds/unittests/Makefile.am
+index f2afb7b..3dd84b8 100644
+--- a/src/tds/unittests/Makefile.am
++++ b/src/tds/unittests/Makefile.am
+@@ -1,10 +1,10 @@
+-# $Id: Makefile.am,v 1.23 2007/08/16 08:10:11 freddy77 Exp $
++# $Id: Makefile.am,v 1.24 2008/11/05 14:27:49 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) dynamic1$(EXEEXT)\
+ 			convert$(EXEEXT) dataread$(EXEEXT) utf8_1$(EXEEXT)\
+ 			utf8_2$(EXEEXT) utf8_3$(EXEEXT) numeric$(EXEEXT) \
+-			iconv_fread$(EXEEXT)
++			iconv_fread$(EXEEXT) toodynamic$(EXEEXT)
+ 
+ # flags test commented, not necessary for 0.62
+ # TODO add flags test again when needed
+@@ -28,6 +28,7 @@ utf8_2_SOURCES	=	utf8_2.c common.c common.h
+ utf8_3_SOURCES	=	utf8_3.c common.c common.h
+ numeric_SOURCES =       numeric.c
+ iconv_fread_SOURCES	= iconv_fread.c
++toodynamic_SOURCES	= toodynamic.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include -I$(srcdir)/.. -I../
+ if MINGW32
+diff --git a/src/tds/unittests/toodynamic.c b/src/tds/unittests/toodynamic.c
+new file mode 100644
+index 0000000..aa3b132
+--- /dev/null
++++ b/src/tds/unittests/toodynamic.c
+@@ -0,0 +1,98 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2008 Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++#include "common.h"
++
++/*
++ * Test creating a lot of dynamics. This can cause some problems cause
++ * generated IDs are reused on a base of 2^16
++ */
++
++static char software_version[] = "$Id: toodynamic.c,v 1.1 2008/11/05 14:27:49 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static void
++fatal_error(const char *msg)
++{
++	fprintf(stderr, "%s\n", msg);
++	exit(1);
++}
++
++int
++main(int argc, char **argv)
++{
++	TDSLOGIN *login;
++	TDSSOCKET *tds;
++	int verbose = 0;
++	TDSDYNAMIC *dyn = NULL;
++	int rc;
++	unsigned int n;
++
++	fprintf(stdout, "%s: Test creating a lot of dynamic queries\n", __FILE__);
++	rc = try_tds_login(&login, &tds, __FILE__, verbose);
++	if (rc != TDS_SUCCEED)
++		fatal_error("try_tds_login() failed");
++
++	run_query(tds, "DROP TABLE #test");
++	if (run_query(tds, "CREATE TABLE #test (i INT, c VARCHAR(40))") != TDS_SUCCEED)
++		fatal_error("creating table error");
++
++	if (tds->cur_dyn)
++		fatal_error("already a dynamic query??");
++
++	/* prepare to insert */
++	if (tds_submit_prepare(tds, "UPDATE #test SET c = 'test' WHERE i = ?", NULL, &dyn, NULL) != TDS_SUCCEED)
++		fatal_error("tds_submit_prepare() error");
++	if (tds_process_simple_query(tds) != TDS_SUCCEED)
++		fatal_error("tds_process_simple_query() error");
++	if (!dyn)
++		fatal_error("dynamic not present??");
++
++	/* waste some ids */
++	for (n = 0; n < 65525; ++n) {
++		TDSDYNAMIC *dyn;
++
++		dyn = tds_alloc_dynamic(tds, NULL);
++		if (!dyn)
++			fatal_error("create dynamic");
++
++		tds_free_dynamic(tds, dyn);
++	}
++
++	/* this should not cause duplicate IDs or erros*/
++	for (n = 0; n < 20; ++n) {
++		TDSDYNAMIC *dyn2;
++
++		if (tds_submit_prepare(tds, "INSERT INTO #test(i,c) VALUES(?,?)", NULL, &dyn2, NULL) != TDS_SUCCEED)
++			fatal_error("tds_submit_prepare() error");
++		if (dyn == dyn2)
++			fatal_error("got duplicated dynamic");
++		if (tds_process_simple_query(tds) != TDS_SUCCEED)
++			fatal_error("tds_process_simple_query() error");
++		if (!dyn2)
++			fatal_error("dynamic not present??");
++		if (tds_submit_unprepare(tds, dyn2) != TDS_SUCCEED || tds_process_simple_query(tds) != TDS_SUCCEED)
++			fatal_error("unprepare error");
++		tds_free_dynamic(tds, dyn2);
++	}
++
++
++	try_tds_logout(login, tds, verbose);
++	return 0;
++}
++
+
+commit 6a7d6c46297a8b0609c6a7c0490425202a72a58e
+Author: freddy77 <freddy77>
+Date:   Wed Nov 5 14:54:41 2008 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index 317bb9f..d5d781f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Nov 05 15:54:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/mem.c src/tds/token.c:
++	- remove warning
++
+ Wed Nov 05 15:26:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/unittests/toodynamic.c(added) include/tds.h:
+ 	* src/tds/mem.c src/tds/query.c src/tds/unittests/Makefile.am:
+@@ -889,4 +893,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2650 2008/11/05 14:27:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2651 2008/11/05 14:54:41 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 9f33cb4..3bb6d95 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.297 2008/11/05 14:27:49 freddy77 Exp $ */
++/* $Id: tds.h,v 1.298 2008/11/05 14:54:41 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1394,7 +1394,7 @@ int tds_alloc_row(TDSRESULTINFO * res_info);
+ int tds_alloc_compute_row(TDSCOMPUTEINFO * res_info);
+ BCPCOLDATA * tds_alloc_bcp_column_data(int column_size);
+ unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, int len, unsigned char *crypt_pass);
+-TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, char *id);
++TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, const char *id);
+ /*@observer@*/ const char *tds_prtype(int token);
+ 
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 6680130..6238db3 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.181 2008/11/05 14:27:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.182 2008/11/05 14:54:41 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -129,7 +129,7 @@ tds_get_dynid(TDSSOCKET * tds, char *id)
+ TDSDYNAMIC *
+ tds_alloc_dynamic(TDSSOCKET * tds, const char *id)
+ {
+-	TDSDYNAMIC *dyn, *curr;
++	TDSDYNAMIC *dyn;
+ 	char tmp_id[30];
+ 
+ 	if (id) {
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 1885ca6..33e3f9f 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.356 2008/10/17 09:38:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.357 2008/11/05 14:54:41 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2686,7 +2686,7 @@ tds_process_cancel(TDSSOCKET * tds)
+  * \param id   dynamic id to search
+  */
+ TDSDYNAMIC *
+-tds_lookup_dynamic(TDSSOCKET * tds, char *id)
++tds_lookup_dynamic(TDSSOCKET * tds, const char *id)
+ {
+ 	TDSDYNAMIC *curr;
+ 
+
+commit 9e1ed25052046561225e7a95a7631885b05cfb8e
+Author: freddy77 <freddy77>
+Date:   Wed Nov 5 19:23:32 2008 +0000
+
+    reduce a roundtrip, improve freeclose test
+
+diff --git a/ChangeLog b/ChangeLog
+index d5d781f..2bb740b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Nov 05 20:21:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/freeclose.c:
++	- reduce one round-trip with server
++	- improve freeclose test to detect complete rebindings
++	- use always cursor results if cursor used
++
+ Wed Nov 05 15:54:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/mem.c src/tds/token.c:
+ 	- remove warning
+@@ -893,4 +899,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2651 2008/11/05 14:54:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2652 2008/11/05 19:23:32 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 06b19dc..2ba97b9 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.504 2008/11/04 15:24:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.505 2008/11/05 19:23:32 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4248,6 +4248,7 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 		TDSPARAMINFO *params = NULL;
+ 		TDSSOCKET *tds = stmt->dbc->tds_socket;
+ 
++		stmt->need_reprepare = 0;
+ 		/*
+ 		 * using TDS7+ we need parameters to prepare a query so try
+ 		 * to get them 
+@@ -4683,9 +4684,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	tds = stmt->dbc->tds_socket;
+ 	context = stmt->dbc->env->tds_ctx;
+ 
+-	resinfo = tds->current_results;
+-	if (stmt->cursor && stmt->cursor->res_info)
+-		resinfo = stmt->cursor->res_info;
++	resinfo = stmt->cursor ? stmt->cursor->res_info : tds->current_results;
+ 	if (!resinfo) {
+ 		odbc_errs_add(&stmt->errs, "HY010", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 3e8422e..3f56323 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -50,7 +50,7 @@
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.9 2008/11/05 19:23:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+@@ -327,24 +327,57 @@ main(int argc, char **argv)
+ 	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+ 
+ 	CHKPrepare((SQLCHAR *) query, SQL_NTS, "SI");
++	printf("%u round trips %u inserts\n", round_trips, inserts);
++
+ 	for (id = 0; id < num_inserts; id++) {
+ 		sprintf(string, "This is a test (%d)", (int) id);
+ 		CHKExecute("SI");
+ 		CHKFreeStmt(SQL_CLOSE, "S");
+ 	}
+ 
++	printf("%u round trips %u inserts\n", round_trips, inserts);
+ 	ResetStatement();
+ 
+-	Disconnect();
++	if (inserts > 1 || round_trips > num_inserts * 2 + 6) {
++		fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts);
++		return 1;
++	}
++	printf("%u round trips %u inserts\n", round_trips, inserts);
+ 
+-	alarm(10);
+-	pthread_join(fake_thread, NULL);
++#ifdef ENABLE_DEVELOPING
++	/* check for SQL_RESET_PARAMS */
++	round_trips = 0;
++	inserts = 0;
++
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
++	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+ 
+-	if (inserts > 2 || round_trips > num_inserts * 2 + 10) {
++	CHKPrepare((SQLCHAR *) query, SQL_NTS, "SI");
++	printf("%u round trips %u inserts\n", round_trips, inserts);
++
++	for (id = 0; id < num_inserts; id++) {
++		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
++		CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
++
++		sprintf(string, "This is a test (%d)", (int) id);
++		CHKExecute("SI");
++		CHKFreeStmt(SQL_RESET_PARAMS, "S");
++	}
++
++	printf("%u round trips %u inserts\n", round_trips, inserts);
++	ResetStatement();
++
++	if (inserts > 1 || round_trips > num_inserts * 2 + 6) {
+ 		fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts);
+ 		return 1;
+ 	}
+ 	printf("%u round trips %u inserts\n", round_trips, inserts);
++#endif
++
++	Disconnect();
++
++	alarm(10);
++	pthread_join(fake_thread, NULL);
+ 
+ 	return 0;
+ }
+
+commit 26b125102e1e74cd952f7c1b70a19547bd63bbf4
+Author: freddy77 <freddy77>
+Date:   Thu Nov 6 14:39:57 2008 +0000
+
+    make it compile under VC6
+
+diff --git a/ChangeLog b/ChangeLog
+index 2bb740b..7d9fc52 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Nov 06 15:39:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/challenge.c: make it compile under VC6
++
+ Wed Nov 05 20:21:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/freeclose.c:
+ 	- reduce one round-trip with server
+@@ -899,4 +902,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2652 2008/11/05 19:23:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2653 2008/11/06 14:39:57 freddy77 Exp $
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index f9be822..2504f96 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.35 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.36 2008/11/06 14:39:57 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -554,12 +554,12 @@ static const unsigned char ntlm_id[] = "NTLMSSP";
+ static void
+ unix_to_nt_time(TDS_UINT8 * nt, time_t t)
+ {
+-#define TIME_FIXUP_CONSTANT 11644473600LLU
++#define TIME_FIXUP_CONSTANT (((TDS_UINT8) 134774U) * 86400U)
+ 
+ 	TDS_UINT8 t2;
+ 
+ 	if (t == (time_t) - 1) {
+-		*nt = (TDS_UINT8) - 1LL;
++		*nt = (TDS_UINT8) - ((TDS_INT8) 1);
+ 		return;
+ 	}
+ 	if (t == 0) {
+
+commit dd13dc280943a86221c31ef05d925c722c184486
+Author: freddy77 <freddy77>
+Date:   Thu Nov 6 15:56:38 2008 +0000
+
+    more odbc test updates
+
+diff --git a/ChangeLog b/ChangeLog
+index 7d9fc52..b3d9c62 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,13 @@
++Thu Nov 06 16:55:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c src/odbc/unittests/common.c:
++	* src/odbc/unittests/common.h src/odbc/unittests/connect.c:
++	* src/odbc/unittests/connect2.c src/odbc/unittests/error.c:
++	* src/odbc/unittests/test64.c src/odbc/unittests/timeout.c:
++	* src/odbc/unittests/timeout3.c src/odbc/unittests/utf8.c:
++	* src/odbc/unittests/utf8_2.c:
++	- remove CHK and CheckReturn
++	- style update
++
+ Thu Nov 06 15:39:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c: make it compile under VC6
+ 
+@@ -902,4 +912,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2653 2008/11/06 14:39:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2654 2008/11/06 15:56:38 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 66b64ea..8c0ca59 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.11 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.12 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -241,7 +241,7 @@ main(int argc, char **argv)
+ 
+ 	for (i = 0; i < cnt; i++) {
+ 
+-		CHK(SQLAllocHandle, (SQL_HANDLE_STMT, Connection, &Statement));
++		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
+ 
+ 		if (db_is_microsoft()) {
+ 			CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 3c18426..7bd452d 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.50 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.51 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -168,30 +168,44 @@ ReportError(const char *errmsg, int line, const char *file)
+ 	exit(1);
+ }
+ 
+-void
+-CheckReturn(void)
++static void
++ReportODBCError(const char *errmsg, SQLSMALLINT handletype, SQLHANDLE handle, SQLRETURN rc, int line, const char *file)
+ {
+-	ReportError("", 0, "");
++	SQLRETURN ret;
++	unsigned char sqlstate[6];
++	unsigned char msg[256];
++
++
++	if (errmsg[0]) {
++		if (line)
++			fprintf(stderr, "%s:%d %s\n", file, line, errmsg);
++		else
++			fprintf(stderr, "%s\n", errmsg);
++	}
++	ret = SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
++	if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
++		fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
++	Disconnect();
++	exit(1);
+ }
+ 
+ int
+ Connect(void)
+ {
+ 
+-	int res;
+-
++	SQLRETURN RetCode;
+ 
+ 	char command[512];
+ 
+ 	if (read_login_info())
+ 		exit(1);
+ 
+-	CHK(SQLAllocEnv, (&Environment));
++	CHKAllocEnv(&Environment, "S");
+ 
+ 	if (use_odbc_version3)
+ 		SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+ 
+-	CHK(SQLAllocConnect, (Environment, &Connection));
++	CHKAllocConnect(&Connection, "S");
+ 	printf("odbctest\n--------\n\n");
+ 	printf("connection parameters:\nserver:   '%s'\nuser:     '%s'\npassword: '%s'\ndatabase: '%s'\n",
+ 	       SERVER, USER, "????" /* PASSWORD */ , DATABASE);
+@@ -199,11 +213,7 @@ Connect(void)
+ 	if (odbc_set_conn_attr)
+ 		(*odbc_set_conn_attr)();
+ 
+-	res = SQLConnect(Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS);
+-	if (!SQL_SUCCEEDED(res)) {
+-		printf("Unable to open data source (ret=%d)\n", res);
+-		CheckReturn();
+-	}
++	CHKR(SQLConnect, (Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS), "SI");
+ 
+ 	CHKAllocStmt(&Statement, "S");
+ 
+@@ -290,7 +300,7 @@ const char *db_version(void)
+ 	SQLSMALLINT version_len;
+ 
+ 	if (!db_str_version[0])
+-		CHK(SQLGetInfo, (Connection, SQL_DBMS_VER, db_str_version, sizeof(db_str_version), &version_len));
++		CHKR(SQLGetInfo, (Connection, SQL_DBMS_VER, db_str_version, sizeof(db_str_version), &version_len), "S");
+ 
+ 	return db_str_version;
+ }
+@@ -345,11 +355,11 @@ CheckRows(int n, int line, const char * file)
+ }
+ 
+ void
+-ResetStatement(void)
++ResetStatementProc(SQLHSTMT *stmt, const char *file, int line)
+ {
+-	SQLFreeStmt(Statement, SQL_DROP);
+-	Statement = SQL_NULL_HSTMT;
+-	CHKAllocStmt(&Statement, "S");
++	SQLFreeStmt(*stmt, SQL_DROP);
++	*stmt = SQL_NULL_HSTMT;
++	CheckRes(file, line, SQLAllocStmt(Connection, stmt), SQL_HANDLE_DBC, Connection, "SQLAllocStmt", "S");
+ }
+ 
+ void
+@@ -369,7 +379,7 @@ CheckCursor(void)
+ 			Disconnect();
+ 			exit(0);
+ 		}
+-		ODBC_REPORT_ERROR("SQLSetStmtAttr");
++		ReportODBCError("SQLSetStmtAttr", SQL_HANDLE_STMT, Statement, retcode, __LINE__, __FILE__);
+ 	}
+ 	ResetStatement();
+ }
+@@ -399,12 +409,14 @@ CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLH
+ 			if (rc == SQL_NEED_DATA)
+ 				return rc;
+ 			p += 2;
++		} else if (!*p) {
++			break;
+ 		} else {
+ 			ReportError("Wrong results specified", line, file);
+ 			return rc;
+ 		}
+ 	}
+-	ReportError(func, line, file);
++	ReportODBCError(func, handle_type, handle, rc, line, file);
+ 	return rc;
+ }
+ 
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index dc2ba24..a698ab6 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.26 2008/11/04 14:46:17 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.27 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -47,23 +47,18 @@ extern char DATABASE[512];
+ extern char DRIVER[1024];
+ 
+ int read_login_info(void);
+-void CheckReturn(void);
+ void ReportError(const char *msg, int line, const char *file);
+ 
+ void CheckCols(int n, int line, const char * file);
+ void CheckRows(int n, int line, const char * file);
+ #define CHECK_ROWS(n) CheckRows(n, __LINE__, __FILE__)
+ #define CHECK_COLS(n) CheckCols(n, __LINE__, __FILE__)
+-void ResetStatement(void);
++void ResetStatementProc(SQLHSTMT *stmt, const char *file, int line);
++#define ResetStatement() ResetStatementProc(&Statement, __FILE__, __LINE__)
+ void CheckCursor(void);
+ 
+ #define ODBC_REPORT_ERROR(msg) ReportError(msg, __LINE__, __FILE__)
+ 
+-#define CHK(func,params) \
+-	do { if ((RetCode=(func params)) != SQL_SUCCESS) \
+-		ODBC_REPORT_ERROR(#func); \
+-	} while(0)
+-
+ SQLRETURN CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res);
+ #define CHKR(func, params, res) \
+ 	CheckRes(__FILE__, __LINE__, (RetCode=(func params)), 0, 0, #func, res)
+@@ -72,6 +67,10 @@ SQLRETURN CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_
+ 
+ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 
++#define CHKAllocConnect(a,res) \
++	CHKR2(SQLAllocConnect, (Environment,a), SQL_HANDLE_ENV, Environment, res)
++#define CHKAllocEnv(a,res) \
++	CHKR2(SQLAllocEnv, (a), 0, 0, res)
+ #define CHKAllocStmt(a,res) \
+ 	CHKR2(SQLAllocStmt, (Connection,a), SQL_HANDLE_DBC, Connection, res)
+ #define CHKAllocHandle(a,b,c,res) \
+@@ -88,6 +87,8 @@ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 	CHKR2(SQLColAttribute, (Statement,a,b,c,d,e,f), SQL_HANDLE_STMT, Statement, res)
+ #define CHKDescribeCol(a,b,c,d,e,f,g,h,res) \
+ 	CHKR2(SQLDescribeCol, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++#define CHKDriverConnect(a,b,c,d,e,f,g,res) \
++	CHKR2(SQLDriverConnect, (Connection,a,b,c,d,e,f,g), SQL_HANDLE_DBC, Connection, res)
+ #define CHKEndTran(a,b,c,res) \
+ 	CHKR2(SQLEndTran, (a,b,c), a, b, res)
+ #define CHKExecDirect(a,b,res) \
+diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c
+index 1d1537d..f634bae 100644
+--- a/src/odbc/unittests/connect.c
++++ b/src/odbc/unittests/connect.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: connect.c,v 1.10 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: connect.c,v 1.11 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,8 +9,8 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKR(SQLAllocEnv, (&Environment), "S");
+-	CHKR(SQLAllocConnect, (Environment, &Connection), "S");
++	CHKAllocEnv(&Environment, "S");
++	CHKAllocConnect(&Connection, "S");
+ }
+ 
+ int
+@@ -58,7 +58,7 @@ main(int argc, char *argv[])
+ 	printf("connect string DSN connect..\n");
+ 	init_connect();
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
++	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+ 	Disconnect();
+ 
+ 	/* try connect string using old SERVERNAME specification */
+@@ -68,7 +68,7 @@ main(int argc, char *argv[])
+ 	/* this is expected to work with unixODBC */
+ 	init_connect();
+ 	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SIE");
++	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+ 	if (RetCode == SQL_ERROR) {
+ 		printf("Unable to open data source (ret=%d)\n", RetCode);
+ 		++failures;
+@@ -78,7 +78,7 @@ main(int argc, char *argv[])
+ 	/* this is expected to work with iODBC */
+ 	init_connect();
+ 	sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", DRIVER, SERVER, USER, PASSWORD, DATABASE);
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SIE");
++	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+ 	if (RetCode == SQL_ERROR) {
+ 		printf("Unable to open data source (ret=%d)\n", RetCode);
+ 		++failures;
+@@ -87,7 +87,7 @@ main(int argc, char *argv[])
+ 
+ 	/* at least one should success.. */
+ 	if (failures > 1) {
+-		CheckReturn();
++		ODBC_REPORT_ERROR("Too much failures");
+ 		exit(1);
+ 	}
+ 
+diff --git a/src/odbc/unittests/connect2.c b/src/odbc/unittests/connect2.c
+index 9eacb7b..9d60b28 100644
+--- a/src/odbc/unittests/connect2.c
++++ b/src/odbc/unittests/connect2.c
+@@ -5,7 +5,7 @@
+  * either SQLConnect and SQLDriverConnect
+  */
+ 
+-static char software_version[] = "$Id: connect2.c,v 1.6 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: connect2.c,v 1.7 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -15,8 +15,8 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKR(SQLAllocEnv, (&Environment), "S");
+-	CHKR(SQLAllocConnect, (Environment, &Connection), "S");
++	CHKAllocEnv(&Environment, "S");
++	CHKAllocConnect(&Connection, "S");
+ }
+ 
+ static void
+@@ -31,7 +31,7 @@ driver_connect(const char *conn_str)
+ 	char tmp[1024];
+ 	SQLSMALLINT len;
+ 
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) conn_str, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
++	CHKDriverConnect(NULL, (SQLCHAR *) conn_str, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+ }
+ 
+ static void
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index 153bdd1..ae85137 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.6 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.7 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -18,7 +18,7 @@ ReadError(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	SQLRETURN retcode;
++	SQLRETURN RetCode;
+ 	HSTMT stmt, tmp_stmt;
+ 
+ 	Connect();
+@@ -32,16 +32,15 @@ main(int argc, char *argv[])
+ 	Command("insert into #tmp values(7)");
+ 
+ 	/* issue our command */
+-	retcode = CommandWithResult(Statement, "select 100 / (i - 5) from #tmp order by i");
++	if (db_is_microsoft())
++		CHKR(CommandWithResult, (Statement, "select 100 / (i - 5) from #tmp order by i"), "SE");
++	else
++		CHKR(CommandWithResult, (Statement, "select 100 / (i - 5) from #tmp order by i"), "E");
+ 
+ 	/* special case, Sybase detect error early */
+-	if (retcode != SQL_ERROR || db_is_microsoft()) {
+-
+-		if (retcode != SQL_SUCCESS)
+-			ODBC_REPORT_ERROR("Error in command");
++	if (RetCode != SQL_ERROR) {
+ 
+ 		/* TODO when multiple row fetch available test for error on some columns */
+-
+ 		CHKFetch("S");
+ 		CHKFetch("S");
+ 		CHKFetch("E");
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index 6a99d5e..a7fdcb4 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.7 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.8 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -22,7 +22,7 @@ check_ipd_params(void)
+ 	/* get IPD */
+ 	CHKGetStmtAttr(SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+-	CHK(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
++	CHKR(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind), "S");
+ 
+ 	if (ptr != ptr2) {
+ 		fprintf(stderr, "IPD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
+@@ -45,7 +45,7 @@ set_ipd_params2(SQLULEN *ptr)
+ 	/* get IPD */
+ 	CHKGetStmtAttr(SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+-	CHK(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0));
++	CHKR(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0), "S");
+ }
+ 
+ static void
+@@ -139,7 +139,7 @@ check_ird_params(void)
+ 	/* get IRD */
+ 	CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+-	CHK(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind));
++	CHKR(SQLGetDescField, (desc, 0, SQL_DESC_ROWS_PROCESSED_PTR, &ptr2, sizeof(ptr2), &ind), "S");
+ 
+ 	if (ptr != ptr2) {
+ 		fprintf(stderr, "IRD inconsistency ptr %p ptr2 %p\n", ptr, ptr2);
+@@ -162,7 +162,7 @@ set_ird_params2(SQLULEN *ptr)
+ 	/* get IRD */
+ 	CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+-	CHK(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0));
++	CHKR(SQLSetDescField, (desc, 1, SQL_DESC_ROWS_PROCESSED_PTR, ptr, 0), "S");
+ }
+ 
+ static const rows_set_t row_set[] = {
+diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c
+index 5a820aa..ee3edef 100644
+--- a/src/odbc/unittests/timeout.c
++++ b/src/odbc/unittests/timeout.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test timeout of query */
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.10 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.11 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -24,7 +24,6 @@ main(int argc, char *argv[])
+ 	HENV env;
+ 	HDBC dbc;
+ 	HSTMT stmt;
+-	SQLRETURN ret;
+ 	SQLINTEGER i;
+ 
+ 	Connect();
+@@ -60,9 +59,7 @@ main(int argc, char *argv[])
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+ 	/* TODO should return error S1T00 Timeout expired, test error message */
+-	ret = CommandWithResult(Statement, "update test_timeout set t = 'bad' where n = 1");
+-	if (ret != SQL_ERROR)
+-		ODBC_REPORT_ERROR("SQLExecDirect success ??");
++	CHKR(CommandWithResult, (Statement, "update test_timeout set t = 'bad' where n = 1"), "E");
+ 
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c
+index ae15217..27e81fd 100644
+--- a/src/odbc/unittests/timeout3.c
++++ b/src/odbc/unittests/timeout3.c
+@@ -40,7 +40,7 @@
+ 	test connection timeout
+ */
+ 
+-static char software_version[] = "$Id: timeout3.c,v 1.8 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: timeout3.c,v 1.9 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -48,9 +48,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKR(SQLAllocEnv, (&Environment), "S");
++	CHKAllocEnv(&Environment, "S");
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	CHKR(SQLAllocConnect, (Environment, &Connection), "S");
++	CHKAllocConnect(&Connection, "S");
+ }
+ 
+ static pthread_t      fake_thread;
+@@ -164,7 +164,7 @@ main(int argc, char *argv[])
+ 	printf("try to connect to our port just to check connection timeout\n");
+ 	sprintf(tmp, "DRIVER=FreeTDS;SERVER=127.0.0.1;Port=%d;TDS_Version=7.0;UID=test;PWD=test;DATABASE=tempdb;", port);
+ 	start_time = time(NULL);
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "E");
++	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "E");
+ 	end_time = time(NULL);
+ 
+ 	strcpy(sqlstate, "XXXXX");
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index e0e6cc6..671b37b 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.9 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.10 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,9 +9,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHK(SQLAllocEnv, (&Environment));
++	CHKAllocEnv(&Environment, "S");
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	CHK(SQLAllocConnect, (Environment, &Connection));
++	CHKAllocConnect(&Connection, "S");
+ }
+ 
+ static void
+@@ -116,7 +116,7 @@ main(int argc, char *argv[])
+ 	/* connect string using DSN */
+ 	init_connect();
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
++	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+ 	if (!driver_is_freetds()) {
+ 		Disconnect();
+ 		printf("Driver is not FreeTDS, exiting\n");
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index 4304fe5..2eb9e33 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.7 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.8 2008/11/06 15:56:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,9 +9,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHK(SQLAllocEnv, (&Environment));
++	CHKAllocEnv(&Environment, "S");
+ 	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	CHK(SQLAllocConnect, (Environment, &Connection));
++	CHKAllocConnect(&Connection, "S");
+ }
+ 
+ static const char * const strings[] = {
+@@ -47,7 +47,7 @@ main(int argc, char *argv[])
+ 	/* connect string using DSN */
+ 	init_connect();
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
+-	CHKR(SQLDriverConnect, (Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT), "SI");
++	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+ 	if (!driver_is_freetds()) {
+ 		Disconnect();
+ 		printf("Driver is not FreeTDS, exiting\n");
+
+commit eaa1bfa2fb6b18e135c3a86515c413375e03edd1
+Author: freddy77 <freddy77>
+Date:   Fri Nov 7 16:23:58 2008 +0000
+
+    *** empty log message ***
+
+diff --git a/TODO.freddy b/TODO.freddy
+index e8d8869..1f475c8 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -56,6 +56,8 @@ Is it possible to support direct binding for parameters using different
+ encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
+ possible changing TDSCOLUMN->char_conv. Some work should be done in 
+ src/tds/iconv.c in order to get a valid char_conv changing client encoding.
++Merge putdata and blob1 tests, tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases).
++Check blob1 dialog, seems to prepare twice during insert.
+ 
+ Other
+ -----
+@@ -71,6 +73,16 @@ Possibility to lock TDSSOCKET (see odbc, multiple RPCs)
+ 
+ Support Unicode under ODBC, use iso8859-1 by default and large characters
+ 
++If application rebind with compatible types do not prepare twice.
++Compatible (tds_match_dynamic ??) if:
++- same query
++- same # of parameters
++- for every param
++  - same server type
++    (tds_get_conversion_type(curcol->on_server.column_type, curcol->on_server.column_size))
++  - same len (tds_fix_column_size(tds, curcol)) or len < previous
++    (for decimal/precision check curcol->column_prec and curcol->column_scale)
++
+ 
+ Tests
+ -----
+
+commit 4c8fa328a6fc63960e1d0b5f1db8d4ec4d00dcbb
+Author: freddy77 <freddy77>
+Date:   Fri Nov 7 16:25:52 2008 +0000
+
+    commented unused field
+
+diff --git a/ChangeLog b/ChangeLog
+index b3d9c62..ed1b4b8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Nov 07 17:24:12 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: commented unused field
++
+ Thu Nov 06 16:55:25 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c src/odbc/unittests/common.c:
+ 	* src/odbc/unittests/common.h src/odbc/unittests/connect.c:
+@@ -912,4 +915,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2654 2008/11/06 15:56:38 freddy77 Exp $
++$Id: ChangeLog,v 1.2655 2008/11/07 16:25:52 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 3bb6d95..ab897b6 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.298 2008/11/05 14:54:41 freddy77 Exp $ */
++/* $Id: tds.h,v 1.299 2008/11/07 16:25:52 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1211,7 +1211,7 @@ typedef struct tds_dynamic
+ 	 * is generated automatically by libTDS
+ 	 */
+ 	char id[30];
+-	int dyn_state;
++	/* int dyn_state; */ /* TODO use it */
+ 	/** numeric id for mssql7+*/
+ 	TDS_INT num_id;
+ 	TDSPARAMINFO *res_info;	/**< query results */
+
+commit 57be8ba9eb37637520f27c884551b3683bb6df50
+Author: freddy77 <freddy77>
+Date:   Mon Nov 10 17:20:39 2008 +0000
+
+    check proper return code
+
+diff --git a/ChangeLog b/ChangeLog
+index ed1b4b8..6d3331d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Nov 10 18:20:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: check proper return code
++
+ Fri Nov 07 17:24:12 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h: commented unused field
+ 
+@@ -915,4 +918,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2655 2008/11/07 16:25:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2656 2008/11/10 17:20:39 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 8c0ca59..5e1240e 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.12 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.13 2008/11/10 17:20:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -215,6 +215,8 @@ main(int argc, char **argv)
+ 			CHKParamData((SQLPOINTER) & p, "SINe");
+ 			printf(">> SQLParamData: ptr = %p  RetCode = %d\n", (void *) p, RetCode);
+ 			if (RetCode == SQL_NEED_DATA) {
++				SQLRETURN RetCode;
++
+ 				if (p == buf3) {
+ 					fill_hex(buf3, NBYTES, 987, 25);
+ 					
+
+commit d6b4c459a96822298d0876635d3f5c24951f6081
+Author: freddy77 <freddy77>
+Date:   Tue Nov 11 08:34:07 2008 +0000
+
+    fix test for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 6d3331d..b94712d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Nov 11 09:33:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/transaction2.c: fix test for Sybase
++
+ Mon Nov 10 18:20:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: check proper return code
+ 
+@@ -918,4 +921,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2656 2008/11/10 17:20:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2657 2008/11/11 08:34:07 freddy77 Exp $
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index b6a9ee4..e812296 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.6 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.7 2008/11/11 08:34:09 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -144,6 +144,8 @@ static int test_with_connect = 0;
+ 
+ static int global_txn;
+ 
++static int hide_error;
++
+ static void
+ my_attrs(void)
+ {
+@@ -160,7 +162,7 @@ ConnectWithTxn(int txn)
+ 	odbc_set_conn_attr = NULL;
+ }
+ 
+-static void
++static int
+ Test(int txn, const char *expected)
+ {
+ 	int dirty, repeatable, phantom;
+@@ -182,9 +184,15 @@ Test(int txn, const char *expected)
+ 
+ 	sprintf(buf, "dirty %d non repeatable %d phantom %d", dirty, repeatable, phantom);
+ 	if (strcmp(buf, expected) != 0) {
++		if (hide_error) {
++			hide_error = 0;
++			return 0;
++		}
+ 		fprintf(stderr, "detected wrong TXN\nexpected '%s' got '%s'\n", expected, buf);
+ 		exit(1);
+ 	}
++	hide_error = 0;
++	return 1;
+ }
+ 
+ int
+@@ -252,17 +260,18 @@ main(int argc, char *argv[])
+ 
+ 	SWAP_CONN();
+ 
+-	Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
+-	Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
+-	Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
+-	Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
+-
+-	test_with_connect = 1;
+-
+-	Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
+-	Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
+-	Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
+-	Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
++	for (test_with_connect = 0; test_with_connect <= 1; ++test_with_connect) {
++		Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
++		Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
++		if (db_is_microsoft()) {
++			Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
++		} else {
++			hide_error = 1;
++			if (!Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1"))
++				Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 0");
++		}
++		Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
++	}
+ 
+ 	Disconnect();
+ 
+
+commit f5c0dda9552943d3a2baeaf7264c4818ca15da6d
+Author: freddy77 <freddy77>
+Date:   Tue Nov 11 08:40:17 2008 +0000
+
+    fix test for newer Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index b94712d..6ac17f8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Nov 11 09:39:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/error.c: fix test for newer Sybase
++
+ Tue Nov 11 09:33:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/transaction2.c: fix test for Sybase
+ 
+@@ -921,4 +924,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2657 2008/11/11 08:34:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2658 2008/11/11 08:40:17 freddy77 Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 7bd452d..897903b 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.51 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.52 2008/11/11 08:40:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -178,9 +178,9 @@ ReportODBCError(const char *errmsg, SQLSMALLINT handletype, SQLHANDLE handle, SQ
+ 
+ 	if (errmsg[0]) {
+ 		if (line)
+-			fprintf(stderr, "%s:%d %s\n", file, line, errmsg);
++			fprintf(stderr, "%s:%d rc=%d %s\n", file, line, (int) rc, errmsg);
+ 		else
+-			fprintf(stderr, "%s\n", errmsg);
++			fprintf(stderr, "rc=%d %s\n", (int) rc, errmsg);
+ 	}
+ 	ret = SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+ 	if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index ae85137..d962444 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.7 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.8 2008/11/11 08:40:17 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -32,12 +32,9 @@ main(int argc, char *argv[])
+ 	Command("insert into #tmp values(7)");
+ 
+ 	/* issue our command */
+-	if (db_is_microsoft())
+-		CHKR(CommandWithResult, (Statement, "select 100 / (i - 5) from #tmp order by i"), "SE");
+-	else
+-		CHKR(CommandWithResult, (Statement, "select 100 / (i - 5) from #tmp order by i"), "E");
++	CHKR(CommandWithResult, (Statement, "select 100 / (i - 5) from #tmp order by i"), "SE");
+ 
+-	/* special case, Sybase detect error early */
++	/* special case, early Sybase detect error early */
+ 	if (RetCode != SQL_ERROR) {
+ 
+ 		/* TODO when multiple row fetch available test for error on some columns */
+
+commit b1eae3d9848aa0f035b3e6564294d1b98fcb9c1c
+Author: jklowden <jklowden>
+Date:   Wed Nov 12 00:47:25 2008 +0000
+
+    dbsqlok did not process entire packet Cf. ML today from Ted Hayes
+
+diff --git a/ChangeLog b/ChangeLog
+index 6ac17f8..fac72d5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,14 @@
++Tue Nov 11 19:42:30 EST 2008	JK Lowden <jklowden@freetds.org>
++	* include/dblib.h src/dblib/dblib.c 
++	- dbsqlok did not process entire packet
++	- Cf. ML today from Ted Hayes
++	* src/dblib/unittests/t0005.c cosmetic changes
++	* src/tds/Makefile.am remember to build types.h
++	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am
++	* src/odbc/unittests/Makefile.am 
++	* src/tds/unittests/Makefile.am
++	- set RPATH to prefer build tree
++
+ Tue Nov 11 09:39:05 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/error.c: fix test for newer Sybase
+ 
+@@ -924,4 +935,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2658 2008/11/11 08:40:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2659 2008/11/12 00:47:25 jklowden Exp $
+diff --git a/include/dblib.h b/include/dblib.h
+index d625ded..eb72b99 100644
+--- a/include/dblib.h
++++ b/include/dblib.h
+@@ -32,16 +32,16 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: dblib.h,v 1.43 2007/12/05 03:04:11 jklowden Exp $ */
+-
+-enum {
+-	  _DB_RES_INIT            = 0
+-	, _DB_RES_RESULTSET_EMPTY = 1
+-	, _DB_RES_RESULTSET_ROWS  = 2
+-	, _DB_RES_NEXT_RESULT     = 3
+-	, _DB_RES_NO_MORE_RESULTS = 4
+-	, _DB_RES_SUCCEED         = 5
+-};
++/* $Id: dblib.h,v 1.44 2008/11/12 00:47:25 jklowden Exp $ */
++
++typedef enum tag_DB_RESULT_STATE {
++	  _DB_RES_INIT
++	, _DB_RES_RESULTSET_EMPTY
++	, _DB_RES_RESULTSET_ROWS
++	, _DB_RES_NEXT_RESULT
++	, _DB_RES_NO_MORE_RESULTS
++	, _DB_RES_SUCCEED
++} DB_RESULT_STATE;
+ 
+ struct tds_dblib_loginrec
+ {
+@@ -147,7 +147,7 @@ struct tds_dblib_dbprocess
+ 
+ 	int noautofree;
+ 	int more_results;	/* boolean.  Are we expecting results? */
+-	int dbresults_state;
++	DB_RESULT_STATE dbresults_state;
+ 	int dbresults_retcode;
+ 	BYTE *user_data;	/* see dbsetuserdata() and dbgetuserdata() */
+ 	unsigned char *dbbuf;	/* is dynamic!                   */
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index e485a29..1f86a15 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.329 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.330 2008/11/12 00:47:25 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1608,7 +1608,6 @@ _dbresults(DBPROCESS * dbproc)
+ 	tdsdump_log(TDS_DBG_FUNC, "dbresults: dbresults_state is %d (%s)\n", 
+ 					dbproc->dbresults_state, prdbresults_state(dbproc->dbresults_state));
+ 	switch ( dbproc->dbresults_state ) {
+-
+ 	case _DB_RES_SUCCEED:
+ 		dbproc->dbresults_state = _DB_RES_NEXT_RESULT;
+ 		return SUCCEED;
+@@ -1698,6 +1697,9 @@ _dbresults(DBPROCESS * dbproc)
+ 					dbproc->dbresults_state = _DB_RES_NEXT_RESULT;
+ 					return SUCCEED;
+ 					break;
++				case _DB_RES_NO_MORE_RESULTS:
++				case _DB_RES_SUCCEED:
++					break;
+ 				}
+ 				break;
+ 
+@@ -3734,7 +3736,6 @@ dbprhead(DBPROCESS * dbproc)
+ RETCODE
+ dbrows(DBPROCESS * dbproc)
+ {
+-	TDSRESULTINFO *resinfo;
+ 	TDSSOCKET *tds;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbrows(%p)\n", dbproc);
+@@ -3744,12 +3745,7 @@ dbrows(DBPROCESS * dbproc)
+ 	if (!(tds=dbproc->tds_socket))
+ 		return FAIL;
+ 
+-	resinfo = tds->res_info;
+-
+-	if (resinfo && resinfo->rows_exist)
+-		return SUCCEED;
+-	else
+-		return FAIL;
++	return (tds->res_info && tds->res_info->rows_exist)? SUCCEED : FAIL;
+ }
+ 
+ /**
+@@ -4553,6 +4549,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 	 * We're looking for a result token or a done token.
+          */
+ 	while (!done) {
++		int retcode;
+ 		marker = tds_peek(tds);
+ 
+ 		/* If we hit a result token, then we know everything is OK.  */
+@@ -4590,6 +4587,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 				break;
+ 			case TDS_DONE_RESULT:
+ 			case TDS_DONEPROC_RESULT:
++#if 0
+ 				if (done_flags & TDS_DONE_ERROR) {
+ 					tdsdump_log(TDS_DBG_FUNC, "dbsqlok() end status was error\n");
+ 
+@@ -4608,6 +4606,15 @@ dbsqlok(DBPROCESS * dbproc)
+ 					return SUCCEED;
+ 				}
+ 				break;
++#else
++				retcode = (done_flags & TDS_DONE_ERROR)? FAIL : SUCCEED;
++				dbproc->dbresults_state = (done_flags & TDS_DONE_MORE_RESULTS)?
++					_DB_RES_NEXT_RESULT : _DB_RES_NO_MORE_RESULTS;
++
++				tdsdump_log(TDS_DBG_FUNC, "dbsqlok: returning %s with %s (%#x)\n", 
++						prdbretcode(retcode), prdbresults_state(dbproc->dbresults_state), done_flags);
++				return retcode;
++#endif
+ 			default:
+ 				break;
+ 			}
+
+commit f463c94f6af4078b1f2d95962ab1c0f9f5a3535e
+Author: jklowden <jklowden>
+Date:   Wed Nov 12 00:47:31 2008 +0000
+
+    cosmetic changes
+
+diff --git a/src/dblib/unittests/t0005.c b/src/dblib/unittests/t0005.c
+index 3d96994..c5d9d1a 100644
+--- a/src/dblib/unittests/t0005.c
++++ b/src/dblib/unittests/t0005.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0005.c,v 1.22 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0005.c,v 1.23 2008/11/12 00:47:31 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -137,7 +137,7 @@ main(int argc, char **argv)
+ 		printf("Read a row of data -> %d %s\n", (int) testint, teststr);
+ 	}
+ 
+-	fprintf(stdout, "This query should succeeded as we have fetched exactly the\n"
++	fprintf(stdout, "This query should succeeded as we have fetched the exact\n"
+ 			"number of rows in the result set\n");
+ 
+ 	sprintf(cmd, "select * from #dblib0005 where i < 6 order by i");
+@@ -309,8 +309,8 @@ main(int argc, char **argv)
+ 	}
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "This next command should succeed as we have fetched exactly the.\n");
+-	fprintf(stdout, "number of rows in the result set\n");
++	fprintf(stdout, "This next command should succeed as we have fetched the exact\n"
++			"number of rows in the result set\n");
+ 
+ 	sprintf(cmd, "select getdate()");
+ 	fprintf(stdout, "%s\n", cmd);
+
+commit bc953b85236b44e037ab13775a2692763f485a91
+Author: jklowden <jklowden>
+Date:   Wed Nov 12 00:47:35 2008 +0000
+
+    remember to build types.h
+
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index 28f8f31..4872270 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.66 2008/09/19 13:38:07 freddy77 Exp $
++# $Id: Makefile.am,v 1.67 2008/11/12 00:47:35 jklowden Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -38,7 +38,7 @@ endif
+ data.c:	types.h
+ 
+ if HAVE_PERL_SOURCES
+-BUILT_SOURCES = tds_willconvert.h encodings.h num_limits.h
++BUILT_SOURCES = tds_willconvert.h encodings.h num_limits.h types.h
+ 
+ clean-local: 
+ 	cd $(srcdir) && rm -f $(EXTRA_DIST)
+
+commit 4b2a443286cfc148cad3d192ccf58673615954c9
+Author: jklowden <jklowden>
+Date:   Wed Nov 12 00:47:40 2008 +0000
+
+    set RPATH to prefer build tree
+
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index b2b3694..a82e807 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.29 2008/08/15 09:55:23 freddy77 Exp $
++# $Id: Makefile.am,v 1.30 2008/11/12 00:47:40 jklowden Exp $
+ 
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT) t0004$(EXEEXT) \
+ 			t0005$(EXEEXT) t0006$(EXEEXT) t0007$(EXEEXT) t0008$(EXEEXT) \
+@@ -46,7 +46,7 @@ AM_CPPFLAGS	=	-I$(top_srcdir)/include
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install
++AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
+ endif
+ LIBS		=	../libct.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index d650f41..2eb5e54 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.43 2007/12/03 09:20:10 freddy77 Exp $
++# $Id: Makefile.am,v 1.44 2008/11/12 00:47:40 jklowden Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -51,7 +51,7 @@ AM_CPPFLAGS	= 	-DFREETDS_SRCDIR=\"$(srcdir)\" -I$(top_srcdir)/include
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install
++AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
+ endif
+ LIBS		=	../libsybdb.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32)
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index f04a6ab..c8dedb1 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.78 2008/10/06 13:45:15 freddy77 Exp $
++# $Id: Makefile.am,v 1.79 2008/11/12 00:47:41 jklowden Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -94,7 +94,7 @@ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install
++AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
+ endif
+ LIBS		=	$(ODBCLIB) $(ODBCNODMLIB) @NETWORK_LIBS@
+ DISTCLEANFILES	=	odbc.ini odbcinst.ini
+diff --git a/src/tds/unittests/Makefile.am b/src/tds/unittests/Makefile.am
+index 3dd84b8..51ca91f 100644
+--- a/src/tds/unittests/Makefile.am
++++ b/src/tds/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.24 2008/11/05 14:27:49 freddy77 Exp $
++# $Id: Makefile.am,v 1.25 2008/11/12 00:47:41 jklowden Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) dynamic1$(EXEEXT)\
+@@ -34,7 +34,7 @@ AM_CPPFLAGS	=	-I$(top_srcdir)/include -I$(srcdir)/.. -I../
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install
++AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
+ endif
+ LIBS		=	../libtds.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+
+commit ed9964e64a81b6a05dabf3c05329bf0c3c6bcdcf
+Author: freddy77 <freddy77>
+Date:   Wed Nov 12 10:38:15 2008 +0000
+
+    minor fixes
+
+diff --git a/ChangeLog b/ChangeLog
+index fac72d5..c28c9e2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Nov 12 11:36:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0013.c: check field data
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
++	- fix error result
++
+ Tue Nov 11 19:42:30 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/dblib.h src/dblib/dblib.c 
+ 	- dbsqlok did not process entire packet
+@@ -935,4 +940,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2659 2008/11/12 00:47:25 jklowden Exp $
++$Id: ChangeLog,v 1.2660 2008/11/12 10:38:15 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index b43e9e1..081bdb7 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.23 2006/07/06 12:48:16 freddy77 Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.24 2008/11/12 10:38:15 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -31,6 +31,7 @@ main(int argc, char **argv)
+ 	long numread;
+ 	BOOL readFirstImage;
+ 	char cmd[1024];
++	int data_ok;
+ 
+ 	set_malloc_options();
+ 
+@@ -72,9 +73,9 @@ main(int argc, char **argv)
+ 		fprintf(stderr, "Cannot open input file: %s\n", argv[1]);
+ 		return 2;
+ 	}
+-	result = fseek(fp, 0, SEEK_END);
++	fseek(fp, 0, SEEK_END);
+ 	isiz = ftell(fp);
+-	result = fseek(fp, 0, SEEK_SET);
++	fseek(fp, 0, SEEK_SET);
+ 
+ 	blob = (char *) malloc(isiz);
+ 	fread((void *) blob, isiz, 1, fp);
+@@ -107,8 +108,6 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	while ((result = dbnextrow(dbproc)) != NO_MORE_ROWS) {
+-		result = REG_ROW;
+-		result = DBTXPLEN;
+ 		strcpy(objname, "#dblib0013.PigTure");
+ 		textPtr = dbtxptr(dbproc, 1);
+ 		timeStamp = dbtxtimestamp(dbproc, 1);
+@@ -201,16 +200,21 @@ main(int argc, char **argv)
+ 		}
+ 	}
+ 
+-	printf("Saving first blob data row to file: %s\n", argv[2]);
+-	if ((fp = fopen(argv[2], "wb")) == NULL) {
+-		fprintf(stderr, "Unable to open output file: %s\n", argv[2]);
+-		return 3;
++	data_ok = 1;
++	if (memcmp(blob, rblob, numread) != 0) {
++		printf("Saving first blob data row to file: %s\n", argv[2]);
++		if ((fp = fopen(argv[2], "wb")) == NULL) {
++			fprintf(stderr, "Unable to open output file: %s\n", argv[2]);
++			return 3;
++		}
++		fwrite((void *) rblob, numread, 1, fp);
++		fclose(fp);
++		failed = 1;
++		data_ok = 0;
+ 	}
+-	result = fwrite((void *) rblob, numread, 1, fp);
+-	fclose(fp);
+ 
+ 	printf("Read blob data row %d --> %s %ld byte comparison\n",
+-	       (int) testint, (memcmp(blob, rblob, numread)) ? "failed" : "PASSED", numread);
++	       (int) testint, data_ok ? "PASSED" : "failed", numread);
+ 	free(rblob);
+ 
+ 	if (dbnextrow(dbproc) != NO_MORE_ROWS) {
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index e4264d1..5a2ed80 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.73 2008/10/16 14:09:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.74 2008/11/12 10:38:15 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -280,7 +280,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		case SQL_DEFAULT_PARAM:
+ 			break;	/* OK */
+ 		default:
+-			odbc_errs_add(&stmt->dbc->errs, "HY009", NULL); /* Invalid use of null pointer */
++			odbc_errs_add(&stmt->errs, "HY009", NULL); /* Invalid use of null pointer */
+ 			return SQL_ERROR;
+ 		}
+ 	}		
+@@ -302,7 +302,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		break;
+ 	case SQL_DEFAULT_PARAM:
+ 		/* FIXME: use the default if the parameter has one. */
+-		odbc_errs_add(&stmt->dbc->errs, "07S01", NULL); /* Invalid use of default parameter */
++		odbc_errs_add(&stmt->errs, "07S01", NULL); /* Invalid use of default parameter */
+ 		return SQL_ERROR;
+ 	default:
+ 		if (DataPtr && StrLen_or_Ind < 0) {
+@@ -311,7 +311,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 			 * the argument StrLen_or_Ind was less than 0 
+ 			 * but not equal to SQL_NTS or SQL_NULL_DATA."
+ 			 */
+-			odbc_errs_add(&stmt->dbc->errs, "HY090", NULL);
++			odbc_errs_add(&stmt->errs, "HY090", NULL);
+ 			return SQL_ERROR;
+ 		}
+ 		len = StrLen_or_Ind;
+@@ -332,7 +332,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		SQLLEN extralen = 0;
+ 
+ 		if (0 == (dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type))) {
+-			odbc_errs_add(&dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
++			odbc_errs_add(&stmt->errs, "07006", NULL); /* Restricted data type attribute violation */
+ 			return SQL_ERROR;
+ 		}
+ 
+@@ -340,7 +340,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		/* TODO test intervals */
+ 		src_type = odbc_c_to_server_type(sql_src_type);
+ 		if (src_type == TDS_FAIL) {
+-			odbc_errs_add(&stmt->dbc->errs, "07006", NULL); /* Restricted data type attribute violation */
++			odbc_errs_add(&stmt->errs, "07006", NULL); /* Restricted data type attribute violation */
+ 			return SQL_ERROR;
+ 		}
+ 
+@@ -404,7 +404,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		if (!p) {
+ 			free(free_ptr);
+ 			free(extradata);
+-			odbc_errs_add(&dbc->errs, "HY001", NULL); /* Memory allocation error */
++			odbc_errs_add(&stmt->errs, "HY001", NULL); /* Memory allocation error */
+ 			return SQL_ERROR;
+ 		}
+ 		blob->textvalue = p;
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 896f15e..25a7041 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.78 2008/10/27 14:27:01 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.79 2008/11/12 10:38:15 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -181,9 +181,10 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 
+ 	/* what type to convert ? */
+ 	dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type);
+-	if (dest_type == TDS_FAIL)
+-		/* TODO fill error */
++	if (dest_type == TDS_FAIL) {
++		odbc_errs_add(&stmt->errs, "07006", NULL);	/* Restricted data type attribute violation */
+ 		return SQL_ERROR;
++	}
+ 	tdsdump_log(TDS_DBG_INFO2, "trace\n");
+ 
+ 	/* get C type */
+@@ -241,9 +242,10 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 	/* test source type */
+ 	/* TODO test intervals */
+ 	src_type = odbc_c_to_server_type(sql_src_type);
+-	if (src_type == TDS_FAIL)
+-		/* TODO fill error */
++	if (src_type == TDS_FAIL) {
++		odbc_errs_add(&stmt->errs, "07006", NULL);	/* Restricted data type attribute violation */
+ 		return SQL_ERROR;
++	}
+ 
+ 	/* we have no data to convert, just return */
+ 	if (!compute_row)
+@@ -297,7 +299,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		break;
+ 	case SQL_DEFAULT_PARAM:
+ 	case SQL_DATA_AT_EXEC:
+-		/* TODO fill error */
++		odbc_errs_add(&stmt->errs, "07S01", NULL);	/* Invalid use of default parameter */
+ 		return SQL_ERROR;
+ 		break;
+ 	default:
+@@ -310,7 +312,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 			case SQL_C_BINARY:
+ 				break;
+ 			default:
+-				/* TODO fill error */
++				odbc_errs_add(&stmt->errs, "HY090", NULL);
+ 				return SQL_ERROR;
+ 			}
+ 			len = SQL_LEN_DATA_AT_EXEC(sql_len);
+@@ -323,7 +325,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 			case SQL_LONGVARBINARY:
+ 				break;
+ 			default:
+-				/* TODO fill error */
++				odbc_errs_add(&stmt->errs, "HY090", NULL);
+ 				return SQL_ERROR;
+ 			}
+ 		}
+
+commit 7c5d798d5abf809b83784f788125cc13612f2705
+Author: freddy77 <freddy77>
+Date:   Wed Nov 12 20:58:45 2008 +0000
+
+    fix an issue with some libtool version
+
+diff --git a/ChangeLog b/ChangeLog
+index c28c9e2..eea9680 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Nov 12 21:58:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* Makefile.am config.rpath: fix an issue with some libtool version
++
+ Wed Nov 12 11:36:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0013.c: check field data
+ 	* src/odbc/prepare_query.c src/odbc/sql2tds.c:
+@@ -940,4 +943,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2660 2008/11/12 10:38:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2661 2008/11/12 20:58:45 freddy77 Exp $
+diff --git a/Makefile.am b/Makefile.am
+index 8f1df10..516be66 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-# version $Id: Makefile.am,v 1.44 2008/07/17 11:52:34 freddy77 Exp $
++# version $Id: Makefile.am,v 1.45 2008/11/12 20:58:45 freddy77 Exp $
+ 
+ ## SUBDIRS determines in which directories automake will generate a Makefile
+ ## See also AC_OUTPUT in configure.ac
+@@ -17,7 +17,8 @@ VMS	=	vms/config_h.vms \
+ 
+ EXTRA_DIST = 	$(VMS) interfaces PWD.in BUGS \
+ 		freetds.conf locales.conf \
+-		autogen.sh freetds.spec.in freetds.spec tds.dox 
++		autogen.sh freetds.spec.in freetds.spec tds.dox \
++		config.rpath
+ 
+ 
+ ETC	=	$(DESTDIR)$(sysconfdir)
+diff --git a/config.rpath b/config.rpath
+new file mode 100755
+index 0000000..c547c68
+--- /dev/null
++++ b/config.rpath
+@@ -0,0 +1,666 @@
++#! /bin/sh
++# Output a system dependent set of variables, describing how to set the
++# run time search path of shared libraries in an executable.
++#
++#   Copyright 1996-2007 Free Software Foundation, Inc.
++#   Taken from GNU libtool, 2001
++#   Originally by Gordon Matzigkeit <gord@gnu.ai.mit.edu>, 1996
++#
++#   This file is free software; the Free Software Foundation gives
++#   unlimited permission to copy and/or distribute it, with or without
++#   modifications, as long as this notice is preserved.
++#
++# The first argument passed to this file is the canonical host specification,
++#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
++# or
++#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
++# The environment variables CC, GCC, LDFLAGS, LD, with_gnu_ld
++# should be set by the caller.
++#
++# The set of defined variables is at the end of this script.
++
++# Known limitations:
++# - On IRIX 6.5 with CC="cc", the run time search patch must not be longer
++#   than 256 bytes, otherwise the compiler driver will dump core. The only
++#   known workaround is to choose shorter directory names for the build
++#   directory and/or the installation directory.
++
++# All known linkers require a `.a' archive for static linking (except MSVC,
++# which needs '.lib').
++libext=a
++shrext=.so
++
++host="$1"
++host_cpu=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\1/'`
++host_vendor=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\2/'`
++host_os=`echo "$host" | sed 's/^\([^-]*\)-\([^-]*\)-\(.*\)$/\3/'`
++
++# Code taken from libtool.m4's _LT_CC_BASENAME.
++
++for cc_temp in $CC""; do
++  case $cc_temp in
++    compile | *[\\/]compile | ccache | *[\\/]ccache ) ;;
++    distcc | *[\\/]distcc | purify | *[\\/]purify ) ;;
++    \-*) ;;
++    *) break;;
++  esac
++done
++cc_basename=`echo "$cc_temp" | sed -e 's%^.*/%%'`
++
++# Code taken from libtool.m4's AC_LIBTOOL_PROG_COMPILER_PIC.
++
++wl=
++if test "$GCC" = yes; then
++  wl='-Wl,'
++else
++  case "$host_os" in
++    aix*)
++      wl='-Wl,'
++      ;;
++    darwin*)
++      case $cc_basename in
++        xlc*)
++          wl='-Wl,'
++          ;;
++      esac
++      ;;
++    mingw* | cygwin* | pw32* | os2*)
++      ;;
++    hpux9* | hpux10* | hpux11*)
++      wl='-Wl,'
++      ;;
++    irix5* | irix6* | nonstopux*)
++      wl='-Wl,'
++      ;;
++    newsos6)
++      ;;
++    linux* | k*bsd*-gnu)
++      case $cc_basename in
++        icc* | ecc*)
++          wl='-Wl,'
++          ;;
++        pgcc | pgf77 | pgf90)
++          wl='-Wl,'
++          ;;
++        ccc*)
++          wl='-Wl,'
++          ;;
++        como)
++          wl='-lopt='
++          ;;
++        *)
++          case `$CC -V 2>&1 | sed 5q` in
++            *Sun\ C*)
++              wl='-Wl,'
++              ;;
++          esac
++          ;;
++      esac
++      ;;
++    osf3* | osf4* | osf5*)
++      wl='-Wl,'
++      ;;
++    rdos*)
++      ;;
++    solaris*)
++      wl='-Wl,'
++      ;;
++    sunos4*)
++      wl='-Qoption ld '
++      ;;
++    sysv4 | sysv4.2uw2* | sysv4.3*)
++      wl='-Wl,'
++      ;;
++    sysv4*MP*)
++      ;;
++    sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*)
++      wl='-Wl,'
++      ;;
++    unicos*)
++      wl='-Wl,'
++      ;;
++    uts4*)
++      ;;
++  esac
++fi
++
++# Code taken from libtool.m4's AC_LIBTOOL_PROG_LD_SHLIBS.
++
++hardcode_libdir_flag_spec=
++hardcode_libdir_separator=
++hardcode_direct=no
++hardcode_minus_L=no
++
++case "$host_os" in
++  cygwin* | mingw* | pw32*)
++    # FIXME: the MSVC++ port hasn't been tested in a loooong time
++    # When not using gcc, we currently assume that we are using
++    # Microsoft Visual C++.
++    if test "$GCC" != yes; then
++      with_gnu_ld=no
++    fi
++    ;;
++  interix*)
++    # we just hope/assume this is gcc and not c89 (= MSVC++)
++    with_gnu_ld=yes
++    ;;
++  openbsd*)
++    with_gnu_ld=no
++    ;;
++esac
++
++ld_shlibs=yes
++if test "$with_gnu_ld" = yes; then
++  # Set some defaults for GNU ld with shared library support. These
++  # are reset later if shared libraries are not supported. Putting them
++  # here allows them to be overridden if necessary.
++  # Unlike libtool, we use -rpath here, not --rpath, since the documented
++  # option of GNU ld is called -rpath, not --rpath.
++  hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++  case "$host_os" in
++    aix3* | aix4* | aix5*)
++      # On AIX/PPC, the GNU linker is very broken
++      if test "$host_cpu" != ia64; then
++        ld_shlibs=no
++      fi
++      ;;
++    amigaos*)
++      hardcode_libdir_flag_spec='-L$libdir'
++      hardcode_minus_L=yes
++      # Samuel A. Falvo II <kc5tja@dolphin.openprojects.net> reports
++      # that the semantics of dynamic libraries on AmigaOS, at least up
++      # to version 4, is to share data among multiple programs linked
++      # with the same dynamic library.  Since this doesn't match the
++      # behavior of shared libraries on other platforms, we cannot use
++      # them.
++      ld_shlibs=no
++      ;;
++    beos*)
++      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
++        :
++      else
++        ld_shlibs=no
++      fi
++      ;;
++    cygwin* | mingw* | pw32*)
++      # hardcode_libdir_flag_spec is actually meaningless, as there is
++      # no search path for DLLs.
++      hardcode_libdir_flag_spec='-L$libdir'
++      if $LD --help 2>&1 | grep 'auto-import' > /dev/null; then
++        :
++      else
++        ld_shlibs=no
++      fi
++      ;;
++    interix[3-9]*)
++      hardcode_direct=no
++      hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
++      ;;
++    gnu* | linux* | k*bsd*-gnu)
++      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
++        :
++      else
++        ld_shlibs=no
++      fi
++      ;;
++    netbsd*)
++      ;;
++    solaris*)
++      if $LD -v 2>&1 | grep 'BFD 2\.8' > /dev/null; then
++        ld_shlibs=no
++      elif $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
++        :
++      else
++        ld_shlibs=no
++      fi
++      ;;
++    sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*)
++      case `$LD -v 2>&1` in
++        *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*)
++          ld_shlibs=no
++          ;;
++        *)
++          if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
++            hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-rpath,$libdir`'
++          else
++            ld_shlibs=no
++          fi
++          ;;
++      esac
++      ;;
++    sunos4*)
++      hardcode_direct=yes
++      ;;
++    *)
++      if $LD --help 2>&1 | grep ': supported targets:.* elf' > /dev/null; then
++        :
++      else
++        ld_shlibs=no
++      fi
++      ;;
++  esac
++  if test "$ld_shlibs" = no; then
++    hardcode_libdir_flag_spec=
++  fi
++else
++  case "$host_os" in
++    aix3*)
++      # Note: this linker hardcodes the directories in LIBPATH if there
++      # are no directories specified by -L.
++      hardcode_minus_L=yes
++      if test "$GCC" = yes; then
++        # Neither direct hardcoding nor static linking is supported with a
++        # broken collect2.
++        hardcode_direct=unsupported
++      fi
++      ;;
++    aix4* | aix5*)
++      if test "$host_cpu" = ia64; then
++        # On IA64, the linker does run time linking by default, so we don't
++        # have to do anything special.
++        aix_use_runtimelinking=no
++      else
++        aix_use_runtimelinking=no
++        # Test if we are trying to use run time linking or normal
++        # AIX style linking. If -brtl is somewhere in LDFLAGS, we
++        # need to do runtime linking.
++        case $host_os in aix4.[23]|aix4.[23].*|aix5*)
++          for ld_flag in $LDFLAGS; do
++            if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then
++              aix_use_runtimelinking=yes
++              break
++            fi
++          done
++          ;;
++        esac
++      fi
++      hardcode_direct=yes
++      hardcode_libdir_separator=':'
++      if test "$GCC" = yes; then
++        case $host_os in aix4.[012]|aix4.[012].*)
++          collect2name=`${CC} -print-prog-name=collect2`
++          if test -f "$collect2name" && \
++            strings "$collect2name" | grep resolve_lib_name >/dev/null
++          then
++            # We have reworked collect2
++            :
++          else
++            # We have old collect2
++            hardcode_direct=unsupported
++            hardcode_minus_L=yes
++            hardcode_libdir_flag_spec='-L$libdir'
++            hardcode_libdir_separator=
++          fi
++          ;;
++        esac
++      fi
++      # Begin _LT_AC_SYS_LIBPATH_AIX.
++      echo 'int main () { return 0; }' > conftest.c
++      ${CC} ${LDFLAGS} conftest.c -o conftest
++      aix_libpath=`dump -H conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
++}'`
++      if test -z "$aix_libpath"; then
++        aix_libpath=`dump -HX64 conftest 2>/dev/null | sed -n -e '/Import File Strings/,/^$/ { /^0/ { s/^0  *\(.*\)$/\1/; p; }
++}'`
++      fi
++      if test -z "$aix_libpath"; then
++        aix_libpath="/usr/lib:/lib"
++      fi
++      rm -f conftest.c conftest
++      # End _LT_AC_SYS_LIBPATH_AIX.
++      if test "$aix_use_runtimelinking" = yes; then
++        hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
++      else
++        if test "$host_cpu" = ia64; then
++          hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib'
++        else
++          hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath"
++        fi
++      fi
++      ;;
++    amigaos*)
++      hardcode_libdir_flag_spec='-L$libdir'
++      hardcode_minus_L=yes
++      # see comment about different semantics on the GNU ld section
++      ld_shlibs=no
++      ;;
++    bsdi[45]*)
++      ;;
++    cygwin* | mingw* | pw32*)
++      # When not using gcc, we currently assume that we are using
++      # Microsoft Visual C++.
++      # hardcode_libdir_flag_spec is actually meaningless, as there is
++      # no search path for DLLs.
++      hardcode_libdir_flag_spec=' '
++      libext=lib
++      ;;
++    darwin* | rhapsody*)
++      hardcode_direct=no
++      if test "$GCC" = yes ; then
++        :
++      else
++        case $cc_basename in
++          xlc*)
++            ;;
++          *)
++            ld_shlibs=no
++            ;;
++        esac
++      fi
++      ;;
++    dgux*)
++      hardcode_libdir_flag_spec='-L$libdir'
++      ;;
++    freebsd1*)
++      ld_shlibs=no
++      ;;
++    freebsd2.2*)
++      hardcode_libdir_flag_spec='-R$libdir'
++      hardcode_direct=yes
++      ;;
++    freebsd2*)
++      hardcode_direct=yes
++      hardcode_minus_L=yes
++      ;;
++    freebsd* | dragonfly*)
++      hardcode_libdir_flag_spec='-R$libdir'
++      hardcode_direct=yes
++      ;;
++    hpux9*)
++      hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
++      hardcode_libdir_separator=:
++      hardcode_direct=yes
++      # hardcode_minus_L: Not really in the search PATH,
++      # but as the default location of the library.
++      hardcode_minus_L=yes
++      ;;
++    hpux10*)
++      if test "$with_gnu_ld" = no; then
++        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
++        hardcode_libdir_separator=:
++        hardcode_direct=yes
++        # hardcode_minus_L: Not really in the search PATH,
++        # but as the default location of the library.
++        hardcode_minus_L=yes
++      fi
++      ;;
++    hpux11*)
++      if test "$with_gnu_ld" = no; then
++        hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir'
++        hardcode_libdir_separator=:
++        case $host_cpu in
++          hppa*64*|ia64*)
++            hardcode_direct=no
++            ;;
++          *)
++            hardcode_direct=yes
++            # hardcode_minus_L: Not really in the search PATH,
++            # but as the default location of the library.
++            hardcode_minus_L=yes
++            ;;
++        esac
++      fi
++      ;;
++    irix5* | irix6* | nonstopux*)
++      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++      hardcode_libdir_separator=:
++      ;;
++    netbsd*)
++      hardcode_libdir_flag_spec='-R$libdir'
++      hardcode_direct=yes
++      ;;
++    newsos6)
++      hardcode_direct=yes
++      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++      hardcode_libdir_separator=:
++      ;;
++    openbsd*)
++      if test -f /usr/libexec/ld.so; then
++        hardcode_direct=yes
++        if test -z "`echo __ELF__ | $CC -E - | grep __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then
++          hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
++        else
++          case "$host_os" in
++            openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*)
++              hardcode_libdir_flag_spec='-R$libdir'
++              ;;
++            *)
++              hardcode_libdir_flag_spec='${wl}-rpath,$libdir'
++              ;;
++          esac
++        fi
++      else
++        ld_shlibs=no
++      fi
++      ;;
++    os2*)
++      hardcode_libdir_flag_spec='-L$libdir'
++      hardcode_minus_L=yes
++      ;;
++    osf3*)
++      hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++      hardcode_libdir_separator=:
++      ;;
++    osf4* | osf5*)
++      if test "$GCC" = yes; then
++        hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir'
++      else
++        # Both cc and cxx compiler support -rpath directly
++        hardcode_libdir_flag_spec='-rpath $libdir'
++      fi
++      hardcode_libdir_separator=:
++      ;;
++    solaris*)
++      hardcode_libdir_flag_spec='-R$libdir'
++      ;;
++    sunos4*)
++      hardcode_libdir_flag_spec='-L$libdir'
++      hardcode_direct=yes
++      hardcode_minus_L=yes
++      ;;
++    sysv4)
++      case $host_vendor in
++        sni)
++          hardcode_direct=yes # is this really true???
++          ;;
++        siemens)
++          hardcode_direct=no
++          ;;
++        motorola)
++          hardcode_direct=no #Motorola manual says yes, but my tests say they lie
++          ;;
++      esac
++      ;;
++    sysv4.3*)
++      ;;
++    sysv4*MP*)
++      if test -d /usr/nec; then
++        ld_shlibs=yes
++      fi
++      ;;
++    sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*)
++      ;;
++    sysv5* | sco3.2v5* | sco5v6*)
++      hardcode_libdir_flag_spec='`test -z "$SCOABSPATH" && echo ${wl}-R,$libdir`'
++      hardcode_libdir_separator=':'
++      ;;
++    uts4*)
++      hardcode_libdir_flag_spec='-L$libdir'
++      ;;
++    *)
++      ld_shlibs=no
++      ;;
++  esac
++fi
++
++# Check dynamic linker characteristics
++# Code taken from libtool.m4's AC_LIBTOOL_SYS_DYNAMIC_LINKER.
++# Unlike libtool.m4, here we don't care about _all_ names of the library, but
++# only about the one the linker finds when passed -lNAME. This is the last
++# element of library_names_spec in libtool.m4, or possibly two of them if the
++# linker has special search rules.
++library_names_spec=      # the last element of library_names_spec in libtool.m4
++libname_spec='lib$name'
++case "$host_os" in
++  aix3*)
++    library_names_spec='$libname.a'
++    ;;
++  aix4* | aix5*)
++    library_names_spec='$libname$shrext'
++    ;;
++  amigaos*)
++    library_names_spec='$libname.a'
++    ;;
++  beos*)
++    library_names_spec='$libname$shrext'
++    ;;
++  bsdi[45]*)
++    library_names_spec='$libname$shrext'
++    ;;
++  cygwin* | mingw* | pw32*)
++    shrext=.dll
++    library_names_spec='$libname.dll.a $libname.lib'
++    ;;
++  darwin* | rhapsody*)
++    shrext=.dylib
++    library_names_spec='$libname$shrext'
++    ;;
++  dgux*)
++    library_names_spec='$libname$shrext'
++    ;;
++  freebsd1*)
++    ;;
++  freebsd* | dragonfly*)
++    case "$host_os" in
++      freebsd[123]*)
++        library_names_spec='$libname$shrext$versuffix' ;;
++      *)
++        library_names_spec='$libname$shrext' ;;
++    esac
++    ;;
++  gnu*)
++    library_names_spec='$libname$shrext'
++    ;;
++  hpux9* | hpux10* | hpux11*)
++    case $host_cpu in
++      ia64*)
++        shrext=.so
++        ;;
++      hppa*64*)
++        shrext=.sl
++        ;;
++      *)
++        shrext=.sl
++        ;;
++    esac
++    library_names_spec='$libname$shrext'
++    ;;
++  interix[3-9]*)
++    library_names_spec='$libname$shrext'
++    ;;
++  irix5* | irix6* | nonstopux*)
++    library_names_spec='$libname$shrext'
++    case "$host_os" in
++      irix5* | nonstopux*)
++        libsuff= shlibsuff=
++        ;;
++      *)
++        case $LD in
++          *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") libsuff= shlibsuff= ;;
++          *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") libsuff=32 shlibsuff=N32 ;;
++          *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") libsuff=64 shlibsuff=64 ;;
++          *) libsuff= shlibsuff= ;;
++        esac
++        ;;
++    esac
++    ;;
++  linux*oldld* | linux*aout* | linux*coff*)
++    ;;
++  linux* | k*bsd*-gnu)
++    library_names_spec='$libname$shrext'
++    ;;
++  knetbsd*-gnu)
++    library_names_spec='$libname$shrext'
++    ;;
++  netbsd*)
++    library_names_spec='$libname$shrext'
++    ;;
++  newsos6)
++    library_names_spec='$libname$shrext'
++    ;;
++  nto-qnx*)
++    library_names_spec='$libname$shrext'
++    ;;
++  openbsd*)
++    library_names_spec='$libname$shrext$versuffix'
++    ;;
++  os2*)
++    libname_spec='$name'
++    shrext=.dll
++    library_names_spec='$libname.a'
++    ;;
++  osf3* | osf4* | osf5*)
++    library_names_spec='$libname$shrext'
++    ;;
++  rdos*)
++    ;;
++  solaris*)
++    library_names_spec='$libname$shrext'
++    ;;
++  sunos4*)
++    library_names_spec='$libname$shrext$versuffix'
++    ;;
++  sysv4 | sysv4.3*)
++    library_names_spec='$libname$shrext'
++    ;;
++  sysv4*MP*)
++    library_names_spec='$libname$shrext'
++    ;;
++  sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*)
++    library_names_spec='$libname$shrext'
++    ;;
++  uts4*)
++    library_names_spec='$libname$shrext'
++    ;;
++esac
++
++sed_quote_subst='s/\(["`$\\]\)/\\\1/g'
++escaped_wl=`echo "X$wl" | sed -e 's/^X//' -e "$sed_quote_subst"`
++shlibext=`echo "$shrext" | sed -e 's,^\.,,'`
++escaped_libname_spec=`echo "X$libname_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
++escaped_library_names_spec=`echo "X$library_names_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
++escaped_hardcode_libdir_flag_spec=`echo "X$hardcode_libdir_flag_spec" | sed -e 's/^X//' -e "$sed_quote_subst"`
++
++LC_ALL=C sed -e 's/^\([a-zA-Z0-9_]*\)=/acl_cv_\1=/' <<EOF
++
++# How to pass a linker flag through the compiler.
++wl="$escaped_wl"
++
++# Static library suffix (normally "a").
++libext="$libext"
++
++# Shared library suffix (normally "so").
++shlibext="$shlibext"
++
++# Format of library name prefix.
++libname_spec="$escaped_libname_spec"
++
++# Library names that the linker finds when passed -lNAME.
++library_names_spec="$escaped_library_names_spec"
++
++# Flag to hardcode \$libdir into a binary during linking.
++# This must work even if \$libdir does not exist.
++hardcode_libdir_flag_spec="$escaped_hardcode_libdir_flag_spec"
++
++# Whether we need a single -rpath flag with a separated argument.
++hardcode_libdir_separator="$hardcode_libdir_separator"
++
++# Set to yes if using DIR/libNAME.so during linking hardcodes DIR into the
++# resulting binary.
++hardcode_direct="$hardcode_direct"
++
++# Set to yes if using the -LDIR flag during linking hardcodes DIR into the
++# resulting binary.
++hardcode_minus_L="$hardcode_minus_L"
++
++EOF
+
+commit 8f8961e382df551150816e7eede21af7f1765b92
+Author: jklowden <jklowden>
+Date:   Fri Nov 14 05:58:14 2008 +0000
+
+    better metadata and -V option for ODBC version
+
+diff --git a/ChangeLog b/ChangeLog
+index eea9680..fb37ad3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Nov 14 00:56:39 EST 2008	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqlodbc.c 
++	- better metadata and -V option for ODBC version
++
+ Wed Nov 12 21:58:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* Makefile.am config.rpath: fix an issue with some libtool version
+ 
+@@ -943,4 +947,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2661 2008/11/12 20:58:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2662 2008/11/14 05:58:14 jklowden Exp $
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index 89d9c19..c8e7b06 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.10 2008/02/13 08:52:09 freddy77 Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.11 2008/11/14 05:58:14 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -79,6 +79,7 @@ typedef struct _options
+ { 
+ 	int 	fverbose, 
+ 		fquiet;
++	size_t	odbc_version;
+ 	FILE 	*headers, 
+ 		*verbose;
+ 	char 	*servername, 
+@@ -273,7 +274,7 @@ main(int argc, char *argv[])
+ 	}
+ 	assert(hEnv);
+ 
+-	if ((erc = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) SQL_OV_ODBC3, SQL_IS_UINTEGER)) != SQL_SUCCESS) {
++	if ((erc = SQLSetEnvAttr(hEnv, SQL_ATTR_ODBC_VERSION, (SQLPOINTER)options.odbc_version, SQL_IS_UINTEGER)) != SQL_SUCCESS){
+ 		odbc_herror(SQL_HANDLE_DBC, hDbc, erc, "SQLSetEnvAttr", "failed to set SQL_OV_ODBC3");
+ 		exit(EXIT_FAILURE);
+ 	}
+@@ -413,6 +414,54 @@ free_metadata(struct METADATA *metadata, struct DATA *data, int ncols)
+ 	free(data);
+ }
+ 
++const char *
++prtype(SQLSMALLINT type)
++{
++	static char buffer[64];
++	
++	switch(type) {
++	case SQL_UNKNOWN_TYPE:		return "SQL_UNKNOWN_TYPE";
++	case SQL_CHAR:			return "SQL_CHAR";
++	case SQL_NUMERIC:		return "SQL_NUMERIC";
++	case SQL_DECIMAL:		return "SQL_DECIMAL";
++	case SQL_INTEGER:		return "SQL_INTEGER";
++	case SQL_SMALLINT:		return "SQL_SMALLINT";
++	case SQL_FLOAT:			return "SQL_FLOAT";
++	case SQL_REAL:			return "SQL_REAL";
++	case SQL_DOUBLE:		return "SQL_DOUBLE";
++#if (ODBCVER >= 0x0300)
++	case SQL_DATETIME:		return "SQL_DATETIME";
++#else
++	case SQL_DATE:			return "SQL_DATE";
++#endif
++	case SQL_VARCHAR:		return "SQL_VARCHAR";
++#if (ODBCVER >= 0x0300)
++	case SQL_TYPE_DATE:		return "SQL_TYPE_DATE";
++	case SQL_TYPE_TIME:		return "SQL_TYPE_TIME";
++	case SQL_TYPE_TIMESTAMP:	return "SQL_TYPE_TIMESTAMP";
++#endif
++#if (ODBCVER >= 0x0300)
++	case SQL_INTERVAL:		return "SQL_INTERVAL";
++#else
++	case SQL_TIME:			return "SQL_TIME";
++#endif  /* ODBCVER >= 0x0300 */
++	case SQL_TIMESTAMP:		return "SQL_TIMESTAMP";
++	case SQL_LONGVARCHAR:		return "SQL_LONGVARCHAR";
++	case SQL_BINARY:		return "SQL_BINARY";
++	case SQL_VARBINARY:		return "SQL_VARBINARY";
++	case SQL_LONGVARBINARY:		return "SQL_LONGVARBINARY";
++	case SQL_BIGINT:		return "SQL_BIGINT";
++	case SQL_TINYINT:		return "SQL_TINYINT";
++	case SQL_BIT:			return "SQL_BIT";
++#if (ODBCVER >= 0x0350)
++	case SQL_GUID:			return "SQL_GUID";
++#endif  /* ODBCVER >= 0x0350 */
++	}
++
++	sprintf(buffer, "unknown: %d", (int)type);
++	return buffer;
++}
++
+ static void
+ print_results(SQLHSTMT hStmt) 
+ {
+@@ -460,8 +509,8 @@ print_results(SQLHSTMT hStmt)
+ 		 */
+ 
+ 		fprintf(options.verbose, "Metadata\n");
+-		fprintf(options.verbose, "%-6s  %-30s  %-30s  %-15s  %-6s  %-6s  \n", "col", "name", "source", "type", "size", "varies");
+-		fprintf(options.verbose, "%.6s  %.30s  %.30s  %.15s  %.6s  %.6s  \n", dashes, dashes, dashes, dashes, dashes, dashes);
++		fprintf(options.verbose, "%-6s  %-30s  %-10s  %-18s  %-6s  %-6s  \n", "col", "name", "type value", "type name", "size", "varies");
++		fprintf(options.verbose, "%.6s  %.30s  %.10s  %.18s  %.6s  %.6s  \n", dashes, dashes, dashes, dashes, dashes, dashes);
+ 		for (c=0; c < ncols; c++) {
+ 			/* Get and print the metadata.  Optional: get only what you need. */
+ 			SQLCHAR name[512];
+@@ -478,8 +527,8 @@ print_results(SQLHSTMT hStmt)
+ 			metadata[c].name = strdup((char *) name);
+ 			metadata[c].width = (ndigits > metadata[c].size)? ndigits : metadata[c].size;
+ 
+-			fprintf(options.verbose, "%6d  %30s  %30s  %15s  %6lu  %6d  \n", 
+-				c+1, metadata[c].name, metadata[c].source, "(todo)", 
++			fprintf(options.verbose, "%6d  %30s  %10d  %18s  %6lu  %6d  \n", 
++				c+1, metadata[c].name, (int)metadata[c].type, prtype(metadata[c].type), 
+ 				(long unsigned int) metadata[c].size,  -1);
+ 
+ #if 0
+@@ -737,6 +786,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	
+ 	options->appname = tds_basename(argv[0]);
+ 	options->colsep = default_colsep; /* may be overridden by -t */
++	options->odbc_version = SQL_OV_ODBC3;	  /* may be overridden by -V */
+ 	
+ 	login = calloc(1, sizeof(LOGINREC));
+ 	
+@@ -749,7 +799,8 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 		perror("unable to get hostname");
+ 	} 
+ 
+-	while ((ch = getopt(argc, argv, "U:P:S:dD:i:o:e:t:hqv")) != -1) {
++	while ((ch = getopt(argc, argv, "U:P:S:dD:i:o:e:t:V:hqv")) != -1) {
++		char *p;
+ 		switch (ch) {
+ 		case 'U':
+ 			login->username = strdup(optarg);
+@@ -783,6 +834,19 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 		case 'q':
+ 			options->fquiet = 1;
+ 			break;
++		case 'V':
++			switch(strtol(optarg, &p, 10)) {
++			case 3: 
++				options->odbc_version = SQL_OV_ODBC3
++				;
++				break;
++			case 2:
++				options->odbc_version = SQL_OV_ODBC2;
++				break;
++			default:
++				fprintf(stderr, "warning: -V must be 2 or 3, not %s.  Using default of 3\n", optarg);
++				break;
++			}
+ 		case 'v':
+ 			options->fverbose = 1;
+ 			break;
+
+commit de2b2ecaae562f435ab82bcda9ac629fe6b58a01
+Author: freddy77 <freddy77>
+Date:   Fri Nov 14 16:34:22 2008 +0000
+
+    a bit more portable
+
+diff --git a/src/server/login.c b/src/server/login.c
+index 085b89f..976beed 100644
+--- a/src/server/login.c
++++ b/src/server/login.c
+@@ -58,7 +58,7 @@
+ #include "tdssrv.h"
+ #include "tdsstring.h"
+ 
+-static char software_version[] = "$Id: login.c,v 1.52 2008/01/07 14:07:21 freddy77 Exp $";
++static char software_version[] = "$Id: login.c,v 1.53 2008/11/14 16:34:22 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ unsigned char *
+@@ -88,7 +88,8 @@ tds_listen(TDSCONTEXT * ctx, int ip_port)
+ 	sin.sin_port = htons((short) ip_port);
+ 	sin.sin_family = AF_INET;
+ 
+-	if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
++	s = socket(AF_INET, SOCK_STREAM, 0);
++	if (TDS_IS_SOCKET_INVALID(s)) {
+ 		perror("socket");
+ 		return NULL;
+ 	}
+@@ -99,7 +100,8 @@ tds_listen(TDSCONTEXT * ctx, int ip_port)
+ 	}
+ 	listen(s, 5);
+ 	len = sizeof(sin);
+-	if ((fd = accept(s, (struct sockaddr *) &sin, &len)) < 0) {
++	fd = accept(s, (struct sockaddr *) &sin, &len);
++	if (TDS_IS_SOCKET_INVALID(fd)) {
+ 		CLOSESOCKET(s);
+ 		perror("accept");
+ 		return NULL;
+
+commit 316408f1038f23076ca5d03072cbe202953ea781
+Author: freddy77 <freddy77>
+Date:   Fri Nov 14 16:35:40 2008 +0000
+
+    update
+
+diff --git a/TODO.freddy b/TODO.freddy
+index 1f475c8..c05e367 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -54,10 +54,10 @@ test to review
+ - blob1.c (SQLGetData test with binary -> char and between chars)
+ Is it possible to support direct binding for parameters using different
+ encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
+-possible changing TDSCOLUMN->char_conv. Some work should be done in 
+-src/tds/iconv.c in order to get a valid char_conv changing client encoding.
++possible changing TDSCOLUMN->char_conv.
+ Merge putdata and blob1 tests, tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases).
+ Check blob1 dialog, seems to prepare twice during insert.
++Do merge a bit continue_parse_prepared_query and odbc_sql2tds ??
+ 
+ Other
+ -----
+
+commit d3f560f948a0e57b0edcfa44595146cbf29dab89
+Author: freddy77 <freddy77>
+Date:   Fri Nov 14 16:52:38 2008 +0000
+
+    *** empty log message ***
+
+diff --git a/m4/.cvsignore b/m4/.cvsignore
+new file mode 100644
+index 0000000..38066dd
+--- /dev/null
++++ b/m4/.cvsignore
+@@ -0,0 +1,5 @@
++libtool.m4
++ltoptions.m4
++ltsugar.m4
++ltversion.m4
++lt~obsolete.m4
+
+commit 03aa0e562c8711f97b8c3ec069d1999ad613929a
+Author: freddy77 <freddy77>
+Date:   Sat Nov 15 09:57:06 2008 +0000
+
+    remove some windows warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index fb37ad3..04ddc24 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sat Nov 15 10:56:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/apps/bsqlodbc.c:
++	* src/pool/member.c src/pool/user.c:
++	- remove some windows warnings
++
+ Fri Nov 14 00:56:39 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/bsqlodbc.c 
+ 	- better metadata and -V option for ODBC version
+@@ -947,4 +952,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2662 2008/11/14 05:58:14 jklowden Exp $
++$Id: ChangeLog,v 1.2663 2008/11/15 09:57:06 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index bce25a0..4b523e0 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.25 2008/01/20 14:23:59 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.26 2008/11/15 09:57:06 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -69,8 +69,8 @@ typedef int pid_t;
+ 
+ #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
+ #include <windows.h>
+-#define READSOCKET(a,b,c)	recv((a), (b), (c), TDS_NOSIGNAL)
+-#define WRITESOCKET(a,b,c)	send((a), (b), (c), TDS_NOSIGNAL)
++#define READSOCKET(a,b,c)	recv((a), (char *) (b), (c), TDS_NOSIGNAL)
++#define WRITESOCKET(a,b,c)	send((a), (const char *) (b), (c), TDS_NOSIGNAL)
+ #define CLOSESOCKET(a)		closesocket((a))
+ #define IOCTLSOCKET(a,b,c)	ioctlsocket((a), (b), (c))
+ #define SOCKLEN_T int
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index c8e7b06..63cd677 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.11 2008/11/14 05:58:14 jklowden Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.12 2008/11/15 09:57:06 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -414,7 +414,7 @@ free_metadata(struct METADATA *metadata, struct DATA *data, int ncols)
+ 	free(data);
+ }
+ 
+-const char *
++static const char *
+ prtype(SQLSMALLINT type)
+ {
+ 	static char buffer[64];
+diff --git a/src/pool/member.c b/src/pool/member.c
+index 347142e..b82e25d 100644
+--- a/src/pool/member.c
++++ b/src/pool/member.c
+@@ -59,7 +59,7 @@
+ #define MAXHOSTNAMELEN 256
+ #endif /* MAXHOSTNAMELEN */
+ 
+-TDS_RCSID(var, "$Id: member.c,v 1.41 2006/12/26 14:56:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: member.c,v 1.42 2008/11/15 09:57:06 freddy77 Exp $");
+ 
+ static int pool_packet_read(TDS_POOL_MEMBER * pmbr);
+ static TDSSOCKET *pool_mbr_login(TDS_POOL * pool);
+@@ -260,14 +260,9 @@ pool_process_members(TDS_POOL * pool, fd_set * fds)
+ 						pmbr->state = TDS_IDLE;
+ 						puser->user_state = TDS_SRV_IDLE;
+ 					}
+-#ifdef MSG_NOSIGNAL	
+ 					/* cf. net.c for better technique.  */
+-					ret = send(puser->tds->s, buf, tds->in_len, MSG_NOSIGNAL);
+-#else
+-					/* write(puser->tds->s, buf, tds->in_len); */
+-					ret = send(puser->tds->s, buf, tds->in_len, 0);
+-#endif
+-					if (ret==-1) { /* couldn't write, ditch the user */
++					ret = WRITESOCKET(puser->tds->s, buf, tds->in_len);
++					if (ret < 0) { /* couldn't write, ditch the user */
+ 						fprintf(stdout, "member %d received error while writing\n",i);
+ 						pool_free_user(pmbr->current_user);
+ 						pool_deassign_member(pmbr);
+diff --git a/src/pool/user.c b/src/pool/user.c
+index 000a9f4..e2db9db 100644
+--- a/src/pool/user.c
++++ b/src/pool/user.c
+@@ -48,7 +48,7 @@
+ #include "tdssrv.h"
+ #include "tdsstring.h"
+ 
+-TDS_RCSID(var, "$Id: user.c,v 1.32 2008/01/07 14:07:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: user.c,v 1.33 2008/11/15 09:57:06 freddy77 Exp $");
+ 
+ static TDS_POOL_USER *pool_user_find_new(TDS_POOL * pool);
+ static int pool_user_login(TDS_POOL * pool, TDS_POOL_USER * puser);
+@@ -298,17 +298,11 @@ pool_user_query(TDS_POOL * pool, TDS_POOL_USER * puser)
+ 	} else {
+ 		pmbr->state = TDS_QUERYING;
+ 		pool_assign_member(pmbr, puser);
+-#ifdef MSG_NOSIGNAL	
+ 		/* cf. net.c for better technique.  */
+-		ret = send(pmbr->tds->s, puser->tds->in_buf, puser->tds->in_len, MSG_NOSIGNAL);
+-#else
+-		/* write(pmbr->tds->s, puser->tds->in_buf, puser->tds->in_len); */
+-		ret = send(pmbr->tds->s, puser->tds->in_buf, puser->tds->in_len, 0);
+-#endif
++		ret = WRITESOCKET(pmbr->tds->s, puser->tds->in_buf, puser->tds->in_len);
+ 		/* write failed, cleanup member */
+-		if (ret==-1) {
++		if (ret < 0) {
+ 			pool_free_member(pmbr);
+ 		}
+-
+ 	}
+ }
+
+commit f9f4dc2472417412c2ddc2b1f71192d1daf890c4
+Author: jklowden <jklowden>
+Date:   Tue Nov 18 01:16:49 2008 +0000
+
+    src/dblib/bcp.c src/dblib/unittests/bcp.c src/dblib/unittests/common.c src/dblib/unittests/common.h src/dblib/unittests/dbmorecmds.c src/dblib/unittests/hang.c src/dblib/unittests/null.c src/dblib/unittests/null2.c src/dblib/unittests/rpc.c src/dblib/unittests/setnull.c src/dblib/unittests/t0001.c src/dblib/unittests/t0002.c src/dblib/unittests/t0003.c src/dblib/unittests/t0004.c src/dblib/unittests/t0005.c src/dblib/unittests/t0006.c src/dblib/unittests/t0007.c src/dblib/unittests/t0008.c src/dblib/unittests/t0009.c src/dblib/unittests/t0011.c  src/dblib/unittests/t0012.c src/dblib/unittests/t0013.c src/dblib/unittests/t0014.c src/dblib/unittests/t0015.c src/dblib/unittests/t0016.c src/dblib/unittests/t0018.c src/dblib/unittests/t0020.c src/dblib/unittests/t0021.c src/dblib/unittests/t0022.c src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c src/dblib/unittests/thread.c src/dblib/unittests/timeout.c win32/tds_sysdep_public.h begin making unittests work with Microsoft's library
+
+diff --git a/ChangeLog b/ChangeLog
+index 04ddc24..b7251a8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,27 @@
++Mon Nov 17 19:46:34 EST 2008	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c 
++	- src/dblib/bcp.c src/dblib/unittests/bcp.c
++	- src/dblib/unittests/common.c src/dblib/unittests/common.h
++	- src/dblib/unittests/dbmorecmds.c
++	- src/dblib/unittests/hang.c src/dblib/unittests/null.c
++	- src/dblib/unittests/null2.c src/dblib/unittests/rpc.c
++	- src/dblib/unittests/setnull.c
++	- src/dblib/unittests/t0001.c src/dblib/unittests/t0002.c
++	- src/dblib/unittests/t0003.c src/dblib/unittests/t0004.c
++	- src/dblib/unittests/t0005.c src/dblib/unittests/t0006.c
++	- src/dblib/unittests/t0007.c src/dblib/unittests/t0008.c
++	- src/dblib/unittests/t0009.c src/dblib/unittests/t0011.c 
++	- src/dblib/unittests/t0012.c src/dblib/unittests/t0013.c
++	- src/dblib/unittests/t0014.c src/dblib/unittests/t0015.c
++	- src/dblib/unittests/t0016.c src/dblib/unittests/t0018.c
++	- src/dblib/unittests/t0020.c src/dblib/unittests/t0021.c
++	- src/dblib/unittests/t0022.c src/dblib/unittests/t0023.c
++	- src/dblib/unittests/text_buffer.c
++	- src/dblib/unittests/thread.c
++	- src/dblib/unittests/timeout.c
++	- win32/tds_sysdep_public.h
++	- begin making unittests work with Microsoft's library
++
+ Sat Nov 15 10:56:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h src/apps/bsqlodbc.c:
+ 	* src/pool/member.c src/pool/user.c:
+@@ -952,4 +976,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2663 2008/11/15 09:57:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2664 2008/11/18 01:16:49 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 1f86a15..f23ac5d 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.330 2008/11/12 00:47:25 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.331 2008/11/18 01:16:49 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4587,7 +4587,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 				break;
+ 			case TDS_DONE_RESULT:
+ 			case TDS_DONEPROC_RESULT:
+-#if 0
++#if 1
+ 				if (done_flags & TDS_DONE_ERROR) {
+ 					tdsdump_log(TDS_DBG_FUNC, "dbsqlok() end status was error\n");
+ 
+
+commit 088e8a1341dc47b8079d89ea6afa164b461e2e59
+Author: jklowden <jklowden>
+Date:   Thu Nov 20 15:59:06 2008 +0000
+
+    added version & encrypted questions
+
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index 1ee35e4..dd03394 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,16 +3,20 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.23 2008/08/21 03:58:14 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.24 2008/11/20 15:59:06 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+   "HTML Tidy for NetBSD (vers 1st August 2004), see www.w3.org" />
+ 
+   <title>FreeTDS Frequently Asked Questions</title>
++  
++  <style type="text/css">
++  	body {bgcolor = #F9F9F9}
++  </style> 
+ </head>
+ 
+-<body bgcolor="#F9F9F9">
++<body>
+   <!-- generic header -->
+ 
+   <table summary="table of contents">
+@@ -53,7 +57,11 @@
+         <li><a href="#Does.FreeTDS.support.Microsoft.servers">Does
+         FreeTDS support Microsoft servers?</a></li>
+ 
+-        <li><a href="#How.can.I.get.help">How can I get help (or
++         <li><a href="#Does.FreeTDS.support.my.server">
++	 Does version <i>X</i> of FreeTDS connect to version <i>Y</i> of 
++	 my Microsoft or Sybase server? </a></li>
++
++       <li><a href="#How.can.I.get.help">How can I get help (or
+         support)?</a></li>
+ 
+         <li><a href="#Who.is.responsible.for.FreeTDS">Who is
+@@ -135,7 +143,9 @@
+         <li><a href="#connectionrefused">What if I get a
+         'connection refused' message?</a></li>
+ 
+-        <li><a href="#integratedsecurity">The server is listening,
++         <li><a href="#encrypted">Do encrypted connections work?</a></li>
++
++       <li><a href="#integratedsecurity">The server is listening,
+         but logins fail? (MS SQL only)</a></li>
+ 
+         <li><a href="#textdata">My <tt>text</tt> data are being
+@@ -192,6 +202,19 @@
+   "userguide/choosingtdsprotocol.htm">User
+   Guide</a> for details.</p>
+ 
++  <h3 id="Does.FreeTDS.support.my.server">
++  	Does version <i>X</i> of FreeTDS connect to version <i>Y</i> of 
++	 my Microsoft or Sybase server?</h3>
++
++  <p>For the last several years, every version of FreeTDS has been 
++  able to communicate with every kind of TDS server.  New servers 
++  sometimes introduce new protocol features, but the changes are small, 
++  and they're always compatible with old clients.  
++  Generally, you should use the latest version of the TDS protocol 
++  for your server.    See the <a href=
++  "userguide/choosingtdsprotocol.htm">User
++  Guide</a> for details.</p>
++
+   <h3>How can I get help (or support)?</h3>
+ 	<a name="How.can.I.get.help" id="How.can.I.get.help"></a>
+ 	
+@@ -803,6 +826,11 @@
+   "userguide/domains.htm">User Guide</a> for
+   details. <a name="textdata" id="textdata"></a></p>
+ 
++  <h3 id="encrypted">Do encrypted connections work?</h3>
++  
++  <p>Encrypted connections to Microsoft SQL Server 2008 using 
++  FreeTDS 0.82 do not work.  Avoid them.  Patches welcome! </p>
++
+   <h3>My <tt>text</tt> data are being truncated or are causing my
+   client to break.</h3>
+ 
+@@ -879,7 +907,7 @@
+   <font size="-1">Updates and comments <a href=
+   "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
+   <br/>
+-    <i>$Id: faq.html,v 1.23 2008/08/21 03:58:14 jklowden Exp $</i>
++    <i>$Id: faq.html,v 1.24 2008/11/20 15:59:06 jklowden Exp $</i>
+ 	</font>
+ <hr/>
+   <p>
+
+commit f741e787336452be2233c43ca02e6b363a46c6d4
+Author: jklowden <jklowden>
+Date:   Tue Nov 25 22:58:28 2008 +0000
+
+    begin making unittests work with Microsoft's library
+
+diff --git a/ChangeLog b/ChangeLog
+index b7251a8..afbe251 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,25 +1,25 @@
+ Mon Nov 17 19:46:34 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c 
+-	- src/dblib/bcp.c src/dblib/unittests/bcp.c
+-	- src/dblib/unittests/common.c src/dblib/unittests/common.h
+-	- src/dblib/unittests/dbmorecmds.c
+-	- src/dblib/unittests/hang.c src/dblib/unittests/null.c
+-	- src/dblib/unittests/null2.c src/dblib/unittests/rpc.c
+-	- src/dblib/unittests/setnull.c
+-	- src/dblib/unittests/t0001.c src/dblib/unittests/t0002.c
+-	- src/dblib/unittests/t0003.c src/dblib/unittests/t0004.c
+-	- src/dblib/unittests/t0005.c src/dblib/unittests/t0006.c
+-	- src/dblib/unittests/t0007.c src/dblib/unittests/t0008.c
+-	- src/dblib/unittests/t0009.c src/dblib/unittests/t0011.c 
+-	- src/dblib/unittests/t0012.c src/dblib/unittests/t0013.c
+-	- src/dblib/unittests/t0014.c src/dblib/unittests/t0015.c
+-	- src/dblib/unittests/t0016.c src/dblib/unittests/t0018.c
+-	- src/dblib/unittests/t0020.c src/dblib/unittests/t0021.c
+-	- src/dblib/unittests/t0022.c src/dblib/unittests/t0023.c
+-	- src/dblib/unittests/text_buffer.c
+-	- src/dblib/unittests/thread.c
+-	- src/dblib/unittests/timeout.c
+-	- win32/tds_sysdep_public.h
++	* src/dblib/bcp.c src/dblib/unittests/bcp.c
++	* src/dblib/unittests/common.c src/dblib/unittests/common.h
++	* src/dblib/unittests/dbmorecmds.c
++	* src/dblib/unittests/hang.c src/dblib/unittests/null.c
++	* src/dblib/unittests/null2.c src/dblib/unittests/rpc.c
++	* src/dblib/unittests/setnull.c
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0002.c
++	* src/dblib/unittests/t0003.c src/dblib/unittests/t0004.c
++	* src/dblib/unittests/t0005.c src/dblib/unittests/t0006.c
++	* src/dblib/unittests/t0007.c src/dblib/unittests/t0008.c
++	* src/dblib/unittests/t0009.c src/dblib/unittests/t0011.c 
++	* src/dblib/unittests/t0012.c src/dblib/unittests/t0013.c
++	* src/dblib/unittests/t0014.c src/dblib/unittests/t0015.c
++	* src/dblib/unittests/t0016.c src/dblib/unittests/t0018.c
++	* src/dblib/unittests/t0020.c src/dblib/unittests/t0021.c
++	* src/dblib/unittests/t0022.c src/dblib/unittests/t0023.c
++	* src/dblib/unittests/text_buffer.c
++	* src/dblib/unittests/thread.c
++	* src/dblib/unittests/timeout.c
++	* win32/tds_sysdep_public.h
+ 	- begin making unittests work with Microsoft's library
+ 
+ Sat Nov 15 10:56:48 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+@@ -976,4 +976,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2664 2008/11/18 01:16:49 jklowden Exp $
++$Id: ChangeLog,v 1.2665 2008/11/25 22:58:28 jklowden Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 2810fcb..4e780a0 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -71,7 +71,7 @@ typedef struct _pbcb
+ }
+ TDS_PBCB;
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.172 2008/05/26 13:56:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.173 2008/11/25 22:58:28 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -1400,6 +1400,12 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 		 * At this point, however the field was read, however big it was, its address is coldata and its size is collen.
+ 		 */
+ 		tdsdump_log(TDS_DBG_FUNC, "Data read from hostfile: collen is now %d, data_is_null is %d\n", collen, data_is_null);
++		if (i == 370 - 1) {
++			char buf[32];
++			memset(buf, '\0', sizeof(buf));
++			memcpy(buf, coldata, collen);
++			tdsdump_log(TDS_DBG_FUNC, "column 370 is '%s', converts to %f\n", buf, atof(buf));
++		}
+ 		if (hostcol->tab_colnum) {
+ 			if (data_is_null) {
+ 				bcpcol->bcp_column_data->is_null = 1;
+@@ -2024,6 +2030,8 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 	
+ 					}
+ 				}
++			} else {
++				printf("skipping row %d (because <= %d)\n", dbproc->hostfileinfo->firstrow, row_of_hostfile);
+ 			}
+ 		}
+ 
+diff --git a/src/dblib/unittests/bcp.c b/src/dblib/unittests/bcp.c
+index 4e6b048..5954615 100644
+--- a/src/dblib/unittests/bcp.c
++++ b/src/dblib/unittests/bcp.c
+@@ -13,7 +13,7 @@
+ 
+ #include "bcp.h"
+ 
+-static char software_version[] = "$Id: bcp.c,v 1.14 2007/11/26 08:52:40 freddy77 Exp $";
++static char software_version[] = "$Id: bcp.c,v 1.15 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[512];
+@@ -189,7 +189,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	dbinit();
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 37961a0..1a7d5de 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -16,7 +16,7 @@
+ #include "replacements.h"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.24 2008/09/09 14:48:03 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.25 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -154,7 +154,7 @@ read_login_info(int argc, char **argv)
+ 		in = fopen(filename, "r");
+ 		if (!in) {
+ 			fprintf(stderr, "Can not open %s file\n\n", filename);
+-			return 1;
++			goto Override;
+ 		}
+ 	}
+ 
+@@ -175,6 +175,7 @@ read_login_info(int argc, char **argv)
+ 	}
+ 	fclose(in);
+ 	
++	Override:
+ 	/* apply command-line overrides */
+ 	if (options.username) {
+ 		strcpy(USER, options.username);
+@@ -192,6 +193,11 @@ read_login_info(int argc, char **argv)
+ 		strcpy(DATABASE, options.database);
+ 		free(options.database);
+ 	}
++
++	if (!*SERVER) {
++		fprintf(stderr, "no servername provided, quitting.\n");
++		exit(1);
++	}
+ 	
+ 	printf("found %s.%s for %s in \"%s\"\n", SERVER, DATABASE, USER, filename);
+ 	return 0;
+@@ -326,7 +332,10 @@ syb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, cha
+ 		}
+ 	}
+ 
+-	assert(0); /* no unanticipated messages allowed in unit tests */
++	if (severity) {
++		fprintf(stderr, "exit: no unanticipated messages allowed in unit tests\n");
++		exit(EXIT_FAILURE);
++	}
+ 	return 0;
+ }
+ 
+@@ -356,8 +365,8 @@ syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *db
+ 	}
+ 
+ 	fprintf(stderr,
+-		"DB-LIBRARY error (severity %d, dberr %d, oserr %d, dberrstr %s, oserrstr %s):\n",
+-		severity, dberr, oserr, dberrstr ? dberrstr : "(null)", oserrstr ? oserrstr : "(null)");
++		"DB-LIBRARY error (dberr %d (severity %d): \"%s\"; oserr %d: \"%s\")\n",
++		dberr, severity, dberrstr ? dberrstr : "(null)", oserr, oserrstr ? oserrstr : "(null)");
+ 	fflush(stderr);
+ 
+ 	/*
+@@ -373,6 +382,10 @@ syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *db
+ 		}
+ 	}
+ 
+-	assert(0); /* no unanticipated errors allowed in unit tests */
++	if (severity) {
++		fprintf(stderr, "error: no unanticipated errors allowed in unit tests\n");
++		exit(EXIT_FAILURE);
++	}
++
+ 	return INT_CANCEL;
+ }
+diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h
+index 35d57a8..67b72db 100644
+--- a/src/dblib/unittests/common.h
++++ b/src/dblib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.14 2007/12/20 21:57:35 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.15 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #if HAVE_CONFIG_H
+@@ -28,6 +28,15 @@ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_wa
+ #include <sqlfront.h>
+ #include <sqldb.h>
+ 
++#if !defined(FREETDS_SRCDIR)
++#define FREETDS_SRCDIR "../../../.."
++#endif
++
++#if !defined(EXIT_FAILURE)
++#define EXIT_FAILURE 1
++#define EXIT_SUCCESS 0
++#endif
++
+ #ifdef DBNTWIN32
+ /*
+  * Define Sybase's symbols in terms of Microsoft's. 
+diff --git a/src/dblib/unittests/dbmorecmds.c b/src/dblib/unittests/dbmorecmds.c
+index fbc0bd7..c5b76f2 100644
+--- a/src/dblib/unittests/dbmorecmds.c
++++ b/src/dblib/unittests/dbmorecmds.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: dbmorecmds.c,v 1.12 2006/07/06 12:48:16 freddy77 Exp $";
++static char software_version[] = "$Id: dbmorecmds.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version,	no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -22,7 +22,7 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/hang.c b/src/dblib/unittests/hang.c
+index 4d9606d..7b3c750 100644
+--- a/src/dblib/unittests/hang.c
++++ b/src/dblib/unittests/hang.c
+@@ -37,9 +37,11 @@
+ #include <sys/wait.h>
+ #endif /* HAVE_SYS_WAIT_H */
+ 
+-static char software_version[] = "$Id: hang.c,v 1.2 2007/06/04 12:15:57 freddy77 Exp $";
++static char software_version[] = "$Id: hang.c,v 1.3 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++char *UNITTEST;
++
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+ 
+ static int end_socket = -1;
+@@ -82,7 +84,7 @@ test(int close_socket)
+ 	RETCODE ret;
+ 	int expected_error = -1;
+ 
+-	printf("Start\n");
++	printf("Starting %s\n", UNITTEST);
+ 
+ 	dbinit();
+ 
+@@ -141,6 +143,7 @@ test(int close_socket)
+ int
+ main(int argc, char **argv)
+ {
++	UNITTEST = argv[0];
+ 	read_login_info(argc, argv);
+ 	if (test(0) || test(1))
+ 		return 1;
+diff --git a/src/dblib/unittests/null.c b/src/dblib/unittests/null.c
+index 3faf382..7563bec 100644
+--- a/src/dblib/unittests/null.c
++++ b/src/dblib/unittests/null.c
+@@ -7,7 +7,7 @@
+ 
+ #include <unistd.h>
+ 
+-static char software_version[] = "$Id: null.c,v 1.6 2007/12/14 10:23:38 freddy77 Exp $";
++static char software_version[] = "$Id: null.c,v 1.7 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static DBPROCESS *dbproc = NULL;
+@@ -140,7 +140,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 
+ 	dbinit();
+ 
+diff --git a/src/dblib/unittests/null2.c b/src/dblib/unittests/null2.c
+index 30e4849..b3b43f0 100644
+--- a/src/dblib/unittests/null2.c
++++ b/src/dblib/unittests/null2.c
+@@ -6,7 +6,7 @@
+ 
+ #include <unistd.h>
+ 
+-static char software_version[] = "$Id: null2.c,v 1.4 2007/12/14 10:23:38 freddy77 Exp $";
++static char software_version[] = "$Id: null2.c,v 1.5 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static DBPROCESS *dbproc = NULL;
+@@ -152,7 +152,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 
+ 	dbinit();
+ 
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index af41df7..bd14096 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.34 2008/07/15 09:53:01 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.35 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[4096];
+@@ -167,7 +167,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	dbinit();
+diff --git a/src/dblib/unittests/setnull.c b/src/dblib/unittests/setnull.c
+index 6da7092..c472667 100644
+--- a/src/dblib/unittests/setnull.c
++++ b/src/dblib/unittests/setnull.c
+@@ -5,7 +5,7 @@
+ #include "common.h"
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: setnull.c,v 1.8 2007/12/20 21:57:35 freddy77 Exp $";
++static char software_version[] = "$Id: setnull.c,v 1.9 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -76,7 +76,7 @@ main(int argc, char **argv)
+ 	
+ 	read_login_info(argc, argv);
+ 
+-	printf("Start\n");
++	printf("Starting %s\n", argv[0]);
+ 	dbinit();
+ 
+ 	dberrhandle(syb_err_handler);
+diff --git a/src/dblib/unittests/t0001.c b/src/dblib/unittests/t0001.c
+index b1c8db3..9d592b5 100644
+--- a/src/dblib/unittests/t0001.c
++++ b/src/dblib/unittests/t0001.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.26 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.27 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -26,10 +26,12 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	argc -= optind;
+-	argv += optind;
++	if (argc > 1) {
++		argc -= optind;
++		argv += optind;
++	}
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0002.c b/src/dblib/unittests/t0002.c
+index 6b80a1a..e5a3474 100644
+--- a/src/dblib/unittests/t0002.c
++++ b/src/dblib/unittests/t0002.c
+@@ -10,7 +10,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.21 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.22 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -57,7 +57,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0003.c b/src/dblib/unittests/t0003.c
+index 5acb059..98b444d 100644
+--- a/src/dblib/unittests/t0003.c
++++ b/src/dblib/unittests/t0003.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.13 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.14 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -28,7 +28,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c
+index 33f95cb..ea06e9e 100644
+--- a/src/dblib/unittests/t0004.c
++++ b/src/dblib/unittests/t0004.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.16 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.17 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -27,7 +27,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	dbinit();
+diff --git a/src/dblib/unittests/t0005.c b/src/dblib/unittests/t0005.c
+index c5d9d1a..8c24410 100644
+--- a/src/dblib/unittests/t0005.c
++++ b/src/dblib/unittests/t0005.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0005.c,v 1.23 2008/11/12 00:47:31 jklowden Exp $";
++static char software_version[] = "$Id: t0005.c,v 1.24 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -24,7 +24,7 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 
+diff --git a/src/dblib/unittests/t0006.c b/src/dblib/unittests/t0006.c
+index ed62817..019c177 100644
+--- a/src/dblib/unittests/t0006.c
++++ b/src/dblib/unittests/t0006.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0006.c,v 1.16 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0006.c,v 1.17 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -54,7 +54,7 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0007.c b/src/dblib/unittests/t0007.c
+index 6061a3b..f82cc7e 100644
+--- a/src/dblib/unittests/t0007.c
++++ b/src/dblib/unittests/t0007.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0007.c,v 1.17 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.18 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -81,7 +81,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	dbinit();
+diff --git a/src/dblib/unittests/t0008.c b/src/dblib/unittests/t0008.c
+index d212e69..d81caab 100644
+--- a/src/dblib/unittests/t0008.c
++++ b/src/dblib/unittests/t0008.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0008.c,v 1.16 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0008.c,v 1.17 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -25,7 +25,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0009.c b/src/dblib/unittests/t0009.c
+index e96531d..22f1cd4 100644
+--- a/src/dblib/unittests/t0009.c
++++ b/src/dblib/unittests/t0009.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0009.c,v 1.14 2006/07/06 12:48:16 freddy77 Exp $";
++static char software_version[] = "$Id: t0009.c,v 1.15 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -23,7 +23,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0011.c b/src/dblib/unittests/t0011.c
+index 3b31edb..7d0996a 100644
+--- a/src/dblib/unittests/t0011.c
++++ b/src/dblib/unittests/t0011.c
+@@ -6,7 +6,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0011.c,v 1.12 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0011.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -24,7 +24,7 @@ main(int argc, char **argv)
+ 	char cmd[2048];
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 
+ 	dbinit();
+ 
+diff --git a/src/dblib/unittests/t0012.c b/src/dblib/unittests/t0012.c
+index be5c34b..3fe88fa 100644
+--- a/src/dblib/unittests/t0012.c
++++ b/src/dblib/unittests/t0012.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0012.c,v 1.21 2007/01/15 02:00:58 jklowden Exp $";
++static char software_version[] = "$Id: t0012.c,v 1.22 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int failed = 0;
+ 
+@@ -24,7 +24,7 @@ main(int argc, char *argv[])
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	dbinit();
+ 
+ 	dberrhandle(syb_err_handler);
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index 081bdb7..ba4fbc2 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,26 +5,52 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.24 2008/11/12 10:38:15 freddy77 Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.25 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+ 
+ int failed = 0;
+ 
++#if !defined(FREETDS_SRCDIR)
++#define FREETDS_SRCDIR "../../../.."
++#endif
++
++#define TABLE_NAME "freetds_dblib_t0013"
++
+ char *testargs[] = { "", FREETDS_SRCDIR "/data.bin", "t0013.out" };
+ 
++DBPROCESS *dbproc, *dbprocw;
++
++void
++drop_table(void)
++{
++	char cmd[1024];
++
++	if (!dbproc) 
++		return;
++
++	dbcancel(dbproc);
++
++	sprintf(cmd, "drop table " TABLE_NAME);
++	fprintf(stdout, "sql: %s\n", cmd);
++	dbcmd(dbproc, cmd);
++	dbsqlexec(dbproc);
++	while (dbresults(dbproc) != NO_MORE_RESULTS) {
++		/* nop */
++	}
++}
++
+ int
+ main(int argc, char **argv)
+ {
+ 	LOGINREC *login;
+-	DBPROCESS *dbproc;
+ 	int i;
+ 	DBINT testint;
+ 	FILE *fp;
+ 	long result, isiz;
+ 	char *blob, *rblob;
+-	unsigned char *textPtr = NULL, *timeStamp = NULL;
++	DBBINARY *textPtr = NULL, *timeStamp = NULL;
+ 	char objname[256];
+ 	char sqlCmd[256];
+ 	char rbuf[BLOB_BLOCK_SIZE];
+@@ -32,11 +58,13 @@ main(int argc, char **argv)
+ 	BOOL readFirstImage;
+ 	char cmd[1024];
+ 	int data_ok;
+-
++#ifdef DBWRITE_OK_FOR_OVER_4K
++	int numtowrite, numwritten;
++#endif
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	dbinit();
+ 
+ 	dberrhandle(syb_err_handler);
+@@ -52,13 +80,13 @@ main(int argc, char **argv)
+ 	fprintf(stdout, "About to open, PASSWORD: %s, USER: %s, SERVER: %s\n", "", "", "");	/* PASSWORD, USER, SERVER); */
+ 
+ 	dbproc = dbopen(login, SERVER);
++	dbprocw = dbopen(login, SERVER);
+ 	if (strlen(DATABASE)) {
+ 		dbuse(dbproc, DATABASE);
++		dbuse(dbprocw, DATABASE);
+ 	}
+-	dbloginfree(login);
+-	fprintf(stdout, "After logon\n");
+-
+-	fprintf(stdout, "About to read binary input file\n");
++	// dbloginfree(login);
++	fprintf(stdout, "logged in\n");
+ 
+ 	if (argc == 1) {
+ 		argv = testargs;
+@@ -73,33 +101,37 @@ main(int argc, char **argv)
+ 		fprintf(stderr, "Cannot open input file: %s\n", argv[1]);
+ 		return 2;
+ 	}
++	fprintf(stdout, "Reading binary input file\n");
++
+ 	fseek(fp, 0, SEEK_END);
+ 	isiz = ftell(fp);
+ 	fseek(fp, 0, SEEK_SET);
+ 
+-	blob = (char *) malloc(isiz);
++	blob = malloc(isiz);
++	assert(blob);
+ 	fread((void *) blob, isiz, 1, fp);
+ 	fclose(fp);
+ 
+-	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0013 (i int not null, PigTure image not null)");
++	sprintf(cmd, "create table " TABLE_NAME " (i int not null, PigTure image not null)");
++	fprintf(stdout, "sql: %s\n", cmd);
++	dbcmd(dbproc, cmd);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
++	atexit(drop_table);
+ 
+-	fprintf(stdout, "insert\n");
+-
+-	sprintf(cmd, "insert into #dblib0013 values (1, '')");
+-	fprintf(stdout, "%s\n", cmd);
++	sprintf(cmd, "insert into " TABLE_NAME " values (1, '')");
++	fprintf(stdout, "sql: %s\n", cmd);
+ 	dbcmd(dbproc, cmd);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+-	sprintf(sqlCmd, "SELECT PigTure FROM #dblib0013 WHERE i = 1");
++	sprintf(sqlCmd, "SELECT PigTure FROM " TABLE_NAME " WHERE i = 1");
++	fprintf(stdout, "sql: %s\n", sqlCmd);
+ 	dbcmd(dbproc, sqlCmd);
+ 	dbsqlexec(dbproc);
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -107,40 +139,69 @@ main(int argc, char **argv)
+ 		return 4;
+ 	}
+ 
+-	while ((result = dbnextrow(dbproc)) != NO_MORE_ROWS) {
+-		strcpy(objname, "#dblib0013.PigTure");
++	for (i=0; (result = dbnextrow(dbproc)) != NO_MORE_ROWS; i++) {
++		assert(REG_ROW == result);
++		printf("fetching row %d\n", i+1);
++		strcpy(objname, TABLE_NAME ".PigTure");
+ 		textPtr = dbtxptr(dbproc, 1);
+ 		timeStamp = dbtxtimestamp(dbproc, 1);
++		break; /* can't proceed until no more rows */
+ 	}
++	assert(REG_ROW == result || 0 < i);
++	assert(0 < textPtr);
+ 
+ 	/*
+ 	 * Use #ifdef if you want to test dbmoretext mode (needed for 16-bit apps)
+ 	 * Use #ifndef for big buffer version (32-bit)
+ 	 */
++	fprintf(stdout, "writing text ... ");
+ #ifndef DBWRITE_OK_FOR_OVER_4K
+-	if (dbwritetext(dbproc, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, (BYTE*) blob) != SUCCEED)
++	if (dbwritetext(dbprocw, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, (BYTE*) blob) != SUCCEED)
+ 		return 5;
++	fprintf(stdout, "done (in one shot)\n");
++	for (; (result = dbnextrow(dbproc)) != NO_MORE_ROWS; i++) {
++		assert(REG_ROW == result);
++		printf("fetching row %d?\n", i+1);
++	}
+ #else
+-	if (dbwritetext(dbproc, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, NULL) != SUCCEED)
++	if (dbwritetext(dbprocw, objname, textPtr, DBTXPLEN, timeStamp, FALSE, isiz, NULL) != SUCCEED)
+ 		return 15;
+-	dbsqlok(dbproc);
+-	dbresults(dbproc);
++	fprintf(stdout, "done\n");
++
++	fprintf(stdout, "dbsqlok\n");
++	dbsqlok(dbprocw);
++	fprintf(stdout, "dbresults\n");
++	dbresults(dbprocw);
+ 
+ 	numtowrite = 0;
+ 	/* Send the update value in chunks. */
+ 	for (numwritten = 0; numwritten < isiz; numwritten += numtowrite) {
++		fprintf(stdout, "dbmoretext %d\n", 1 + numwritten);
+ 		numtowrite = (isiz - numwritten);
+ 		if (numtowrite > BLOB_BLOCK_SIZE)
+ 			numtowrite = BLOB_BLOCK_SIZE;
+-		dbmoretext(dbproc, (DBINT) numtowrite, blob + numwritten);
++		dbmoretext(dbprocw, (DBINT) numtowrite, blob + numwritten);
++	}
++	dbsqlok(dbprocw);
++	while (dbresults(dbprocw) != NO_MORE_RESULTS){
++		printf("suprise!\n");
+ 	}
+-	dbsqlok(dbproc);
+-	while (dbresults(dbproc) != NO_MORE_RESULTS);
+ #endif
++#if 0
++	if (SUCCEED != dbclose(dbproc)){
++		fprintf(stdout, "dbclose failed");
++		exit(1);
++	}
++	dbproc = dbopen(login, SERVER);
++	assert(dbproc);
++	if (strlen(DATABASE)) {
++		dbuse(dbproc, DATABASE);
++	}
++#endif
++	sprintf(cmd, "select i, PigTure from " TABLE_NAME " order by i");
+ 
+-	fprintf(stdout, "select\n");
+-
+-	dbcmd(dbproc, "select * from #dblib0013 order by i");
++	fprintf(stdout, "sql: %s\n", cmd);
++	dbcmd(dbproc, cmd);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -150,36 +211,41 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	for (i = 1; i <= dbnumcols(dbproc); i++) {
+-		printf("col %d is %s\n", i, dbcolname(dbproc, i));
++		printf("col %d, \"%s\", is type %s\n", 
++			i, dbcolname(dbproc, i), dbprtype(dbcoltype(dbproc, i)));
++	}
++	if (2 != dbnumcols(dbproc)) {
++		fprintf(stderr, "Failed.  Expected 2 columns\n");
++		exit(1);
+ 	}
+ 
+ 	if (SUCCEED != dbbind(dbproc, 1, INTBIND, -1, (BYTE *) & testint)) {
+-		failed = 1;
+ 		fprintf(stderr, "Had problem with bind\n");
+-		abort();
++		exit(1);
+ 	}
+ 
+ 	if (REG_ROW != dbnextrow(dbproc)) {
+-		failed = 1;
+ 		fprintf(stderr, "Failed.  Expected a row\n");
+ 		exit(1);
+ 	}
+ 	if (testint != 1) {
+ 		failed = 1;
+-		fprintf(stderr, "Failed.  Expected i to be %d, was %d\n", i, (int) testint);
+-		abort();
++		fprintf(stderr, "Failed.  Expected i to be %d, was %d\n", 1, (int) testint);
++		exit(1);
+ 	}
+ 	dbnextrow(dbproc);
+ 
+ 	/* get the image */
+ 	strcpy(sqlCmd, "SET TEXTSIZE 2147483647");
++	fprintf(stdout, "sql: %s\n", sqlCmd);
+ 	dbcmd(dbproc, sqlCmd);
+ 	dbsqlexec(dbproc);
+ 	dbresults(dbproc);
+ 
+ 	fprintf(stdout, "select 2\n");
+ 
+-	sprintf(sqlCmd, "SELECT PigTure FROM #dblib0013 WHERE i = 1");
++	sprintf(sqlCmd, "SELECT PigTure FROM " TABLE_NAME " WHERE i = 1");
++	fprintf(stdout, "sql: %s\n", sqlCmd);
+ 	dbcmd(dbproc, sqlCmd);
+ 	dbsqlexec(dbproc);
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -224,6 +290,17 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	free(blob);
++	drop_table();
++#if 1
++	dbclose(dbproc);
++#else
++	if (SUCCEED != dbclose(dbproc)){
++		fprintf(stdout, "dbclose failed");
++		abort();
++	}
++#endif
++	dbproc = 0;
++
+ 	dbexit();
+ 
+ 	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
+diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c
+index d88dcd7..96ca83e 100644
+--- a/src/dblib/unittests/t0014.c
++++ b/src/dblib/unittests/t0014.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0014.c,v 1.27 2006/07/06 12:48:16 freddy77 Exp $";
++static char software_version[] = "$Id: t0014.c,v 1.28 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -36,7 +36,7 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	dbinit();
+ 
+ 	dberrhandle(syb_err_handler);
+diff --git a/src/dblib/unittests/t0015.c b/src/dblib/unittests/t0015.c
+index 02ea29c..ba8a3b8 100644
+--- a/src/dblib/unittests/t0015.c
++++ b/src/dblib/unittests/t0015.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0015.c,v 1.17 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0015.c,v 1.18 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -26,7 +26,7 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0016.c b/src/dblib/unittests/t0016.c
+index 9abc89d..5c966bd 100644
+--- a/src/dblib/unittests/t0016.c
++++ b/src/dblib/unittests/t0016.c
+@@ -4,8 +4,9 @@
+  */
+ 
+ #include "common.h"
++#include <sys/stat.h>
+ 
+-static char software_version[] = "$Id: t0016.c,v 1.26 2006/12/26 14:56:19 freddy77 Exp $";
++static char software_version[] = "$Id: t0016.c,v 1.27 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -22,6 +23,9 @@ failure(const char *fmt, ...)
+         va_end(ap);
+ }
+ 
++#define INFILE_NAME "t0016.in"
++#define TABLE_NAME "#dblib0016"
++
+ int
+ main(int argc, char *argv[])
+ {
+@@ -31,20 +35,32 @@ main(int argc, char *argv[])
+ 	char sqlCmd[256];
+ 	RETCODE ret;
+ 	const char *out_file = "t0016.out";
+-	const char *in_file = FREETDS_SRCDIR "/t0016.in";
++	const char *in_file = FREETDS_SRCDIR "/" INFILE_NAME;
+ 	const char *err_file = "t0016.err";
+ 	DBINT rows_copied;
+ 	int num_cols = 0;
+ 
+ 	FILE *input_file, *output_file;
+ 
++#if 1
++	struct stat sb;
++
++	if (0 != stat(in_file, &sb)) {
++		in_file = INFILE_NAME;
++		if (0 != stat(in_file, &sb)) {
++			perror("could not open " INFILE_NAME);
++			exit(1);
++		}
++	}
++#endif
++
+ 	setbuf(stdout, NULL);
+ 	setbuf(stderr, NULL);
+ 
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	printf("Start\n");
++	printf("Starting %s\n", argv[0]);
+ 	dbinit();
+ 
+ 	dberrhandle(syb_err_handler);
+@@ -65,7 +81,7 @@ main(int argc, char *argv[])
+ 	dbloginfree(login);
+ 	printf("After logon\n");
+ 
+-	printf("Creating table\n");
++	printf("Creating table '%s'\n", TABLE_NAME);
+ 	strcpy(sqlCmd, "create table #dblib0016 (f1 int not null, s1 int null, f2 numeric(10,2) null, ");
+ 	strcat(sqlCmd, "f3 varchar(255) not null, f4 datetime null) ");
+ 	dbcmd(dbproc, sqlCmd);
+@@ -76,7 +92,8 @@ main(int argc, char *argv[])
+ 
+ 	/* BCP in */
+ 
+-	ret = bcp_init(dbproc, "#dblib0016", in_file, err_file, DB_IN);
++	printf("bcp_init with in_file as '%s'\n", in_file);
++	ret = bcp_init(dbproc, TABLE_NAME, in_file, err_file, DB_IN);
+ 	if (ret != SUCCEED)
+ 		failure("bcp_init failed\n");
+ 
+@@ -119,7 +136,7 @@ main(int argc, char *argv[])
+ 	/* BCP out */
+ 
+ 	rows_copied = 0;
+-	ret = bcp_init(dbproc, "#dblib0016", out_file, err_file, DB_OUT);
++	ret = bcp_init(dbproc, TABLE_NAME, out_file, err_file, DB_OUT);
+ 	if (ret != SUCCEED)
+ 		failure("bcp_int failed\n");
+ 
+diff --git a/src/dblib/unittests/t0018.c b/src/dblib/unittests/t0018.c
+index 5dca4f9..8b5bd82 100644
+--- a/src/dblib/unittests/t0018.c
++++ b/src/dblib/unittests/t0018.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0018.c,v 1.18 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0018.c,v 1.19 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -26,7 +26,7 @@ main(int argc, char **argv)
+ 	set_malloc_options();
+ 
+ 	read_login_info(argc, argv);
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0020.c b/src/dblib/unittests/t0020.c
+index 90cc765..aa8b4b9 100644
+--- a/src/dblib/unittests/t0020.c
++++ b/src/dblib/unittests/t0020.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0020.c,v 1.15 2007/01/15 19:43:09 jklowden Exp $";
++static char software_version[] = "$Id: t0020.c,v 1.16 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -38,7 +38,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/t0021.c b/src/dblib/unittests/t0021.c
+index 06f3701..2d0c8d6 100644
+--- a/src/dblib/unittests/t0021.c
++++ b/src/dblib/unittests/t0021.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0021.c,v 1.12 2006/07/06 12:48:16 freddy77 Exp $";
++static char software_version[] = "$Id: t0021.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -26,7 +26,7 @@ main(int argc, char **argv)
+ 
+ 	set_malloc_options();
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 
+ 	/* Fortify_EnterScope(); */
+ 	dbinit();
+diff --git a/src/dblib/unittests/t0022.c b/src/dblib/unittests/t0022.c
+index 9f4b378..09eaf80 100644
+--- a/src/dblib/unittests/t0022.c
++++ b/src/dblib/unittests/t0022.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0022.c,v 1.24 2007/11/27 12:38:11 freddy77 Exp $";
++static char software_version[] = "$Id: t0022.c,v 1.25 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -27,7 +27,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	dbinit();
+diff --git a/src/dblib/unittests/t0023.c b/src/dblib/unittests/t0023.c
+index 8e39262..9d57529 100644
+--- a/src/dblib/unittests/t0023.c
++++ b/src/dblib/unittests/t0023.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0023.c,v 1.12 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: t0023.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -31,7 +31,7 @@ main(int argc, char *argv[])
+ 	set_malloc_options();
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/text_buffer.c b/src/dblib/unittests/text_buffer.c
+index 7a7b607..2af70a9 100644
+--- a/src/dblib/unittests/text_buffer.c
++++ b/src/dblib/unittests/text_buffer.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: text_buffer.c,v 1.3 2007/12/04 02:06:38 jklowden Exp $";
++static char software_version[] = "$Id: text_buffer.c,v 1.4 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -22,7 +22,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	/* Fortify_EnterScope(); */
+diff --git a/src/dblib/unittests/thread.c b/src/dblib/unittests/thread.c
+index d09afe0..5e0d4b5 100644
+--- a/src/dblib/unittests/thread.c
++++ b/src/dblib/unittests/thread.c
+@@ -8,7 +8,7 @@
+ #include <unistd.h>
+ #include <pthread.h>
+ 
+-static char software_version[] = "$Id: thread.c,v 1.12 2007/12/20 21:57:35 freddy77 Exp $";
++static char software_version[] = "$Id: thread.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+@@ -149,7 +149,7 @@ main(int argc, char **argv)
+ 
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 
+ 	dbinit();
+ 
+diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c
+index 7de6013..ea897ee 100644
+--- a/src/dblib/unittests/timeout.c
++++ b/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.4 2008/01/20 14:23:59 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.5 2008/11/25 22:58:29 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+@@ -18,6 +18,12 @@ int timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr,
+ int chkintr(DBPROCESS * dbproc);
+ int hndlintr(DBPROCESS * dbproc);
+ 
++#if !defined(SYBETIME)
++#define SYBETIME SQLETIME
++#define INT_TIMEOUT INT_CANCEL
++dbsetinterrupt(DBPROCESS *dbproc, void* hand, void* p) {}
++#endif
++
+ int
+ timeout_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
+ {
+@@ -101,7 +107,7 @@ main(int argc, char **argv)
+ 	
+ 	read_login_info(argc, argv);
+ 
+-	fprintf(stdout, "Start\n");
++	fprintf(stdout, "Starting %s\n", argv[0]);
+ 	add_bread_crumb();
+ 
+ 	dbinit();
+diff --git a/win32/tds_sysdep_public.h b/win32/tds_sysdep_public.h
+index d86e324..cc65242 100644
+--- a/win32/tds_sysdep_public.h
++++ b/win32/tds_sysdep_public.h
+@@ -1,58 +1,59 @@
+-/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
+- *
+- * This library is free software; you can redistribute it and/or
+- * modify it under the terms of the GNU Library General Public
+- * License as published by the Free Software Foundation; either
+- * version 2 of the License, or (at your option) any later version.
+- *
+- * This library is distributed in the hope that it will be useful,
+- * but WITHOUT ANY WARRANTY; without even the implied warranty of
+- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+- * Library General Public License for more details.
+- *
+- * You should have received a copy of the GNU Library General Public
+- * License along with this library; if not, write to the
+- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+- * Boston, MA 02111-1307, USA.
+- */
+-
+-#ifndef _tds_sysdep_public_h_
+-#define _tds_sysdep_public_h_
+-
+-static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.6 2008/01/20 14:23:59 freddy77 Exp $";
+-static void *no_unused_tds_sysdep_public_h_warn[] = { rcsid_tds_sysdep_public_h, no_unused_tds_sysdep_public_h_warn };
+-
+-#ifdef __cplusplus
+-extern "C"
+-{
+-#endif
+-
+-#include <windows.h>
+-#define tds_sysdep_int16_type short	/* 16-bit int */
+-#define tds_sysdep_int32_type int	/* 32-bit int */
+-#define tds_sysdep_int64_type __int64	/* 64-bit int */
+-#define tds_sysdep_real32_type float	/* 32-bit real */
+-#define tds_sysdep_real64_type double	/* 64-bit real */
+-#if !defined(WIN64) && !defined(_WIN64)
+-#define tds_sysdep_intptr_type int	/* 32-bit int */
+-#else
+-#define tds_sysdep_intptr_type __int64	/* 64-bit int */
+-#endif
+-typedef SOCKET TDS_SYS_SOCKET;
+-#ifndef TDS_IS_SOCKET_INVALID
+-#define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
+-#endif
+-
+-#if !defined(MSDBLIB) && !defined(SYBDBLIB)
+-#define SYBDBLIB 1
+-#endif
+-#if defined(MSDBLIB) && defined(SYBDBLIB)
+-#error MSDBLIB and SYBDBLIB cannot both be defined
+-#endif
+-
+-#ifdef __cplusplus
+-}
+-#endif
+-
+-#endif				/* _tds_sysdep_public_h_ */
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#ifndef _tds_sysdep_public_h_
++#define _tds_sysdep_public_h_
++
++static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.7 2008/11/25 22:58:29 jklowden Exp $";
++static void *no_unused_tds_sysdep_public_h_warn[] = { rcsid_tds_sysdep_public_h, no_unused_tds_sysdep_public_h_warn };
++
++#ifdef __cplusplus
++extern "C"
++{
++#endif
++
++#include <windows.h>
++#include <winsock2.h>
++#define tds_sysdep_int16_type short	/* 16-bit int */
++#define tds_sysdep_int32_type int	/* 32-bit int */
++#define tds_sysdep_int64_type __int64	/* 64-bit int */
++#define tds_sysdep_real32_type float	/* 32-bit real */
++#define tds_sysdep_real64_type double	/* 64-bit real */
++#if !defined(WIN64) && !defined(_WIN64)
++#define tds_sysdep_intptr_type int	/* 32-bit int */
++#else
++#define tds_sysdep_intptr_type __int64	/* 64-bit int */
++#endif
++typedef SOCKET TDS_SYS_SOCKET;
++#ifndef TDS_IS_SOCKET_INVALID
++#define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
++#endif
++
++#if !defined(MSDBLIB) && !defined(SYBDBLIB)
++#define SYBDBLIB 1
++#endif
++#if defined(MSDBLIB) && defined(SYBDBLIB)
++#error MSDBLIB and SYBDBLIB cannot both be defined
++#endif
++
++#ifdef __cplusplus
++}
++#endif
++
++#endif				/* _tds_sysdep_public_h_ */
+
+commit 1e84a2ba308bf4c9f5d6343ca0fa6c8a661f90f4
+Author: jklowden <jklowden>
+Date:   Tue Nov 25 23:38:33 2008 +0000
+
+    added link to jtds for ODBC stored procedures
+
+diff --git a/doc/tds.html b/doc/tds.html
+index 7e5db61..be53f5a 100644
+--- a/doc/tds.html
++++ b/doc/tds.html
+@@ -32,6 +32,7 @@ This document attempts to cover the TDS protocol for:
+ <li><a href="#collate">Collation structure</a>
+ <li><a href="#requests">Client requests</a>
+ <li><a href="#responses">Server Responses</a>
++<li><a href="http://jtds.sourceforge.net/apiCursors.html">OCBC stored procedures (by jtds)</a>
+ </ul>
+ 
+ <h2 class="section">Common Terms</h2>
+@@ -1530,7 +1531,7 @@ The following people have contributed to this document:
+ (short list)
+ 
+ <h2>Document Status </h2>
+-<P>$Id: tds.html,v 1.40 2008/07/31 16:40:32 freddy77 Exp $</p>
++<P>$Id: tds.html,v 1.41 2008/11/25 23:38:33 jklowden Exp $</p>
+ <p>
+     <a href="http://validator.w3.org/check?uri=referer"><img
+         src="http://www.w3.org/Icons/valid-html401"
+
+commit 7b53374ee6112f2ab84ef6ed072941a01e21a8d3
+Author: freddy77 <freddy77>
+Date:   Mon Dec 1 09:59:35 2008 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index afbe251..fdf99a5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Dec 01 10:58:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0013.c: remove warning
++
+ Mon Nov 17 19:46:34 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c 
+ 	* src/dblib/bcp.c src/dblib/unittests/bcp.c
+@@ -976,4 +979,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2665 2008/11/25 22:58:28 jklowden Exp $
++$Id: ChangeLog,v 1.2666 2008/12/01 09:59:35 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index ba4fbc2..42f8d92 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.25 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.26 2008/12/01 09:59:35 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -22,7 +22,7 @@ char *testargs[] = { "", FREETDS_SRCDIR "/data.bin", "t0013.out" };
+ 
+ DBPROCESS *dbproc, *dbprocw;
+ 
+-void
++static void
+ drop_table(void)
+ {
+ 	char cmd[1024];
+
+commit 5e2ecb35ce1c8398adebcd28c810d52e714ef0e4
+Author: freddy77 <freddy77>
+Date:   Tue Dec 2 10:54:37 2008 +0000
+
+    avoid memory leak
+
+diff --git a/ChangeLog b/ChangeLog
+index fdf99a5..8839590 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Dec 02 11:53:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0013.c: avoid leak
++
+ Mon Dec 01 10:58:04 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0013.c: remove warning
+ 
+@@ -979,4 +982,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2666 2008/12/01 09:59:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2667 2008/12/02 10:54:37 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index 42f8d92..c3044a7 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.26 2008/12/01 09:59:35 freddy77 Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.27 2008/12/02 10:54:38 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -85,7 +85,7 @@ main(int argc, char **argv)
+ 		dbuse(dbproc, DATABASE);
+ 		dbuse(dbprocw, DATABASE);
+ 	}
+-	// dbloginfree(login);
++	dbloginfree(login);
+ 	fprintf(stdout, "logged in\n");
+ 
+ 	if (argc == 1) {
+
+commit fc95eef85318824e0590255bb62d67433ea6e86e
+Author: freddy77 <freddy77>
+Date:   Wed Dec 3 08:37:10 2008 +0000
+
+    improve lookup routines
+
+diff --git a/ChangeLog b/ChangeLog
+index 8839590..33a643e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Dec 03 09:35:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/cs.c src/dblib/dblib.c: avoid possible buffer overflow
++	* src/dblib/dbutil.c: make message const
++	* src/odbc/odbc.c: make odbc_prret thread safe
++
+ Tue Dec 02 11:53:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0013.c: avoid leak
+ 
+@@ -982,4 +987,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2667 2008/12/02 10:54:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2668 2008/12/03 08:37:10 freddy77 Exp $
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index a759a52..fd5fa07 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.67 2008/08/26 14:14:33 freddy77 Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.68 2008/12/03 08:37:11 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -61,7 +61,7 @@ static CS_INT cs_diag_countmsg(CS_CONTEXT *context, CS_INT *count);
+ const char *
+ cs_prretcode(int retcode)
+ {
+-	static char unknown[12]="oops: ";
++	static char unknown[24];
+ 	
+ 	switch(retcode) {
+ 	case CS_SUCCEED:	return "CS_SUCCEED";
+@@ -86,7 +86,7 @@ cs_prretcode(int retcode)
+ 	case CS_TIMED_OUT:	return "CS_TIMED_OUT";
+ 
+ 	default:
+-		sprintf(unknown + 6, "%u ??", retcode);
++		sprintf(unknown, "oops: %u ??", retcode);
+ 	}
+ 	return unknown;
+ }
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index f23ac5d..655f28a 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.331 2008/11/18 01:16:49 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.332 2008/12/03 08:37:11 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1481,7 +1481,7 @@ dbexit()
+ static const char *
+ prdbresults_state(int retcode)
+ {
+-	static char unknown[12]="oops: ";
++	static char unknown[24];
+ 	switch(retcode) {
+ 	case _DB_RES_INIT:		return "_DB_RES_INIT";
+ 	case _DB_RES_RESULTSET_EMPTY:	return "_DB_RES_RESULTSET_EMPTY";
+@@ -1490,7 +1490,7 @@ prdbresults_state(int retcode)
+ 	case _DB_RES_NO_MORE_RESULTS:	return "_DB_RES_NO_MORE_RESULTS";
+ 	case _DB_RES_SUCCEED:		return "_DB_RES_SUCCEED";
+ 	default:
+-		sprintf(unknown + 6, "%u ??", retcode);
++		sprintf(unknown, "oops: %u ??", retcode);
+ 	}
+ 	return unknown;
+ }
+@@ -1498,7 +1498,7 @@ prdbresults_state(int retcode)
+ static const char *
+ prdbretcode(int retcode)
+ {
+-	static char unknown[12]="oops: ";
++	static char unknown[24];
+ 	switch(retcode) {
+ 	case REG_ROW:		return "REG_ROW/MORE_ROWS";
+ 	case NO_MORE_ROWS:	return "NO_MORE_ROWS";
+@@ -1507,7 +1507,7 @@ prdbretcode(int retcode)
+ 	case SUCCEED:		return "SUCCEED";
+ 	case FAIL:		return "FAIL";
+ 	default:
+-		sprintf(unknown + 6, "%u ??", retcode);
++		sprintf(unknown, "oops: %u ??", retcode);
+ 	}
+ 	return unknown;
+ }
+@@ -1515,14 +1515,14 @@ prdbretcode(int retcode)
+ static const char *
+ prretcode(int retcode)
+ {
+-	static char unknown[12]="oops";
++	static char unknown[24];
+ 	switch(retcode) {
+ 	case TDS_SUCCEED:		return "TDS_SUCCEED";
+ 	case TDS_FAIL:			return "TDS_FAIL";
+ 	case TDS_NO_MORE_RESULTS:	return "TDS_NO_MORE_RESULTS";
+ 	case TDS_CANCELLED:		return "TDS_CANCELLED";
+ 	default:
+-		sprintf(unknown, "%u ??", retcode);
++		sprintf(unknown, "oops: %u ??", retcode);
+ 	}
+ 	return unknown;
+ }
+@@ -1530,7 +1530,7 @@ prretcode(int retcode)
+ static const char *
+ prresult_type(int result_type)
+ {
+-	static char unknown[12]="oops";
++	static char unknown[24];
+ 	switch(result_type) {
+ 	case TDS_ROW_RESULT:		return "TDS_ROW_RESULT";
+ 	case TDS_PARAM_RESULT:		return "TDS_PARAM_RESULT";
+@@ -1548,7 +1548,7 @@ prresult_type(int result_type)
+ 	case TDS_DONEINPROC_RESULT:	return "TDS_DONEINPROC_RESULT";
+ 	case TDS_OTHERS_RESULT:		return "TDS_OTHERS_RESULT";
+ 	default:
+-		sprintf(unknown, "%u ??", result_type);
++		sprintf(unknown, "oops: %u ??", result_type);
+ 	}
+ 	return unknown;
+ }
+diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c
+index 92ad3f5..da87bf4 100644
+--- a/src/dblib/dbutil.c
++++ b/src/dblib/dbutil.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbutil.c,v 1.43 2008/08/17 07:44:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dbutil.c,v 1.44 2008/12/03 08:37:11 freddy77 Exp $");
+ 
+ /*
+  * test include consistency 
+@@ -105,8 +105,8 @@ _dblib_handle_info_message(const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, TDSMESSA
+ 		 * server messages with severity greater than 10.
+ 		 */
+ 		/* Cannot call dbperror() here because server messsage numbers (and text) are not in its lookup table. */
+-		static char message[] = "General SQL Server error: Check messages from the SQL Server";
+-		(*_dblib_err_handler)(dbproc, msg->severity, msg->msgno, 0, message, NULL);
++		static const char message[] = "General SQL Server error: Check messages from the SQL Server";
++		(*_dblib_err_handler)(dbproc, msg->severity, msg->msgno, 0, (char *) message, NULL);
+ 	}
+ 	return SUCCEED;
+ }
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 2ba97b9..b44ce5f 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.505 2008/11/05 19:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.506 2008/12/03 08:37:11 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -155,10 +155,8 @@ static void odbc_ird_check(TDS_STMT * stmt);
+  */
+ 
+ static char *
+-odbc_prret(SQLRETURN ret)
++odbc_prret(SQLRETURN ret, char *unknown)
+ {
+-	static char unknown[32];
+-	
+ 	switch (ret) {
+ 	case SQL_ERROR:			return "SQL_ERROR";
+ 	case SQL_INVALID_HANDLE:	return "SQL_INVALID_HANDLE";
+@@ -175,6 +173,8 @@ odbc_prret(SQLRETURN ret)
+ 
+ 	return unknown;
+ }
++#define ODBC_PRRET_BUF	char unknown_prret_buf[24]
++#define odbc_prret(ret) odbc_prret(ret, unknown_prret_buf)
+ 
+ static void
+ odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name)
+@@ -3315,6 +3315,7 @@ SQLExecDirect(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ SQLRETURN ODBC_API
+ SQLExecute(SQLHSTMT hstmt)
+ {
++	ODBC_PRRET_BUF;
+ 	SQLRETURN res;
+ 
+ 	INIT_HSTMT;
+@@ -5890,6 +5891,7 @@ _SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
+ SQLRETURN ODBC_API
+ SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
+ {
++	ODBC_PRRET_BUF;
+ 	SQLRETURN ret = _SQLParamData(hstmt, prgbValue);
+ 	
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLParamData returns %s\n", odbc_prret(ret));
+@@ -5900,6 +5902,7 @@ SQLParamData(SQLHSTMT hstmt, SQLPOINTER FAR * prgbValue)
+ SQLRETURN ODBC_API
+ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ {
++	ODBC_PRRET_BUF;
+ 	INIT_HSTMT;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLPutData(%p, %p, %i)\n", hstmt, rgbValue, (int)cbValue);
+
+commit e29a2b34bc469a997d2d34f8731fff541b039e3e
+Author: freddy77 <freddy77>
+Date:   Wed Dec 3 12:55:52 2008 +0000
+
+    remove global RetCode
+
+diff --git a/ChangeLog b/ChangeLog
+index 33a643e..b9e4922 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,19 @@
++Wed Dec 03 13:54:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array_out.c src/odbc/unittests/blob1.c:
++	* src/odbc/unittests/cancel.c src/odbc/unittests/common.c:
++	* src/odbc/unittests/common.h src/odbc/unittests/connect.c:
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor5.c:
++	* src/odbc/unittests/cursor7.c src/odbc/unittests/error.c:
++	* src/odbc/unittests/lang_error.c src/odbc/unittests/prepclose.c:
++	* src/odbc/unittests/print.c src/odbc/unittests/putdata.c:
++	* src/odbc/unittests/raiserror.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/timeout.c src/odbc/unittests/timeout4.c:
++	* src/odbc/unittests/transaction.c src/odbc/unittests/transaction2.c:
++	* src/odbc/unittests/typeinfo.c src/odbc/unittests/utf8.c:
++	* src/odbc/unittests/warning.c:
++	- remove global RetCode
++	- new Command2 macro, use it
++
+ Wed Dec 03 09:35:32 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/cs.c src/dblib/dblib.c: avoid possible buffer overflow
+ 	* src/dblib/dbutil.c: make message const
+@@ -987,4 +1003,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2668 2008/12/03 08:37:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2669 2008/12/03 12:55:52 freddy77 Exp $
+diff --git a/src/odbc/unittests/array_out.c b/src/odbc/unittests/array_out.c
+index 1c8c8d5..3c802b9 100644
+--- a/src/odbc/unittests/array_out.c
++++ b/src/odbc/unittests/array_out.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array_out.c,v 1.14 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: array_out.c,v 1.15 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -30,7 +30,6 @@ query_test(const char* expected, const char *expected_status)
+ 	int desc_len = trunc ? 4 : 51;
+ 	int rec_size = 0;
+ 	Record *rec = NULL;
+-	RETCODE RetCode;
+ 	char status[20];
+ 
+ 	assert(Statement != SQL_NULL_HSTMT);
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 5e1240e..1633264 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.13 2008/11/10 17:20:39 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.14 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define CHECK_RCODE(t,h,m) \
+@@ -86,7 +86,7 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ static int
+ readBlob(SQLUSMALLINT pos)
+ {
+-	SQLRETURN RetCode;
++	SQLRETURN rc;
+ 	char buf[4096];
+ 	SQLLEN len, total = 0;
+ 	int i = 0;
+@@ -95,8 +95,8 @@ readBlob(SQLUSMALLINT pos)
+ 	printf(">> readBlob field %d\n", pos);
+ 	while (1) {
+ 		i++;
+-		CHKGetData(pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len, "SINo");
+-		if (RetCode == SQL_NO_DATA || len <= 0)
++		rc = CHKGetData(pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len, "SINo");
++		if (rc == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		if (len > (SQLLEN) sizeof(buf))
+ 			len = (SQLLEN) sizeof(buf);
+@@ -114,13 +114,13 @@ readBlob(SQLUSMALLINT pos)
+ 	printf(">>   total bytes read = %d \n", (int) total);
+ 	if (total != 10000)
+ 		failed = 1;
+-	return RetCode;
++	return rc;
+ }
+ 
+ static int
+ readBlobAsChar(SQLUSMALLINT pos, int step)
+ {
+-	SQLRETURN RetCode = SQL_SUCCESS_WITH_INFO;
++	SQLRETURN rc = SQL_SUCCESS_WITH_INFO;
+ 	char buf[8192];
+ 	SQLLEN len, total = 0;
+ 	int i = 0;
+@@ -131,10 +131,10 @@ readBlobAsChar(SQLUSMALLINT pos, int step)
+ 	else bufsize = sizeof(buf);
+ 
+ 	printf(">> readBlobAsChar field %d\n", pos);
+-	while (RetCode == SQL_SUCCESS_WITH_INFO) {
++	while (rc == SQL_SUCCESS_WITH_INFO) {
+ 		i++;
+-		CHKGetData(pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
+-		if (RetCode == SQL_NO_DATA || len <= 0)
++		rc = CHKGetData(pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
++		if (rc == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		if (len > (SQLLEN) bufsize)
+ 			len = (SQLLEN) bufsize - 1;
+@@ -151,7 +151,7 @@ readBlobAsChar(SQLUSMALLINT pos, int step)
+ 	printf(">>   total bytes read = %d \n", (int) total);
+ 	if (total != 20000)
+ 		failed = 1;
+-	return RetCode;
++	return rc;
+ }
+ 
+ 
+@@ -208,15 +208,13 @@ main(int argc, char **argv)
+ 		
+ 
+ 		printf(">> insert... %d\n", i);
+-		CHKExecute("SINe");
++		RetCode = CHKExecute("SINe");
+ 		while (RetCode == SQL_NEED_DATA) {
+ 			char *p;
+ 
+-			CHKParamData((SQLPOINTER) & p, "SINe");
++			RetCode = CHKParamData((SQLPOINTER) & p, "SINe");
+ 			printf(">> SQLParamData: ptr = %p  RetCode = %d\n", (void *) p, RetCode);
+ 			if (RetCode == SQL_NEED_DATA) {
+-				SQLRETURN RetCode;
+-
+ 				if (p == buf3) {
+ 					fill_hex(buf3, NBYTES, 987, 25);
+ 					
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index b7c7ab0..239707d 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -45,8 +45,6 @@ exit_forced(int s)
+ static void
+ sigalrm_handler(int s)
+ {
+-	SQLRETURN RetCode;
+-
+ 	printf(">>>> SQLCancel() ...\n");
+ 	CHKCancel("S");
+ 	printf(">>>> ... SQLCancel done\n");
+@@ -58,8 +56,6 @@ sigalrm_handler(int s)
+ int
+ main(int argc, char **argv)
+ {
+-	SQLRETURN RetCode;
+-
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+@@ -74,7 +70,6 @@ main(int argc, char **argv)
+ 		Disconnect();
+ 		return 1;
+ 	}
+-	printf(">> ...  done RetCode = %d\n", RetCode);
+ 
+ 	ResetStatement();
+ 
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 897903b..fd4c3c0 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,13 +12,12 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.52 2008/11/11 08:40:17 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.53 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+ HDBC Connection;
+ HSTMT Statement;
+-SQLRETURN RetCode;
+ int use_odbc_version3 = 0;
+ void (*odbc_set_conn_attr)(void) = NULL;
+ 
+@@ -192,9 +191,6 @@ ReportODBCError(const char *errmsg, SQLSMALLINT handletype, SQLHANDLE handle, SQ
+ int
+ Connect(void)
+ {
+-
+-	SQLRETURN RetCode;
+-
+ 	char command[512];
+ 
+ 	if (read_login_info())
+@@ -321,7 +317,6 @@ void
+ CheckCols(int n, int line, const char * file)
+ {
+ 	SQLSMALLINT cols;
+-	SQLRETURN RetCode;
+ 
+ 	if (n < 0) {
+ 		CHKNumResultCols(&cols, "E");
+@@ -339,7 +334,6 @@ void
+ CheckRows(int n, int line, const char * file)
+ {
+ 	SQLLEN rows;
+-	SQLRETURN RetCode;
+ 
+ 	if (n < -1) {
+ 		CHKRowCount(&rows, "E");
+@@ -434,11 +428,10 @@ AllocHandleErrType(SQLSMALLINT type)
+ 	return 0;
+ }
+ 
+-#undef Command
+ SQLRETURN
+-Command(HSTMT stmt, const char *command, const char *file, int line)
++CommandProc(HSTMT stmt, const char *command, const char *file, int line, const char *res)
+ {
+ 	printf("%s\n", command);
+-	return CheckRes(file, line, SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS), SQL_HANDLE_STMT, stmt, "Command", "SNo");
++	return CheckRes(file, line, SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS), SQL_HANDLE_STMT, stmt, "Command", res);
+ }
+ 
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index a698ab6..35ed75c 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.27 2008/11/06 15:56:39 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.28 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -36,7 +36,6 @@ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_wa
+ extern HENV Environment;
+ extern HDBC Connection;
+ extern HSTMT Statement;
+-extern SQLRETURN RetCode;
+ extern int use_odbc_version3;
+ extern void (*odbc_set_conn_attr)(void);
+ 
+@@ -61,9 +60,9 @@ void CheckCursor(void);
+ 
+ SQLRETURN CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res);
+ #define CHKR(func, params, res) \
+-	CheckRes(__FILE__, __LINE__, (RetCode=(func params)), 0, 0, #func, res)
++	CheckRes(__FILE__, __LINE__, (func params), 0, 0, #func, res)
+ #define CHKR2(func, params, type, handle, res) \
+-	CheckRes(__FILE__, __LINE__, (RetCode=(func params)), type, handle, #func, res)
++	CheckRes(__FILE__, __LINE__, (func params), type, handle, #func, res)
+ 
+ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 
+@@ -144,8 +143,9 @@ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 
+ int Connect(void);
+ int Disconnect(void);
+-SQLRETURN Command(HSTMT stmt, const char *command, const char *file, int line);
+-#define Command(cmd) (RetCode=Command(Statement, cmd, __FILE__, __LINE__))
++SQLRETURN CommandProc(HSTMT stmt, const char *command, const char *file, int line, const char *res);
++#define Command(cmd) CommandProc(Statement, cmd, __FILE__, __LINE__, "SNo")
++#define Command2(cmd, res) CommandProc(Statement, cmd, __FILE__, __LINE__, res)
+ SQLRETURN CommandWithResult(HSTMT stmt, const char *command);
+ int db_is_microsoft(void);
+ const char *db_version(void);
+diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c
+index f634bae..119ac37 100644
+--- a/src/odbc/unittests/connect.c
++++ b/src/odbc/unittests/connect.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: connect.c,v 1.11 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: connect.c,v 1.12 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -20,6 +20,7 @@ main(int argc, char *argv[])
+ 	SQLSMALLINT len;
+ 	int failures = 0;
+ 	int is_freetds = 1;
++	SQLRETURN rc;
+ 
+ 	if (read_login_info())
+ 		exit(1);
+@@ -68,9 +69,9 @@ main(int argc, char *argv[])
+ 	/* this is expected to work with unixODBC */
+ 	init_connect();
+ 	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
+-	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+-	if (RetCode == SQL_ERROR) {
+-		printf("Unable to open data source (ret=%d)\n", RetCode);
++	rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
++	if (rc == SQL_ERROR) {
++		printf("Unable to open data source (ret=%d)\n", rc);
+ 		++failures;
+ 	}
+ 	Disconnect();
+@@ -78,9 +79,9 @@ main(int argc, char *argv[])
+ 	/* this is expected to work with iODBC */
+ 	init_connect();
+ 	sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", DRIVER, SERVER, USER, PASSWORD, DATABASE);
+-	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+-	if (RetCode == SQL_ERROR) {
+-		printf("Unable to open data source (ret=%d)\n", RetCode);
++	rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
++	if (rc == SQL_ERROR) {
++		printf("Unable to open data source (ret=%d)\n", rc);
+ 		++failures;
+ 	}
+ 	Disconnect();
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index f282a19..63eddc7 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.18 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.19 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
+@@ -12,10 +12,10 @@ static int mssql2005 = 0;
+ static void
+ CheckNoRow(const char *query)
+ {
+-	SQLRETURN RetCode;
++	SQLRETURN rc;
+ 
+-	CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
+-	if (RetCode == SQL_NO_DATA)
++	rc = CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
++	if (rc == SQL_NO_DATA)
+ 		return;
+ 
+ 	do {
+@@ -44,7 +44,6 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 	SQLUSMALLINT i;
+ 	SQLULEN num_row;
+ 	SQLHSTMT stmt2;
+-	SQLRETURN RetCode;
+ 
+ 	/* create test table */
+ 	Command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index b394ec0..2fc451e 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.9 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLINTEGER v_int_3;
+@@ -14,7 +14,7 @@ doFetch(int dir, int pos)
+ {
+ 	SQLRETURN RetCode;
+ 
+-	CHKFetchScroll(dir, pos, "SINo");
++	RetCode = CHKFetchScroll(dir, pos, "SINo");
+ 
+ 	if (RetCode != SQL_NO_DATA)
+ 		printf(">> fetch %2d %10d : %d [%s]\n", dir, pos, v_ind_3_1 ? (int) v_int_3 : -1, v_ind_3_2 ? v_char_3 : "null");
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index 6aaf64d..2be1706 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.7 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.8 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -38,7 +38,7 @@ Test(void)
+ 
+ 	/* Read records from last to first */
+ 	printf("\n\nReading records from last to first:\n");
+-	CHKFetchScroll(SQL_FETCH_LAST, -ROWS, "SINo");
++	RetCode = CHKFetchScroll(SQL_FETCH_LAST, -ROWS, "SINo");
+ 	while (RetCode != SQL_NO_DATA) {
+ 		SQLULEN RowNumber;
+ 
+@@ -54,11 +54,11 @@ Test(void)
+ 
+ 		/* Read next rowset */
+ 		if ( (RowNumber>1) && (RowNumber<ROWS) ) {
+-			CHKFetchScroll(SQL_FETCH_RELATIVE, 1-RowNumber, "SINo"); 
++			RetCode = CHKFetchScroll(SQL_FETCH_RELATIVE, 1-RowNumber, "SINo"); 
+ 			for (i=RowNumber-1; i<ROWS; ++i)
+ 				statuses[i] = SQL_ROW_NOROW;
+ 		} else {
+-			CHKFetchScroll(SQL_FETCH_RELATIVE, -ROWS, "SINo");
++			RetCode = CHKFetchScroll(SQL_FETCH_RELATIVE, -ROWS, "SINo");
+ 		}
+ 	}
+ }
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index d962444..f7d8e76 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.8 2008/11/11 08:40:17 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.9 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -32,7 +32,7 @@ main(int argc, char *argv[])
+ 	Command("insert into #tmp values(7)");
+ 
+ 	/* issue our command */
+-	CHKR(CommandWithResult, (Statement, "select 100 / (i - 5) from #tmp order by i"), "SE");
++	RetCode = Command2("select 100 / (i - 5) from #tmp order by i", "SE");
+ 
+ 	/* special case, early Sybase detect error early */
+ 	if (RetCode != SQL_ERROR) {
+@@ -58,12 +58,12 @@ main(int argc, char *argv[])
+ 
+ 	Command("SELECT * FROM sysobjects");
+ 
+-	/* a statement is already active so you get error */
+-	CHKR(CommandWithResult, (stmt, "SELECT * FROM sysobjects"), "E");
+-
+ 	tmp_stmt = Statement;
+ 	Statement = stmt;
+ 
++	/* a statement is already active so you get error */
++	Command2("SELECT * FROM sysobjects", "E");
++
+ 	ReadError();
+ 
+ 	Disconnect();
+diff --git a/src/odbc/unittests/lang_error.c b/src/odbc/unittests/lang_error.c
+index c974cbd..9e1f7d0 100644
+--- a/src/odbc/unittests/lang_error.c
++++ b/src/odbc/unittests/lang_error.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test if SQLExecDirect return error if a error in row is returned */
+ 
+-static char software_version[] = "$Id: lang_error.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: lang_error.c,v 1.5 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -11,7 +11,7 @@ main(int argc, char *argv[])
+ 	Connect();
+ 
+ 	/* issue print statement and test message returned */
+-	CHKR(CommandWithResult, (Statement, "SELECT DATEADD(dd,-100000,getdate())"), "E");
++	Command2("SELECT DATEADD(dd,-100000,getdate())", "E");
+ 
+ 	Disconnect();
+ 
+diff --git a/src/odbc/unittests/prepclose.c b/src/odbc/unittests/prepclose.c
+index 78ae112..8fa19ba 100644
+--- a/src/odbc/unittests/prepclose.c
++++ b/src/odbc/unittests/prepclose.c
+@@ -26,7 +26,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: prepclose.c,v 1.4 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: prepclose.c,v 1.5 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -65,7 +65,6 @@ static int
+ Test(int direct)
+ {
+ 	char buf[256];
+-	SQLRETURN RetCode;
+ 	unsigned char sqlstate[6];
+ 
+ 	Connect();
+diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c
+index 9ba83ae..9deb9c8 100644
+--- a/src/odbc/unittests/print.c
++++ b/src/odbc/unittests/print.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: print.c,v 1.21 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: print.c,v 1.22 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -32,7 +32,7 @@ test(int odbc3)
+ 	/* issue print statement and test message returned */
+ 	output[0] = 0;
+ 	query = "print 'START' select count(*) from sysobjects where name='sysobjects' print 'END'";
+-	CHKR(CommandWithResult, (Statement, query), "I");
++	Command2(query, "I");
+ 	ReadError();
+ 	if (!strstr((char *) output, "START")) {
+ 		printf("Message invalid\n");
+@@ -95,7 +95,7 @@ test(int odbc3)
+ 	}
+ 
+ 	/* issue invalid command and test error */
+-	CHKR(CommandWithResult, (Statement, "SELECT donotexistsfield FROM donotexiststable"), "E");
++	Command2("SELECT donotexistsfield FROM donotexiststable", "E");
+ 	ReadError();
+ 
+ 	/* test no data returned */
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index 1598231..7d70afc 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.14 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.15 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -131,7 +131,7 @@ main(int argc, char *argv[])
+ 
+ 		ind = SQL_LEN_DATA_AT_EXEC(0);
+ 
+-		CHKExecute("Ne");
++		RetCode = CHKExecute("Ne");
+ 		while (RetCode == SQL_NEED_DATA) {
+ 			RetCode = SQLParamData(Statement, &ptr);
+ 			if (RetCode == SQL_NEED_DATA) {
+diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c
+index 0321b2f..684df8c 100644
+--- a/src/odbc/unittests/raiserror.c
++++ b/src/odbc/unittests/raiserror.c
+@@ -4,7 +4,7 @@
+ 
+ /* TODO add support for Sybase */
+ 
+-static char software_version[] = "$Id: raiserror.c,v 1.23 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: raiserror.c,v 1.24 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{?=call #tmp1(?,?,?)}"
+@@ -42,7 +42,7 @@ TestResult(SQLRETURN result0, int level, const char *func)
+ 	SQLINTEGER NativeError;
+ 	char MessageText[1000];
+ 	SQLSMALLINT TextLength;
+-	SQLRETURN result = result0;
++	SQLRETURN result = result0, rc;
+ 
+ 	if (result == SQL_NO_DATA && strcmp(func, "SQLFetch") == 0)
+ 		result = SQL_SUCCESS_WITH_INFO;
+@@ -61,8 +61,8 @@ TestResult(SQLRETURN result0, int level, const char *func)
+ 	SqlState[0] = 0;
+ 	MessageText[0] = 0;
+ 	NativeError = 0;
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText, sizeof(MessageText), &TextLength, "SI");
+-	printf("Func=%s Result=%d DIAG REC 1: State=%s Error=%d: %s\n", func, (int) RetCode, SqlState, (int) NativeError, MessageText);
++	rc = CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText, sizeof(MessageText), &TextLength, "SI");
++	printf("Func=%s Result=%d DIAG REC 1: State=%s Error=%d: %s\n", func, (int) rc, SqlState, (int) NativeError, MessageText);
+ 
+ 	if (strstr(MessageText, "An error occurred") == NULL) {
+ 		fprintf(stderr, "Wrong error returned!\n");
+@@ -78,11 +78,11 @@ CheckData(const char *s, int line)
+ {
+ 	char buf[80];
+ 	SQLLEN ind;
+-	SQLRETURN RetCode;
++	SQLRETURN rc;
+ 
+-	CHKGetData(1, SQL_C_CHAR, buf, sizeof(buf), &ind, "SE");
++	rc = CHKGetData(1, SQL_C_CHAR, buf, sizeof(buf), &ind, "SE");
+ 
+-	if (RetCode == SQL_ERROR) {
++	if (rc == SQL_ERROR) {
+ 		buf[0] = 0;
+ 		ind = 0;
+ 	}
+@@ -245,7 +245,7 @@ Test2(int nocount, int second_select)
+ 
+ 	sprintf(sql, create_proc, nocount ? "     SET NOCOUNT ON\n" : "",
+ 		second_select ? "     SELECT 'Here is the last row' AS LastResult\n" : "");
+-	CHKR(CommandWithResult, (Statement, sql), "SNo");
++	Command(sql);
+ 
+ 	Test(5);
+ 
+diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c
+index 6595f9c..4c85dca 100644
+--- a/src/odbc/unittests/tables.c
++++ b/src/odbc/unittests/tables.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: tables.c,v 1.16 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: tables.c,v 1.17 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef WIN32
+@@ -57,7 +57,6 @@ static void
+ DoTest(const char *type, int row_returned)
+ {
+ 	int table_len = SQL_NULL_DATA;
+-	SQLRETURN RetCode;
+ 	char table_buf[80];
+ 	int found = 0;
+ 
+@@ -116,11 +115,6 @@ DoTest(const char *type, int row_returned)
+ 			break;
+ 	}
+ 
+-	if (RetCode != SQL_NO_DATA) {
+-		printf("Unexpected data\n");
+-		exit(1);
+-	}
+-
+ 	if (expect && !found) {
+ 		printf("expected row not found\n");
+ 		exit(1);
+diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c
+index ee3edef..230c89a 100644
+--- a/src/odbc/unittests/timeout.c
++++ b/src/odbc/unittests/timeout.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test timeout of query */
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.11 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.12 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -59,7 +59,7 @@ main(int argc, char *argv[])
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+ 	/* TODO should return error S1T00 Timeout expired, test error message */
+-	CHKR(CommandWithResult, (Statement, "update test_timeout set t = 'bad' where n = 1"), "E");
++	Command2("update test_timeout set t = 'bad' where n = 1", "E");
+ 
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+diff --git a/src/odbc/unittests/timeout4.c b/src/odbc/unittests/timeout4.c
+index 14e3edd..cb0cbea 100644
+--- a/src/odbc/unittests/timeout4.c
++++ b/src/odbc/unittests/timeout4.c
+@@ -39,7 +39,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: timeout4.c,v 1.3 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: timeout4.c,v 1.4 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -80,7 +80,6 @@ static int
+ Test(int direct)
+ {
+ 	char buf[256];
+-	SQLRETURN RetCode;
+ 	char sqlstate[6];
+ 	time_t start_time, end_time;
+ 
+diff --git a/src/odbc/unittests/transaction.c b/src/odbc/unittests/transaction.c
+index d90a685..54c4558 100644
+--- a/src/odbc/unittests/transaction.c
++++ b/src/odbc/unittests/transaction.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: transaction.c,v 1.15 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: transaction.c,v 1.16 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int
+@@ -8,7 +8,6 @@ Test(int discard_test)
+ {
+ 	SQLINTEGER out_buf;
+ 	SQLLEN out_len;
+-	SQLRETURN RetCode;
+ 	SQLLEN rows;
+ 	int retcode = 0;
+ 	char buf[512];
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index e812296..b297b1a 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.7 2008/11/11 08:34:09 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.8 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -48,7 +48,7 @@ CheckDirtyRead(void)
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch uncommited row */
+-	CHKR(CommandWithResult, (Statement, "SELECT * FROM test_transaction WHERE t = 'second' AND n = 1"), "SE");
++	RetCode = Command2("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1", "SE");
+ 	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+@@ -77,7 +77,7 @@ CheckNonrepeatableRead(void)
+ 
+ 	/* transaction 1 change a row and commit */
+ 	SWAP_CONN();
+-	CHKR(CommandWithResult, (Statement, "UPDATE test_transaction SET t = 'second' WHERE n = 1"), "SE");
++	RetCode = Command2("UPDATE test_transaction SET t = 'second' WHERE n = 1", "SE");
+ 	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+@@ -114,7 +114,7 @@ CheckPhantom(void)
+ 
+ 	/* transaction 1 insert a row that match critera */
+ 	SWAP_CONN();
+-	CHKR(CommandWithResult, (Statement, "INSERT INTO test_transaction(n, t) VALUES(2, 'initial')"), "SE");
++	RetCode = Command2("INSERT INTO test_transaction(n, t) VALUES(2, 'initial')", "SE");
+ 	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+@@ -198,8 +198,6 @@ Test(int txn, const char *expected)
+ int
+ main(int argc, char *argv[])
+ {
+-	SQLRETURN RetCode;
+-
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c
+index 038ac5c..b716b65 100644
+--- a/src/odbc/unittests/typeinfo.c
++++ b/src/odbc/unittests/typeinfo.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: typeinfo.c,v 1.11 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: typeinfo.c,v 1.12 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -34,8 +34,6 @@ TestName(int index, const char *expected_name)
+ static void
+ FlushStatement(void)
+ {
+-	SQLRETURN RetCode;
+-
+ 	while (CHKFetch("SNo") == SQL_SUCCESS)
+ 		;
+ 
+@@ -53,7 +51,7 @@ CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int l
+ 
+ 	CHKBindCol(2, SQL_C_SSHORT, &out_type, 0, &ind, "SI");
+ 	CHKGetTypeInfo(type, "SI");
+-	CHKFetch("SNo");
++	RetCode = CHKFetch("SNo");
+ 	switch (RetCode) {
+ 	case SQL_SUCCESS:
+ 		if (expected == SQL_UNKNOWN_TYPE) {
+@@ -88,7 +86,6 @@ DoTest(int version3)
+ 	SQLSMALLINT type, is_unsigned;
+ 	SQLINTEGER col_size, min_scale;
+ 	SQLLEN ind1, ind2, ind3, ind4, ind5, ind6;
+-	SQLRETURN RetCode;
+ 	int date_time_supported = 0;
+ 
+ 	use_odbc_version3 = version3;
+@@ -124,8 +121,7 @@ DoTest(int version3)
+ 	/* numeric type for data */
+ 
+ 	/* test for date/time support */
+-	RetCode = CommandWithResult(Statement, "select cast(getdate() as date)");
+-	if (RetCode == SQL_SUCCESS)
++	if (CommandWithResult(Statement, "select cast(getdate() as date)") == SQL_SUCCESS)
+ 		date_time_supported = 1;
+ 	SQLCloseCursor(Statement);
+ 
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index 671b37b..d53c986 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.10 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.11 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -17,10 +17,10 @@ init_connect(void)
+ static void
+ CheckNoRow(const char *query)
+ {
+-	SQLRETURN RetCode;
++	SQLRETURN rc;
+ 
+-	CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
+-	if (RetCode == SQL_NO_DATA)
++	rc = CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
++	if (rc == SQL_NO_DATA)
+ 		return;
+ 
+ 	do {
+diff --git a/src/odbc/unittests/warning.c b/src/odbc/unittests/warning.c
+index 8a0d866..a7ce5e6 100644
+--- a/src/odbc/unittests/warning.c
++++ b/src/odbc/unittests/warning.c
+@@ -14,7 +14,7 @@
+  * inside recordset
+  * Sybase do not return warning but test works the same
+  */
+-static char software_version[] = "$Id: warning.c,v 1.8 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: warning.c,v 1.9 2008/12/03 12:55:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char one_null_with_warning[] = "select max(a) as foo from (select convert(int, null) as a) as test";
+@@ -28,8 +28,6 @@ static const int tds_no_dm = 0;
+ static void
+ Test(const char *query)
+ {
+-	SQLRETURN RetCode;
+-
+ 	CHKPrepare((SQLCHAR *) query, SQL_NTS, "S");
+ 
+ 	CHKExecute("S");
+
+commit f1ab3cd9d373897ef89bca529e8efc3543430701
+Author: freddy77 <freddy77>
+Date:   Fri Dec 5 08:32:47 2008 +0000
+
+    improve test
+
+diff --git a/ChangeLog b/ChangeLog
+index b9e4922..04afb1c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Dec 05 09:31:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/putdata.c: improve
++
+ Wed Dec 03 13:54:18 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/array_out.c src/odbc/unittests/blob1.c:
+ 	* src/odbc/unittests/cancel.c src/odbc/unittests/common.c:
+@@ -1003,4 +1006,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2669 2008/12/03 12:55:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2670 2008/12/05 08:32:47 freddy77 Exp $
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index 7d70afc..140c069 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.15 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.16 2008/12/05 08:32:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -10,12 +10,45 @@ static const char test_text[] =
+ 
+ #define BYTE_AT(n) (((n) * 245 + 123) & 0xff)
+ 
++static void
++CheckNoRow(const char *query)
++{
++	SQLRETURN rc;
++
++	rc = CHKExecDirect((SQLCHAR *) query, SQL_NTS, "SINo");
++	if (rc == SQL_NO_DATA)
++		return;
++
++	do {
++		SQLSMALLINT cols;
++
++		CHKNumResultCols(&cols, "S");
++		if (cols != 0) {
++			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
++			Disconnect();
++			exit(1);
++		}
++	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
++}
++
++static int
++to_sqlwchar(SQLWCHAR *dst, const char *src, int n)
++{
++	int i;
++	for (i = 0; i < n; ++i)
++		dst[i] = src[i];
++	return n * sizeof(SQLWCHAR);
++}
++
++static char sql[1024];
++
+ int
+ main(int argc, char *argv[])
+ {
+ 	SQLLEN ind;
+ 	int len = strlen(test_text), n, i;
+ 	const char *p;
++	char *pp;
+ 	SQLPOINTER ptr;
+ 	unsigned char buf[256], *pb;
+ 	SQLRETURN RetCode;
+@@ -56,10 +89,7 @@ main(int argc, char *argv[])
+ 				CHKPutData((char *) p, n, "S");
+ 			} else {
+ 				SQLWCHAR buf[256];
+-				int i;
+-				for (i = 0; i < n; ++i)
+-					buf[i] = p[i];
+-				CHKPutData((char *) buf, n * lc, "S");
++				CHKPutData((char *) buf, to_sqlwchar(buf, p, n), "S");
+ 			}
+ 			p += n;
+ 			n *= 2;
+@@ -108,7 +138,7 @@ main(int argc, char *argv[])
+ 
+ 		if (l < n)
+ 			n = l;
+-		CHKPutData((char *) p, n, "S");
++		CHKPutData((char *) pb, n, "S");
+ 		pb += n;
+ 		n *= 2;
+ 	}
+@@ -120,9 +150,28 @@ main(int argc, char *argv[])
+ 	Command("DECLARE @i2 INT");
+ 
+ 
+-	/* test len == 0 case from ML */
+ 	CHKFreeStmt(SQL_RESET_PARAMS, "S");
+ 
++	/* check inserts ... */
++	strcpy(sql, "IF EXISTS(SELECT * FROM #putdata WHERE CONVERT(VARBINARY(255),b) <> 0x");
++	/* append binary */
++	for (i = 0; i < 254; ++i)
++		sprintf(strchr(sql, 0), "%02x", buf[i]);
++	strcat(sql, " OR CONVERT(VARCHAR(255),c) <> '");
++	/* append string */
++	pp = strchr(sql, 0);
++	p = test_text;
++	do {
++		*pp++ = *p;
++		if (*p == '\'')
++			*pp++ = *p;
++	} while(*p++);
++	strcat(sql, "') SELECT 1");
++	CheckNoRow(sql);
++
++	Command("DELETE FROM #putdata");
++
++	/* test len == 0 case from ML */
+ 	type = SQL_C_CHAR;
+ 	for (;;) {
+ 		CHKPrepare((SQLCHAR *) "INSERT INTO #putdata(c) VALUES(?)", SQL_NTS, "S");
+@@ -135,7 +184,12 @@ main(int argc, char *argv[])
+ 		while (RetCode == SQL_NEED_DATA) {
+ 			RetCode = SQLParamData(Statement, &ptr);
+ 			if (RetCode == SQL_NEED_DATA) {
+-				SQLPutData(Statement, "abc", 3);
++				if (type == SQL_C_CHAR) {
++					SQLPutData(Statement, "abc", 3);
++				} else {
++					SQLWCHAR buf[10];
++					SQLPutData(Statement, buf, to_sqlwchar(buf, "abc", 3));
++				}
+ 			}
+ 		}
+ 		if (type != SQL_C_CHAR)
+@@ -144,7 +198,9 @@ main(int argc, char *argv[])
+ 		ResetStatement();
+ 	}
+ 
+-	/* TODO check inserts ... */
++	/* check inserts ... */
++	CheckNoRow("IF EXISTS(SELECT * FROM #putdata WHERE c NOT LIKE 'abc') SELECT 1");
++
+ 	/* TODO test cancel inside SQLExecute */
+ 
+ 	Disconnect();
+
+commit 0c6cd06565e67810199cfe8eb42be994ecab5142
+Author: jklowden <jklowden>
+Date:   Mon Dec 8 22:44:26 2008 +0000
+
+    initial version
+
+diff --git a/samples/odbcfunc.pl b/samples/odbcfunc.pl
+new file mode 100755
+index 0000000..3ab49ac
+--- /dev/null
++++ b/samples/odbcfunc.pl
+@@ -0,0 +1,95 @@
++#! /usr/bin/perl -w
++
++# List supported/unsupported functions for an ODBC data source
++
++# Contributed to the public domain by James K. Lowden
++# $Id: odbcfunc.pl,v 1.1 2008/12/08 22:44:26 jklowden Exp $
++
++use Getopt::Std;
++use File::Basename;
++use DBI;
++use DBI::Const::GetInfoType;
++
++getopts( 'I:P:S:U:v:', \%opts );
++
++$opts{v} = 0 unless defined($opts{v});
++
++$server = $opts{S} 
++	or die basename($0) . qq(: need -S server (DSN) name\n);
++
++$dsn = qq(dbi:ODBC:$server) 
++	or die qq(could not connect to ODBC Data Source "$server"\n);
++
++my ($username, $passwd) = ($opts{U}, $opts{P});
++
++$dbh = DBI->connect($dsn, $username, $passwd, undef);
++
++print "Available ODBC Constants:\n", join($/, keys %GetInfoType), $/
++	if $opts{v} == 1;
++
++$sql_h_path = "C:/Program Files/Microsoft SQL Server/80/Tools/DevTools/Include";
++$sql_h_path = $opts{I} if defined($opts{I});
++
++# 
++# Build list of SQL_API constants from include files. 
++#
++foreach my $file (('sql.h', 'sqlext.h')) {
++	$sql_h_file = "$sql_h_path/$file";
++	open SQLH, "$sql_h_file" or die "could not open $sql_h_file\n";
++
++	while( <SQLH> ) {
++		next unless s/SQL_API_//;
++		my ($define, $name, $value) = split;
++		if( defined($api{$value}) ) {
++			printf STDERR "overwriting %d (%s) with %s in $file\n", 
++				$value, $api{$value}, $name, $file;
++		}
++		$api{$value} = $name;
++	}
++}
++
++die unless %api;
++
++# Capture array of supported/unsupported by SQL_API index value. 
++my @supported = $dbh->func(0, "GetFunctions");
++
++# Map names to supported/unsupported 
++for ($api=1; $api < 100; $api++) {
++	next if( !$supported[$api] && !$api{$api} ); 
++	local $^W;
++	$^W = 0;
++	printf "%4d:\t%-30s\t%s supported\n", $api, $api{$api}, $supported[$api]? '   ':'not'
++		if $opts{v} == 2;
++	$functions{$api{$api}} = $supported[$api]? 'supported' : 'unsupported';
++}
++
++# Print names, sorted
++foreach my $name (sort keys %functions) {
++	printf "%-30s\t%s\n", $name, $functions{$name};
++}
++
++__END__
++
++=head1 NAME
++
++odbcfunc - List ODBC functions supported (and unsupported) by an ODBC driver. 
++
++=head1 SYNOPSIS
++
++	odbcfunc.pl -S DSN [-U username] [-P passwd] [-v verbosity]
++
++=head1 DESCRIPTION
++
++Prints results from the ODBC function SQLGetFunctions.  
++
++=head1 OPTIONS
++
++=over 
++
++=item -S DSN is a Data Source Name that uses the driver. 
++
++=item -U is a username, if required. 
++
++=item -P is a password, if required. 
++
++=item -v may have a value of 1 or 2, which prints more details. 
+diff --git a/samples/odbschema.pl b/samples/odbschema.pl
+new file mode 100755
+index 0000000..c2ccd79
+--- /dev/null
++++ b/samples/odbschema.pl
+@@ -0,0 +1,135 @@
++#! /usr/bin/perl -w
++
++# List DDL for an ODBC data source
++
++# Contributed to the public domain by James K. Lowden
++# Inspired by the much more sophisticated dbschema by Michael Peppler, et al.
++# $Id: odbschema.pl,v 1.1 2008/12/08 22:44:26 jklowden Exp $
++
++use Getopt::Std;
++use File::Basename;
++use DBI;
++use DBI::Const::GetInfoType;
++
++getopts( 'S:v:X', \%opts );
++
++$opts{v} = 0 unless defined($opts{v});
++
++# print environment information, to help know what can be connected to
++if( $opts{v} == 3 ) {
++	print "Available drivers:\n", join($/, DBI->available_drivers, $/);
++	print "Available ODBC Data Sources:\n", join($/, DBI->data_sources('ODBC', undef), $/);
++	print "Available ODBC Constants:\n", join($/, keys %GetInfoType), $/;
++}
++
++$server = $opts{S} 
++	or die basename($0) . qq(: need -S server (DSN) name\n);
++
++$dsn = qq(dbi:ODBC:$server) 
++	or die qq(could not connect to ODBC Data Source "$server"\n);
++
++my ($username, $auth);
++
++$dbh = DBI->connect($dsn, $username, $auth, undef);
++
++# get tables
++$sth = $dbh->table_info('%', '', '');
++while ( @row = $sth->fetchrow_array ) {
++	if( $opts{v} == 2 ) {
++		print '[', join('], [', @row), ']', $/;
++	}
++	next unless $row[3] eq 'TABLE';
++	push @tables, $row[2];
++	$catalogs{$row[0]}++;
++}
++
++die if 1 < keys %catalogs;
++
++($catalog) = keys %catalogs;
++$schema = '';
++$fGetKeys = 1;
++
++# set LongReadLen to something more than 80 if extracting data. 
++if( $opts{X} ) {
++	printf STDERR qq("LongReadLen" is %d\n), $dbh->{LongReadLen};
++	$dbh->{LongReadLen} = 640;
++	printf STDERR qq("LongReadLen" is %d\n), $dbh->{LongReadLen};
++}
++
++foreach my $table (@tables) {
++	if( $fGetKeys ) {
++		my $ksth = $dbh->primary_key_info( $catalog, $schema, $table ); 
++		if( !defined($ksth) ) {
++			warn "warning: primary_key_info failed for $catalog.$schema.$table, "
++				 . "no primary keys will be extracted for this schema.\n";
++			$fGetKeys = 0;
++			goto GetColumns;
++		}
++
++		# get primary key columns
++		my $c = 0;
++		my @key = ();
++		while ( $rrow = $ksth->fetchrow_hashref ) {
++			my $pkname = defined($rrow->{PK_NAME})? $rrow->{PK_NAME} : '';
++			$rrow->{KEY_SEQ} == ++$c 
++				or die "KEY_SEQ $rrow->{KEY_SEQ} != $c\n";
++			push @key, $rrow->{COLUMN_NAME};
++		}
++	}
++
++	#
++	GetColumns:
++	#
++	my $column = '%';
++	$sth = $dbh->column_info( $catalog, $schema, $table, $column ) 
++		or die "error: column_info failed\n";
++
++	printf "create table [%s]\n", $table;
++
++	# get columns
++	my $comma = '(';
++	while ( $rrow = $sth->fetchrow_hashref ) {
++		my $nullable = $rrow->{NULLABLE}? '    NULL' : 'not NULL';
++		my $type = $rrow->{TYPE_NAME};
++		$type .= "($rrow->{CHAR_OCTET_LENGTH})" if $rrow->{CHAR_OCTET_LENGTH};
++		printf "\t$comma [%-30s] %-15s %s -- %3d\n", 
++			$rrow->{COLUMN_NAME}, $type, $nullable, $rrow->{ORDINAL_POSITION};
++		$comma = ',';
++	}
++	if( $key ) {
++		printf "\t, PRIMARY KEY (%s)\n", join ', ', @key;
++	}
++	printf "\t);\n\n";
++
++	if( $opts{X} ) {
++		extract_data($table);
++	}
++}
++
++sub extract_data
++{ my $table = $_[0];
++
++	my $filename = $table;
++	$filename =~ s/[<>\ ]//g;
++	open DAT, ">$filename.dat" 
++		or die qq(error: could not open "$filename.dat" (table: $table)\n);
++
++	my $statement = "select * from [$table]";
++
++	my $sth = $dbh->prepare($statement) 
++		or die qq(error: could not prepare "$statement"\n);
++
++	$sth->execute() or die;
++
++	local $^W;
++	$^W = 0;
++	my @row;
++	while ( @row = $sth->fetchrow_array ) {
++			die if grep /\t/, @row;
++			print DAT join("\t", @row), $/;
++	}
++}
++	
++
++
++__END__
+
+commit 3dee5e4087456e4a49ee2ac27603ad43b5e0c2db
+Author: jklowden <jklowden>
+Date:   Mon Dec 8 22:47:07 2008 +0000
+
+    finished pod
+
+diff --git a/samples/odbcfunc.pl b/samples/odbcfunc.pl
+index 3ab49ac..2ce27d6 100755
+--- a/samples/odbcfunc.pl
++++ b/samples/odbcfunc.pl
+@@ -3,7 +3,7 @@
+ # List supported/unsupported functions for an ODBC data source
+ 
+ # Contributed to the public domain by James K. Lowden
+-# $Id: odbcfunc.pl,v 1.1 2008/12/08 22:44:26 jklowden Exp $
++# $Id: odbcfunc.pl,v 1.2 2008/12/08 22:47:07 jklowden Exp $
+ 
+ use Getopt::Std;
+ use File::Basename;
+@@ -84,7 +84,9 @@ Prints results from the ODBC function SQLGetFunctions.
+ 
+ =head1 OPTIONS
+ 
+-=over 
++=over
++
++=item -I include path for sql.h and sqlext.h 
+ 
+ =item -S DSN is a Data Source Name that uses the driver. 
+ 
+@@ -93,3 +95,5 @@ Prints results from the ODBC function SQLGetFunctions.
+ =item -P is a password, if required. 
+ 
+ =item -v may have a value of 1 or 2, which prints more details. 
++
++=back
+
+commit e1bff945b4763a3353e94e6dedaa297253b3a542
+Author: freddy77 <freddy77>
+Date:   Tue Dec 9 09:39:13 2008 +0000
+
+    optimize link using gcc4
+
+diff --git a/ChangeLog b/ChangeLog
+index 04afb1c..5f3705b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Dec 09 10:38:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/hmac_md5.h include/tds.h include/tdsconvert.h:
++	* src/tds/tds_checks.h:
++	- optimize link using gcc4
++
+ Fri Dec 05 09:31:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/putdata.c: improve
+ 
+@@ -1006,4 +1011,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2670 2008/12/05 08:32:47 freddy77 Exp $
++$Id: ChangeLog,v 1.2671 2008/12/09 09:39:13 freddy77 Exp $
+diff --git a/include/hmac_md5.h b/include/hmac_md5.h
+index e06c778..3999b44 100644
+--- a/include/hmac_md5.h
++++ b/include/hmac_md5.h
+@@ -20,10 +20,16 @@
+ #ifndef _hmac_md5_h_
+ #define _hmac_md5_h_
+ 
+-/* $Id: hmac_md5.h,v 1.1 2008/07/30 08:02:54 freddy77 Exp $ */
++/* $Id: hmac_md5.h,v 1.2 2008/12/09 09:39:14 freddy77 Exp $ */
+ 
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility push(hidden)
++#endif
+ void hmac_md5(const unsigned char key[16],
+               const unsigned char* data, size_t data_len,
+               unsigned char* digest);
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility pop
++#endif
+ 
+ #endif
+diff --git a/include/tds.h b/include/tds.h
+index ab897b6..79b3d29 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.299 2008/11/07 16:25:52 freddy77 Exp $ */
++/* $Id: tds.h,v 1.300 2008/12/09 09:39:14 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -40,6 +40,10 @@ typedef struct tds_socket TDSSOCKET;
+ #include "tds_sysdep_private.h"
+ #endif /* _FREETDS_LIBRARY_SOURCE */
+ 
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility push(hidden)
++#endif
++
+ #ifdef __cplusplus
+ extern "C"
+ {
+@@ -1535,7 +1539,13 @@ unsigned int tds_gettime_ms(void);
+ /* log.c */
+ void tdsdump_off(void);
+ void tdsdump_on(void);
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility pop
++#endif
+ int tdsdump_open(const char *filename);
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility push(hidden)
++#endif
+ void tdsdump_close(void);
+ void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, int length);
+ void tdsdump_col(const TDSCOLUMN *col);
+@@ -1606,4 +1616,8 @@ TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds);
+ }
+ #endif
+ 
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility pop
++#endif
++
+ #endif /* _tds_h_ */
+diff --git a/include/tdsconvert.h b/include/tdsconvert.h
+index a6c444a..449f826 100644
+--- a/include/tdsconvert.h
++++ b/include/tdsconvert.h
+@@ -20,6 +20,10 @@
+ #ifndef _tdsconvert_h_
+ #define _tdsconvert_h_
+ 
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility push(hidden)
++#endif
++
+ #ifdef __cplusplus
+ extern "C"
+ {
+@@ -28,7 +32,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsconvert.h,v 1.23 2006/04/15 08:18:44 freddy77 Exp $ */
++/* $Id: tdsconvert.h,v 1.24 2008/12/09 09:39:14 freddy77 Exp $ */
+ 
+ typedef union conv_result
+ {
+@@ -96,4 +100,8 @@ size_t tds_strftime(char *buf, size_t maxsize, const char *format, const TDSDATE
+ }
+ #endif
+ 
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility pop
++#endif
++
+ #endif /* _tdsconvert_h_ */
+diff --git a/src/tds/tds_checks.h b/src/tds/tds_checks.h
+index 2811cc3..0d50055 100644
+--- a/src/tds/tds_checks.h
++++ b/src/tds/tds_checks.h
+@@ -20,7 +20,10 @@
+ #ifndef TDS_CHECKS_H
+ #define TDS_CHECKS_H
+ 
+-/* $Id: tds_checks.h,v 1.3 2007/06/19 13:31:34 freddy77 Exp $ */
++/* $Id: tds_checks.h,v 1.4 2008/12/09 09:39:14 freddy77 Exp $ */
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility push(hidden)
++#endif
+ 
+ #if ENABLE_EXTRA_CHECKS
+ #define CHECK_STRUCT_EXTRA(func,s) func(s)
+@@ -50,4 +53,7 @@ int tds_get_cardinal_type(int datatype);
+ int tds_get_varint_size(TDSSOCKET * tds, int datatype);
+ #endif
+ 
++#if defined(__GNUC__) && __GNUC__ >= 4
++#pragma GCC visibility pop
++#endif
+ #endif /* TDS_CHECKS_H */
+
+commit ff99c49a8086a7c6e8a44dadbfbf9309adb1f5d8
+Author: freddy77 <freddy77>
+Date:   Wed Dec 10 14:56:26 2008 +0000
+
+    declare tds_g_append_mode and STD_DATETIME_FMT in tds.h
+
+diff --git a/ChangeLog b/ChangeLog
+index 5f3705b..5dac0cb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Dec 10 15:55:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/apps/tsql.c src/ctlib/cs.c:
++	* src/ctlib/unittests/common.c src/dblib/dblib.c src/tds/config.c:
++	* src/tds/unittests/convert.c:
++	- declare tds_g_append_mode and STD_DATETIME_FMT in tds.h
++
+ Tue Dec 09 10:38:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/hmac_md5.h include/tds.h include/tdsconvert.h:
+ 	* src/tds/tds_checks.h:
+@@ -1011,4 +1017,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2671 2008/12/09 09:39:13 freddy77 Exp $
++$Id: ChangeLog,v 1.2672 2008/12/10 14:56:26 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 79b3d29..b16c057 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.300 2008/12/09 09:39:14 freddy77 Exp $ */
++/* $Id: tds.h,v 1.301 2008/12/10 14:56:26 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1392,6 +1392,7 @@ void tds_fix_connection(TDSCONNECTION * connection);
+ void tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
+ void tds_lookup_host(const char *servername, char *ip);
+ int tds_set_interfaces_file_loc(const char *interfloc);
++extern const char STD_DATETIME_FMT[];
+ 
+ TDSLOCALE *tds_get_locale(void);
+ int tds_alloc_row(TDSRESULTINFO * res_info);
+@@ -1556,6 +1557,7 @@ void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...
+ #endif
+ ;
+ extern int tds_debug_flags;
++extern int tds_g_append_mode;
+ 
+ /* net.c */
+ int tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index ab3594d..5914c97 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.121 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.122 2008/12/10 14:56:26 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -602,8 +602,6 @@ print_instance_data(TDSCONNECTION *connection)
+ 		printf("connecting to instance %s on port %d\n", tds_dstr_cstr(&connection->instance_name), connection->port);
+ }
+ 
+-extern const char STD_DATETIME_FMT[];
+-
+ int
+ main(int argc, char **argv)
+ {
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index fd5fa07..fd99aae 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.68 2008/12/03 08:37:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.69 2008/12/10 14:56:26 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -338,8 +338,6 @@ Cleanup:
+ 	return NULL;
+ }
+ 
+-extern const char STD_DATETIME_FMT[];
+-
+ CS_RETCODE
+ cs_ctx_alloc(CS_INT version, CS_CONTEXT ** ctx)
+ {
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index 2b917e2..8139c04 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -24,7 +24,7 @@
+ #include "common.h"
+ #include "ctlib.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.20 2008/09/09 14:48:03 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.21 2008/12/10 14:56:26 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -176,8 +176,6 @@ establish_login(int argc, char **argv)
+ 	return (*USER && *SERVER && *DATABASE)? CS_SUCCEED : CS_FAIL;
+ }
+ 
+-extern const char STD_DATETIME_FMT[];
+-
+ CS_RETCODE
+ try_ctlogin_with_options(int argc, char **argv, CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd, int verbose)
+ {
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 655f28a..3727a30 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.332 2008/12/03 08:37:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.333 2008/12/10 14:56:26 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -3228,7 +3228,6 @@ dbspr1row(DBPROCESS * dbproc, char *buffer, DBINT buf_len)
+ 	return SUCCEED;
+ }
+ 
+-extern const char STD_DATETIME_FMT[];
+ /**
+  * \ingroup dblib_core
+  * \brief Print a result set to stdout. 
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 3b8f6e7..220c253 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.137 2008/09/12 15:12:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.138 2008/12/10 14:56:27 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -90,8 +90,6 @@ static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * log
+ static int tds_lookup_port(const char *portname);
+ static void tds_config_encryption(const char * value, TDSCONNECTION * connection);
+ 
+-extern int tds_g_append_mode;
+-
+ static char *interf_file = NULL;
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char ) (c))
+diff --git a/src/tds/unittests/convert.c b/src/tds/unittests/convert.c
+index f20d43f..70d28c3 100644
+--- a/src/tds/unittests/convert.c
++++ b/src/tds/unittests/convert.c
+@@ -32,7 +32,7 @@
+ #include <sys/time.h>
+ #endif
+ 
+-static char software_version[] = "$Id: convert.c,v 1.23 2007/12/23 21:12:02 jklowden Exp $";
++static char software_version[] = "$Id: convert.c,v 1.24 2008/12/10 14:56:27 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int g_result = 0;
+@@ -50,8 +50,6 @@ free_convert(int type, CONV_RESULT *cr)
+ 	}
+ }
+ 
+-extern const char STD_DATETIME_FMT[];
+-
+ int
+ main(int argc, char **argv)
+ {
+
+commit d3cf349d3fe89f1e9b11dda56cc37095ab9a953e
+Author: jklowden <jklowden>
+Date:   Wed Dec 10 23:12:18 2008 +0000
+
+    add osql to unixODBC troubleshooting
+
+diff --git a/ChangeLog b/ChangeLog
+index 5dac0cb..d5cf670 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Dec 10 18:07:31 EST 2008	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml
++	- add osql to unixODBC troubleshooting 
++
+ Wed Dec 10 15:55:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/apps/tsql.c src/ctlib/cs.c:
+ 	* src/ctlib/unittests/common.c src/dblib/dblib.c src/tds/config.c:
+@@ -1017,4 +1021,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2672 2008/12/10 14:56:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2673 2008/12/10 23:12:18 jklowden Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index f1d9c32..74678cc 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/08/15 08:13:09 $</date>
+-		<releaseinfo>$Revision: 1.117 $</releaseinfo>
++		<date>$Date: 2008/12/10 23:12:19 $</date>
++		<releaseinfo>$Revision: 1.118 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.117 $</>
+-<member>$Date: 2008/08/15 08:13:09 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.117 2008/08/15 08:13:09 freddy77 Exp $.</>
++<member>$Revision: 1.118 $</>
++<member>$Date: 2008/12/10 23:12:19 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.118 2008/12/10 23:12:19 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/08/15 08:13:09 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/12/10 23:12:19 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1732,8 +1732,73 @@ The <option>-g</> is important to keep the symbol tables for debugging purposes.
+ 		<sect2 id="with.unixODBC"><title>With unixODBC</title>
+ 		
+ 			<para>
+-Try <command>isql -v <replaceable>dsn</> <replaceable>username</> <replaceable>password</></command>, and have  a look at the log.  See if the right address and TDS version are being used.  Adjust to taste.  
++Try <command>isql -v <replaceable>dsn</> <replaceable>username</> <replaceable>password</></command>, and have a look at the log.  See if the right address and TDS version are being used.  Adjust to taste.  
+ 			</para>
++		<sect3 id="with.unixODBC.osql"><title>Use <command>osql</></title>
++
++			<para>
++The <command>osql</> utility is a Bourne shell script that checks your ODBC configuration.  If it approves, it invokes the unixODBC isql utility.  Cf. <command>man osql</> for details on its use.  
++
++<example id="e.g.odbcdiagnose.osql">
++	<title>Use <command>osql</> to test the ODBC setup.</title>
++<screen>
++<prompt>$ </prompt><userinput>make odbctest.o</userinput>
++
++<prompt>$ </prompt><userinput>osql -S $S -U$U -P$P</userinput>
++looking for odbc.ini and odbcinst.ini in /usr/local/etc
++        reading "/usr/home/mr_ed/.odbc.ini"
++[machine] found in "/usr/home/mr_ed/.odbc.ini"
++found this section:
++        [machine]
++        Database = testdb
++        Servername = machine
++        Trace           = Yes
++        TraceFile       = /tmp/unixodbc.trace
++
++looking for driver for DSN [machine]
++no driver mentioned for [machine] in .odbc.ini
++looking for driver for DSN [default]
++driver "FreeTDS" found for [default] in .odbc.ini
++found driver named "FreeTDS"
++FreeTDS is not a readable file
++looking for entry named [FreeTDS] in /usr/local/etc/odbcinst.ini
++driver "/usr/local/lib/libtdsodbc.so" found for [FreeTDS] in odbcinst.ini
++/usr/local/lib/libtdsodbc.so is a readable file
++Using ODBC-Combined strategy
++FreeTDS servername is "machine" (from /usr/home/mr_ed/.odbc.ini)
++looking for [machine] in /usr/home/mr_ed/.freetds.conf
++"/usr/home/mr_ed/.freetds.conf" is a readable file
++found this section:
++        [machine]
++                host = machine.example.com
++                port = 2500
++                tds version = 8.0
++
++machine.example.com has address 10.82.32.177
++
++                           DSN: machine
++                        Driver: /usr/local/lib/libtdsodbc.so
++             Server's hostname: machine.example.com
++                       Address: 10.82.32.177
++
++Attempting connection as mr_ed ...
+++ exec isql machine mr_ed hayseed -v
+++---------------------------------------+
++| Connected!                            |
++|                                       |
++| sql-statement                         |
++| help [tablename]                      |
++| quit                                  |
++|                                       |
+++---------------------------------------+
++SQL>
++</screen>
++</example>
++			
++			</para>
++
++		</sect3>
++		
+ 		</sect2>
+ 		</sect1>
+ 		
+
+commit 75df4f05faf2aaeea1664bf70b2cda0fbf1808e2
+Author: jklowden <jklowden>
+Date:   Wed Dec 10 23:27:09 2008 +0000
+
+    show command line in example
+
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 74678cc..30ab1e5 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/12/10 23:12:19 $</date>
+-		<releaseinfo>$Revision: 1.118 $</releaseinfo>
++		<date>$Date: 2008/12/10 23:27:09 $</date>
++		<releaseinfo>$Revision: 1.119 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.118 $</>
+-<member>$Date: 2008/12/10 23:12:19 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.118 2008/12/10 23:12:19 jklowden Exp $.</>
++<member>$Revision: 1.119 $</>
++<member>$Date: 2008/12/10 23:27:09 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.119 2008/12/10 23:27:09 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/12/10 23:12:19 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/12/10 23:27:09 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1744,7 +1744,7 @@ The <command>osql</> utility is a Bourne shell script that checks your ODBC conf
+ <screen>
+ <prompt>$ </prompt><userinput>make odbctest.o</userinput>
+ 
+-<prompt>$ </prompt><userinput>osql -S $S -U$U -P$P</userinput>
++<prompt>$ </prompt><userinput>osql -S machine -U mr_ed -P hayseed</userinput>
+ looking for odbc.ini and odbcinst.ini in /usr/local/etc
+         reading "/usr/home/mr_ed/.odbc.ini"
+ [machine] found in "/usr/home/mr_ed/.odbc.ini"
+
+commit 2f19541492aee1ecbc5b3f80f1defbc8c62bf078
+Author: freddy77 <freddy77>
+Date:   Thu Dec 11 10:14:19 2008 +0000
+
+    add test for thread
+
+diff --git a/ChangeLog b/ChangeLog
+index d5cf670..c615d31 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Dec 11 11:11:34 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cancel.c: add test for thread
++
+ Wed Dec 10 18:07:31 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml
+ 	- add osql to unixODBC troubleshooting 
+@@ -1021,4 +1024,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2673 2008/12/10 23:12:18 jklowden Exp $
++$Id: ChangeLog,v 1.2674 2008/12/11 10:14:19 freddy77 Exp $
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 239707d..be887a0 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -10,7 +10,9 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+-#ifdef HAVE_ALARM
++#if defined(TDS_HAVE_PTHREAD_MUTEX) && HAVE_ALARM
++
++#include <pthread.h>
+ 
+ static char sqlstate[SQL_SQLSTATE_SIZE + 1];
+ 
+@@ -53,27 +55,76 @@ sigalrm_handler(int s)
+ 	signal(SIGALRM, exit_forced);
+ }
+ 
+-int
+-main(int argc, char **argv)
++volatile int exit_thread;
++
++static void *
++wait_thread_proc(void * arg)
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	int n;
++
++	sleep(4);
++
++	printf(">>>> SQLCancel() ...\n");
++	CHKCancel("S");
++	printf(">>>> ... SQLCancel done\n");
++	
++	for (n = 0; n < 4; ++n) {
++		sleep(1);
++		if (exit_thread)
++			return NULL;
++	}
++
++	exit_forced(0);
++	return NULL;
++}
+ 
++static void
++Test(int use_threads)
++{
++	pthread_t wait_thread;
++
++	printf("testing with %s\n", use_threads ? "threads" : "signals");
+ 	printf(">> Wait 5 minutes...\n");
+-	alarm(4);
+-	signal(SIGALRM, sigalrm_handler);
++	if (!use_threads) {
++		alarm(4);
++		signal(SIGALRM, sigalrm_handler);
++	} else {
++		int err;
++
++		exit_thread = 0;
++		err = pthread_create(&wait_thread, NULL, wait_thread_proc, NULL);
++		if (err != 0) {
++			perror("pthread_create");
++			exit(1);
++		}
++	}
+ 	CHKExecDirect((SQLCHAR *) "WAITFOR DELAY '000:05:00'", SQL_NTS, "E");
+-	alarm(0);
++	exit_thread = 1;
++	if (!use_threads) {
++		alarm(0);
++	} else {
++		pthread_join(wait_thread, NULL);
++	}
+ 	getErrorInfo(SQL_HANDLE_STMT, Statement);
+ 	if (strcmp(sqlstate, "HY008") != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+ 		Disconnect();
+-		return 1;
++		exit(1);
+ 	}
+ 
+ 	ResetStatement();
+ 
+ 	Command("SELECT name FROM sysobjects WHERE 0=1");
++}
++
++int
++main(int argc, char **argv)
++{
++	use_odbc_version3 = 1;
++	Connect();
++
++	Test(0);
++	Test(1);
+ 
+ 	Disconnect();
+ 	return 0;
+
+commit d2676e5ba020cf3b9b76411a8671f948d544f250
+Author: freddy77 <freddy77>
+Date:   Thu Dec 11 12:31:31 2008 +0000
+
+    avoid some possible buffer overflows
+
+diff --git a/ChangeLog b/ChangeLog
+index c615d31..9491b0d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Dec 11 13:29:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/Makefile.am src/apps/datacopy.c src/apps/freebcp.c:
++	* src/apps/freebcp.h:
++	- avoid some possible buffer overflows
++
+ Thu Dec 11 11:11:34 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cancel.c: add test for thread
+ 
+@@ -1024,4 +1029,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2674 2008/12/11 10:14:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2675 2008/12/11 12:31:31 freddy77 Exp $
+diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
+index 9e5c4d1..dd459c8 100644
+--- a/src/apps/Makefile.am
++++ b/src/apps/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.27 2008/01/25 17:35:52 freddy77 Exp $
++# $Id: Makefile.am,v 1.28 2008/12/11 12:31:31 freddy77 Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -16,7 +16,7 @@ endif
+ 
+ dist_bin_SCRIPTS = osql
+ 
+-freebcp_LDADD	= ../dblib/libsybdb.la $(NETWORK_LIBS)
++freebcp_LDADD	= ../dblib/libsybdb.la ../replacements/libreplacements.la $(NETWORK_LIBS)
+ freebcp_SOURCES = freebcp.c freebcp.h
+ 
+ tsql_LDADD	= ../tds/libtds.la \
+diff --git a/src/apps/datacopy.c b/src/apps/datacopy.c
+index 7ca73b3..cdab16c 100644
+--- a/src/apps/datacopy.c
++++ b/src/apps/datacopy.c
+@@ -171,10 +171,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 	int state;
+ 	int i;
+ 
+-	char arg[FILENAME_MAX + 1];
+-
+-	char connection[256];
+-	char owner[256];
++	char *arg;
+ 	char *tok;
+ 
+ 
+@@ -187,7 +184,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 	state = GET_NEXTARG;
+ 
+ 	for (i = 1; i < argc; i++) {
+-		strcpy(arg, argv[i]);
++		arg = argv[i];
+ 
+ 		switch (state) {
+ 
+@@ -220,10 +217,9 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 				break;
+ 			case 'c':
+ 				pdata->cflag++;
+-				if (strlen(arg) > 2) {
+-					strcpy(owner, &arg[2]);
+-					pdata->owner = strdup(owner);
+-				} else
++				if (strlen(arg) > 2)
++					pdata->owner = strdup(&arg[2]);
++				else
+ 					state = GET_OWNER;
+ 				break;
+ 			case 'd':
+@@ -232,9 +228,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 			case 'S':
+ 				pdata->Sflag++;
+ 				if (strlen(arg) > 2) {
+-					strcpy(connection, &arg[2]);
+-
+-					tok = strtok(connection, "/");
++					tok = strtok(arg + 2, "/");
+ 					if (!tok)
+ 						return FALSE;
+ 					pdata->sserver = strdup(tok);
+@@ -265,9 +259,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 			case 'D':
+ 				pdata->Dflag++;
+ 				if (strlen(arg) > 2) {
+-					strcpy(connection, &arg[2]);
+-
+-					tok = strtok(connection, "/");
++					tok = strtok(arg + 2, "/");
+ 					if (!tok)
+ 						return FALSE;
+ 					pdata->dserver = strdup(tok);
+@@ -316,14 +308,11 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 				fprintf(stderr, "If -c is specified an owner for the table must be provided.\n");
+ 				return FALSE;
+ 			}
+-			strcpy(owner, arg);
+-			pdata->owner = strdup(owner);
++			pdata->owner = strdup(arg);
+ 			state = GET_NEXTARG;
+ 			break;
+ 		case GET_SOURCE:
+-			strcpy(connection, arg);
+-
+-			tok = strtok(connection, "/");
++			tok = strtok(arg, "/");
+ 			if (!tok)
+ 				return FALSE;
+ 			pdata->sserver = strdup(tok);
+@@ -352,9 +341,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA * pdata)
+ 			break;
+ 
+ 		case GET_DEST:
+-			strcpy(connection, arg);
+-
+-			tok = strtok(connection, "/");
++			tok = strtok(arg, "/");
+ 			if (!tok)
+ 				return FALSE;
+ 			pdata->dserver = strdup(tok);
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 86d9a2b..60e03c7 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -41,11 +41,12 @@
+ #endif
+ 
+ #include "tds.h"
++#include "replacements.h"
+ #include <sybfront.h>
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.49 2008/05/28 20:08:48 freddy77 Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.50 2008/12/11 12:31:31 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -170,7 +171,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 	}
+ 
+ 	/* argument 2 - the direction */
+-	strcpy(pdata->dbdirection, argv[2]);
++	tds_strlcpy(pdata->dbdirection, argv[2], sizeof(pdata->dbdirection));
+ 
+ 	if (strcmp(pdata->dbdirection, "in") == 0) {
+ 		pdata->direction = DB_IN;
+@@ -184,7 +185,8 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 	}
+ 
+ 	/* argument 3 - the datafile name */
+-	strcpy(pdata->hostfilename, argv[3]);
++	free(pdata->hostfilename);
++	pdata->hostfilename = strdup(argv[3]);
+ 
+ 	/* 
+ 	 * Get the rest of the arguments 
+@@ -203,7 +205,8 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 			break;
+ 		case 'f':
+ 			pdata->fflag++;
+-			strcpy(pdata->formatfile, optarg);
++			free(pdata->formatfile);
++			pdata->formatfile = strdup(optarg);
+ 			break;
+ 		case 'e':
+ 			pdata->eflag++;
+@@ -262,7 +265,8 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 			break;
+ 		case 'I':
+ 			pdata->Iflag++;
+-			strcpy(pdata->interfacesfile, optarg);
++			free(pdata->interfacesfile);
++			pdata->interfacesfile = strdup(optarg);
+ 			break;
+ 		case 'S':
+ 			pdata->Sflag++;
+diff --git a/src/apps/freebcp.h b/src/apps/freebcp.h
+index d3793ed..8d77f86 100644
+--- a/src/apps/freebcp.h
++++ b/src/apps/freebcp.h
+@@ -1,4 +1,4 @@
+-static char rcsid_freebcp_h[] = "$Id: freebcp.h,v 1.12 2006/10/06 21:28:20 jklowden Exp $";
++static char rcsid_freebcp_h[] = "$Id: freebcp.h,v 1.13 2008/12/11 12:31:31 freddy77 Exp $";
+ static void *no_unused_freebcp_h_warn[] = { rcsid_freebcp_h, no_unused_freebcp_h_warn };
+ 
+ enum states
+@@ -33,10 +33,10 @@ typedef struct pd
+ 	char *dbobject;
+ 	char dbdirection[10];
+ 	DBINT direction;
+-	char hostfilename[FILENAME_MAX + 1];
+-	char formatfile[FILENAME_MAX + 1];
++	char *hostfilename;
++	char *formatfile;
+ 	char *errorfile;
+-	char interfacesfile[FILENAME_MAX + 1];
++	char *interfacesfile;
+ 	int firstrow;
+ 	int lastrow;
+ 	int batchsize;
+
+commit 988978e97c09d1822b20ff8495c4b83e380d58fb
+Author: freddy77 <freddy77>
+Date:   Thu Dec 11 12:37:57 2008 +0000
+
+    add TDS_MUTEX_DECLARE
+
+diff --git a/ChangeLog b/ChangeLog
+index 9491b0d..8357e85 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Dec 11 13:36:33 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsthread.h src/dblib/dblib.c src/tds/log.c:
++	- add TDS_MUTEX_DECLARE
++
+ Thu Dec 11 13:29:50 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/Makefile.am src/apps/datacopy.c src/apps/freebcp.c:
+ 	* src/apps/freebcp.h:
+@@ -1029,4 +1033,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2675 2008/12/11 12:31:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2676 2008/12/11 12:37:57 freddy77 Exp $
+diff --git a/include/tdsthread.h b/include/tdsthread.h
+index 09e785b..fde1c52 100644
+--- a/include/tdsthread.h
++++ b/include/tdsthread.h
+@@ -21,13 +21,14 @@
+ #ifndef TDSTHREAD_H
+ #define TDSTHREAD_H 1
+ 
+-/* $Id: tdsthread.h,v 1.3 2005/07/06 12:35:37 freddy77 Exp $ */
++/* $Id: tdsthread.h,v 1.4 2008/12/11 12:37:57 freddy77 Exp $ */
+ 
+ #if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX)
+ 
+ #include <pthread.h>
+ 
+-#define TDS_MUTEX_DECLARE(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
++#define TDS_MUTEX_DECLARE(name) pthread_mutex_t name
++#define TDS_MUTEX_DEFINE(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+ #define TDS_MUTEX_LOCK(a) pthread_mutex_lock(a)
+ #define TDS_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
+ #define TDS_MUTEX_T pthread_mutex_t
+@@ -42,6 +43,7 @@
+ #else
+ 
+ #define TDS_MUTEX_DECLARE(name) int name
++#define TDS_MUTEX_DEFINE(name) int name
+ #define TDS_MUTEX_LOCK(a)
+ #define TDS_MUTEX_UNLOCK(a)
+ #define TDS_MUTEX_T int
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 3727a30..94838ad 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.333 2008/12/10 14:56:26 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.334 2008/12/11 12:37:57 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -208,7 +208,7 @@ typedef struct dblib_context
+ DBLIBCONTEXT;
+ 
+ static DBLIBCONTEXT g_dblib_ctx;
+-static TDS_MUTEX_DECLARE(dblib_mutex);
++static TDS_MUTEX_DEFINE(dblib_mutex);
+ 
+ static int g_dblib_version =
+ #ifdef TDS42
+diff --git a/src/tds/log.c b/src/tds/log.c
+index bb40ee4..58518e1 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.7 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.8 2008/12/11 12:37:57 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALLLVL | TDS_DBGFLAG_SOURCE;
+@@ -74,7 +74,7 @@ int tds_g_append_mode = 0;
+ static char *g_dump_filename = NULL;
+ static int write_dump = 0;	/* is TDS stream debug log turned on? */
+ static FILE *g_dumpfile = NULL;	/* file pointer for dump log          */
+-static TDS_MUTEX_DECLARE(g_dump_mutex);
++static TDS_MUTEX_DEFINE(g_dump_mutex);
+ 
+ static FILE* tdsdump_append(void);
+ 
+
+commit af94b76a0a08097bdfc2d70c985aebe13a562a28
+Author: freddy77 <freddy77>
+Date:   Fri Dec 12 13:56:11 2008 +0000
+
+    start putting some BCP stuff into libTDS
+
+diff --git a/ChangeLog b/ChangeLog
+index 8357e85..fbf2c02 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Dec 12 14:53:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/ctlib.h include/dblib.h include/tds.h src/ctlib/blk.c:
++	* src/dblib/bcp.c src/tds/Makefile.am src/tds/bulk.c(added):
++	- start putting some BCP stuff into libTDS
++
+ Thu Dec 11 13:36:33 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsthread.h src/dblib/dblib.c src/tds/log.c:
+ 	- add TDS_MUTEX_DECLARE
+@@ -1033,4 +1038,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2676 2008/12/11 12:37:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2677 2008/12/12 13:56:11 freddy77 Exp $
+diff --git a/include/ctlib.h b/include/ctlib.h
+index f0e41e7..55924f8 100644
+--- a/include/ctlib.h
++++ b/include/ctlib.h
+@@ -36,7 +36,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.25 2007/06/25 09:48:20 freddy77 Exp $";
++static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.26 2008/12/12 13:56:11 freddy77 Exp $";
+ static const void *const no_unused_ctlib_h_warn[] = { rcsid_ctlib_h, no_unused_ctlib_h_warn };
+ 
+ #include <tds.h>
+@@ -238,18 +238,11 @@ struct _cs_command_list
+ 	struct _cs_command *cmd;
+ 	struct _cs_command_list *next;
+ };
+- 
++
+ struct _cs_blkdesc
+ {
+ 	CS_CONNECTION *con;
+-	CS_CHAR *tablename;
+-	CS_CHAR *insert_stmt;
+-	CS_INT direction;
+-	CS_INT identity_insert_on;
+-	CS_INT bind_count;
+-	CS_INT xfer_init;
+-	CS_INT var_cols;
+-	TDSRESULTINFO *bindinfo;
++	TDSBCPINFO bcpinfo;
+ };
+ 
+ 
+diff --git a/include/dblib.h b/include/dblib.h
+index eb72b99..9da44de 100644
+--- a/include/dblib.h
++++ b/include/dblib.h
+@@ -32,7 +32,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: dblib.h,v 1.44 2008/11/12 00:47:25 jklowden Exp $ */
++/* $Id: dblib.h,v 1.45 2008/12/12 13:56:11 freddy77 Exp $ */
+ 
+ typedef enum tag_DB_RESULT_STATE {
+ 	  _DB_RES_INIT
+@@ -86,19 +86,6 @@ typedef struct
+ 	TDS_INT batch;
+ } BCP_HOSTFILEINFO;
+ 
+-typedef struct
+-{
+-	const char *hint;
+-	TDS_CHAR *tablename;
+-	TDS_CHAR *insert_stmt;
+-	TDS_INT direction;
+-	TDS_INT queryout;
+-	TDS_INT identity_insert_on;
+-	TDS_INT xfer_init;
+-	TDS_INT var_cols;
+-	TDS_INT bind_count;
+-	TDSRESULTINFO *bindinfo;
+-} DB_BCPINFO;
+ /* linked list of rpc parameters */
+ 
+ typedef struct _DBREMOTE_PROC_PARAM
+@@ -160,7 +147,7 @@ struct tds_dblib_dbprocess
+ 	DBOPTION *dbopts;
+ 	DBSTRING *dboptcmd;
+ 	BCP_HOSTFILEINFO *hostfileinfo;
+-	DB_BCPINFO *bcpinfo;
++	TDSBCPINFO *bcpinfo;
+ 	DBREMOTE_PROC *rpc;
+ 	DBUSMALLINT envchange_rcv;
+ 	char dbcurdb[DBMAXNAME + 1];
+diff --git a/include/tds.h b/include/tds.h
+index b16c057..2149602 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.301 2008/12/10 14:56:26 freddy77 Exp $ */
++/* $Id: tds.h,v 1.302 2008/12/12 13:56:11 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -292,6 +292,7 @@ typedef enum {	TDSEICONVIU    = 2400,
+ 		TDSEWRIT = 20006, 
+ 		TDSESOCK = 20008, 
+ 		TDSECONN = 20009, 
++		TDSEMEM  = 20010,
+ 		TDSEPWD  = 20014, 
+ 		TDSESEOF = 20017, 
+ 		TDSERPND = 20019, 
+@@ -305,6 +306,7 @@ typedef enum {	TDSEICONVIU    = 2400,
+ 		TDSENEG  = 20210, 
+ 		TDSEUMSG = 20212, 
+ 		TDSECAPTYP  = 20213, 
++		TDSEBPROBADTYP = 20250,
+ 		TDSECLOSEIN = 20292 
+ } TDSERRNO;
+ 
+@@ -1585,6 +1587,23 @@ void tds_getmac(int s, unsigned char mac[6]);
+ TDSAUTHENTICATION * tds_ntlm_get_auth(TDSSOCKET * tds);
+ TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds);
+ 
++/* bulk.c */
++typedef struct tds_bcpinfo
++{
++	const char *hint;
++	void *parent;
++	TDS_CHAR *tablename;
++	TDS_CHAR *insert_stmt;
++	TDS_INT direction;
++	TDS_INT identity_insert_on;
++	TDS_INT xfer_init;
++	TDS_INT var_cols;
++	TDS_INT bind_count;
++	TDSRESULTINFO *bindinfo;
++} TDSBCPINFO;
++
++int tds_bcp_start_insert_stmt(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++
+ #define IS_TDS42(x) (x->major_version==4 && x->minor_version==2)
+ #define IS_TDS46(x) (x->major_version==4 && x->minor_version==6)
+ #define IS_TDS50(x) (x->major_version==5 && x->minor_version==0)
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 136d12a..881fe89 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,20 +38,13 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-typedef struct _pbcb
+-{
+-	char *pb;
+-	unsigned int cb;
+-} TDS_PBCB;
+-
+-TDS_RCSID(var, "$Id: blk.c,v 1.43 2007/12/31 10:06:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.44 2008/12/12 13:56:11 freddy77 Exp $");
+ 
+ static CS_RETCODE _blk_get_col_data(CS_BLKDESC *, TDSCOLUMN *, int );
+ static int _blk_add_variable_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start, int *var_cols);
+ static CS_RETCODE _blk_add_fixed_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start);
+ static CS_RETCODE _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset);
+ static CS_RETCODE _blk_send_colmetadata(CS_BLKDESC * blkdesc);
+-static CS_RETCODE _blk_build_bulk_insert_stmt(TDS_PBCB * clause, TDSCOLUMN * bcpcol, int first);
+ static CS_RETCODE _rowxfer_in_init(CS_BLKDESC * blkdesc);
+ static CS_RETCODE _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+ static CS_RETCODE _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+@@ -89,9 +82,9 @@ blk_bind(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buff
+ 	if (item == CS_UNUSED) {
+ 		/* clear all bindings */
+ 		if (datafmt == NULL && buffer == NULL && datalen == NULL && indicator == NULL ) { 
+-			blkdesc->bind_count = CS_UNUSED;
+-			for (i = 0; i < blkdesc->bindinfo->num_cols; i++ ) {
+-				colinfo = blkdesc->bindinfo->columns[i];
++			blkdesc->bcpinfo.bind_count = CS_UNUSED;
++			for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++ ) {
++				colinfo = blkdesc->bcpinfo.bindinfo->columns[i];
+ 				colinfo->column_varaddr  = NULL;
+ 				colinfo->column_bindtype = 0;
+ 				colinfo->column_bindfmt  = 0;
+@@ -105,7 +98,7 @@ blk_bind(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buff
+ 
+ 	/* check item value */
+ 
+-	if (item < 1 || item > blkdesc->bindinfo->num_cols) {
++	if (item < 1 || item > blkdesc->bcpinfo.bindinfo->num_cols) {
+ 		_ctclient_msg(con, "blk_bind", 2, 5, 1, 141, "%s, %d", "colnum", item);
+ 		return CS_FAIL;
+ 	}
+@@ -114,7 +107,7 @@ blk_bind(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buff
+ 
+ 	if (datafmt == NULL && buffer == NULL && datalen == NULL && indicator == NULL ) { 
+ 
+-		colinfo = blkdesc->bindinfo->columns[item - 1];
++		colinfo = blkdesc->bcpinfo.bindinfo->columns[item - 1];
+ 		colinfo->column_varaddr  = NULL;
+ 		colinfo->column_bindtype = 0;
+ 		colinfo->column_bindfmt  = 0;
+@@ -134,19 +127,19 @@ blk_bind(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buff
+ 
+ 	/* first bind for this result set */
+ 
+-	if (blkdesc->bind_count == CS_UNUSED) {
+-		blkdesc->bind_count = bind_count;
++	if (blkdesc->bcpinfo.bind_count == CS_UNUSED) {
++		blkdesc->bcpinfo.bind_count = bind_count;
+ 	} else {
+ 		/* all subsequent binds for this result set - the bind counts must be the same */
+-		if (blkdesc->bind_count != bind_count) {
+-			_ctclient_msg(con, "blk_bind", 1, 1, 1, 137, "%d, %d", bind_count, blkdesc->bind_count);
++		if (blkdesc->bcpinfo.bind_count != bind_count) {
++			_ctclient_msg(con, "blk_bind", 1, 1, 1, 137, "%d, %d", bind_count, blkdesc->bcpinfo.bind_count);
+ 			return CS_FAIL;
+ 		}
+ 	}
+ 
+ 	/* bind the column_varaddr to the address of the buffer */
+ 
+-	colinfo = blkdesc->bindinfo->columns[item - 1];
++	colinfo = blkdesc->bcpinfo.bindinfo->columns[item - 1];
+ 
+ 	colinfo->column_varaddr = (char *) buffer;
+ 	colinfo->column_bindtype = datafmt->datatype;
+@@ -186,12 +179,12 @@ blk_describe(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "blk_describe()\n");
+ 
+-	if (item < 1 || item > blkdesc->bindinfo->num_cols) {
++	if (item < 1 || item > blkdesc->bcpinfo.bindinfo->num_cols) {
+ 		_ctclient_msg(blkdesc->con, "blk_describe", 2, 5, 1, 141, "%s, %d", "colnum", item);
+ 		return CS_FAIL;
+ 	}
+ 
+-	curcol = blkdesc->bindinfo->columns[item - 1];
++	curcol = blkdesc->bcpinfo.bindinfo->columns[item - 1];
+ 	len = curcol->column_namelen;
+ 	if (len >= CS_MAX_NAME)
+ 		len = CS_MAX_NAME - 1;
+@@ -247,7 +240,7 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow)
+ 		if (outrow) 
+ 			*outrow = tds->rows_affected;
+ 		
+-		tds_submit_query(tds, blkdesc->insert_stmt);
++		tds_submit_query(tds, blkdesc->bcpinfo.insert_stmt);
+ 		if (tds_process_simple_query(tds) != TDS_SUCCEED) {
+ 			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");
+ 			return CS_FAIL;
+@@ -276,21 +269,21 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow)
+ 		
+ 		/* free allocated storage in blkdesc & initialise flags, etc. */
+ 	
+-		if (blkdesc->tablename)
+-			TDS_ZERO_FREE(blkdesc->tablename);
++		if (blkdesc->bcpinfo.tablename)
++			TDS_ZERO_FREE(blkdesc->bcpinfo.tablename);
+ 	
+-		if (blkdesc->insert_stmt)
+-			TDS_ZERO_FREE(blkdesc->insert_stmt);
++		if (blkdesc->bcpinfo.insert_stmt)
++			TDS_ZERO_FREE(blkdesc->bcpinfo.insert_stmt);
+ 	
+-		if (blkdesc->bindinfo) {
+-			tds_free_results(blkdesc->bindinfo);
+-			blkdesc->bindinfo = NULL;
++		if (blkdesc->bcpinfo.bindinfo) {
++			tds_free_results(blkdesc->bcpinfo.bindinfo);
++			blkdesc->bcpinfo.bindinfo = NULL;
+ 		}
+ 	
+-		blkdesc->direction = 0;
+-		blkdesc->bind_count = CS_UNUSED;
+-		blkdesc->xfer_init = 0;
+-		blkdesc->var_cols = 0;
++		blkdesc->bcpinfo.direction = 0;
++		blkdesc->bcpinfo.bind_count = CS_UNUSED;
++		blkdesc->bcpinfo.xfer_init = 0;
++		blkdesc->bcpinfo.var_cols = 0;
+ 
+ 		break;
+ 
+@@ -305,9 +298,9 @@ blk_drop(CS_BLKDESC * blkdesc)
+ 	if (!blkdesc)
+ 		return CS_SUCCEED;
+ 
+-	free(blkdesc->tablename);
+-	free(blkdesc->insert_stmt);
+-	tds_free_results(blkdesc->bindinfo);
++	free(blkdesc->bcpinfo.tablename);
++	free(blkdesc->bcpinfo.insert_stmt);
++	tds_free_results(blkdesc->bcpinfo.bindinfo);
+ 	free(blkdesc);
+ 
+ 	return CS_SUCCEED;
+@@ -360,37 +353,37 @@ blk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tna
+ 
+ 	/* free allocated storage in blkdesc & initialise flags, etc. */
+ 
+-	if (blkdesc->tablename) {
++	if (blkdesc->bcpinfo.tablename) {
+ 		tdsdump_log(TDS_DBG_FUNC, "blk_init() freeing tablename\n");
+-		free(blkdesc->tablename);
++		free(blkdesc->bcpinfo.tablename);
+ 	}
+ 
+-	if (blkdesc->insert_stmt) {
++	if (blkdesc->bcpinfo.insert_stmt) {
+ 		tdsdump_log(TDS_DBG_FUNC, "blk_init() freeing insert_stmt\n");
+-		TDS_ZERO_FREE(blkdesc->insert_stmt);
++		TDS_ZERO_FREE(blkdesc->bcpinfo.insert_stmt);
+ 	}
+ 
+-	if (blkdesc->bindinfo) {
++	if (blkdesc->bcpinfo.bindinfo) {
+ 		tdsdump_log(TDS_DBG_FUNC, "blk_init() freeing results\n");
+-		tds_free_results(blkdesc->bindinfo);
+-		blkdesc->bindinfo = NULL;
++		tds_free_results(blkdesc->bcpinfo.bindinfo);
++		blkdesc->bcpinfo.bindinfo = NULL;
+ 	}
+ 
+ 	/* string can be no-nul terminated so copy with memcpy */
+-	blkdesc->tablename = (char *) malloc(tnamelen + 1);
++	blkdesc->bcpinfo.tablename = (char *) malloc(tnamelen + 1);
+ 	/* FIXME malloc can fail */
+-	memcpy(blkdesc->tablename, tablename, tnamelen);
+-	blkdesc->tablename[tnamelen] = 0;
++	memcpy(blkdesc->bcpinfo.tablename, tablename, tnamelen);
++	blkdesc->bcpinfo.tablename[tnamelen] = 0;
+ 
+-	blkdesc->direction = direction;
+-	blkdesc->bind_count = CS_UNUSED;
+-	blkdesc->xfer_init = 0;
+-	blkdesc->var_cols = 0;
++	blkdesc->bcpinfo.direction = direction;
++	blkdesc->bcpinfo.bind_count = CS_UNUSED;
++	blkdesc->bcpinfo.xfer_init = 0;
++	blkdesc->bcpinfo.var_cols = 0;
+ 
+ 	tds = blkdesc->con->tds_socket;
+ 
+ 	/* TODO quote tablename if needed */
+-	if (tds_submit_queryf(tds, "select * from %s where 0 = 1", blkdesc->tablename) == TDS_FAIL) {
++	if (tds_submit_queryf(tds, "select * from %s where 0 = 1", blkdesc->bcpinfo.tablename) == TDS_FAIL) {
+ 		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+ 		return CS_FAIL;
+ 	}
+@@ -458,12 +451,12 @@ blk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tna
+ 	/* TODO check */
+ 	tds_alloc_row(bindinfo);
+ 
+-	blkdesc->bindinfo = bindinfo;
+-	blkdesc->bind_count = CS_UNUSED;
++	blkdesc->bcpinfo.bindinfo = bindinfo;
++	blkdesc->bcpinfo.bind_count = CS_UNUSED;
+ 
+-	if (blkdesc->identity_insert_on) {
++	if (blkdesc->bcpinfo.identity_insert_on) {
+ 
+-		if (tds_submit_queryf(tds, "set identity_insert %s on", blkdesc->tablename) == TDS_FAIL) {
++		if (tds_submit_queryf(tds, "set identity_insert %s on", blkdesc->bcpinfo.tablename) == TDS_FAIL) {
+ 			_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+ 			return CS_FAIL;
+ 		}
+@@ -494,14 +487,14 @@ blk_props(CS_BLKDESC * blkdesc, CS_INT action, CS_INT property, CS_VOID * buffer
+ 			if (buffer) {
+ 				memcpy(&intval, buffer, sizeof(intval));
+ 				if (intval == CS_TRUE)
+-					blkdesc->identity_insert_on = 1;
++					blkdesc->bcpinfo.identity_insert_on = 1;
+ 				if (intval == CS_FALSE)
+-					blkdesc->identity_insert_on = 0;
++					blkdesc->bcpinfo.identity_insert_on = 0;
+ 			}
+ 			return CS_SUCCEED;
+ 			break;
+ 		case CS_GET:
+-			retval = blkdesc->identity_insert_on == 1 ? CS_TRUE : CS_FALSE ;
++			retval = blkdesc->bcpinfo.identity_insert_on == 1 ? CS_TRUE : CS_FALSE ;
+ 			if (buffer) {
+ 				memcpy (buffer, &retval, sizeof(retval));
+ 				if (outlen)
+@@ -549,19 +542,18 @@ blk_rowxfer(CS_BLKDESC * blkdesc)
+ CS_RETCODE
+ blk_rowxfer_mult(CS_BLKDESC * blkdesc, CS_INT * row_count)
+ {
+-
+-	int rows_to_xfer = 0;
+-	int rows_xferred = 0;
++	CS_INT rows_to_xfer = 0;
++	CS_INT rows_xferred = 0;
+ 	CS_RETCODE ret;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "blk_rowxfer_mult()\n");
+ 
+ 	if (!row_count || *row_count == 0 )
+-		rows_to_xfer = blkdesc->bind_count;
++		rows_to_xfer = blkdesc->bcpinfo.bind_count;
+ 	else
+ 		rows_to_xfer = *row_count;
+ 
+-	if (blkdesc->direction == CS_BLK_IN) {
++	if (blkdesc->bcpinfo.direction == CS_BLK_IN) {
+ 		ret = _blk_rowxfer_in(blkdesc, rows_to_xfer, &rows_xferred);
+ 	} else {
+ 		ret = _blk_rowxfer_out(blkdesc, rows_to_xfer, &rows_xferred);
+@@ -627,9 +619,9 @@ _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferre
+ 	 * do the query and get to the row data...
+ 	 */
+ 
+-	if (blkdesc->xfer_init == 0) {
++	if (blkdesc->bcpinfo.xfer_init == 0) {
+ 
+-		if (tds_submit_queryf(tds, "select * from %s", blkdesc->tablename)
++		if (tds_submit_queryf(tds, "select * from %s", blkdesc->bcpinfo.tablename)
+ 			== TDS_FAIL) {
+ 			_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 5, 1, 140, "");
+ 			return CS_FAIL;
+@@ -645,7 +637,7 @@ _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferre
+ 			return CS_FAIL;
+ 		}
+ 
+-		blkdesc->xfer_init = 1;
++		blkdesc->bcpinfo.xfer_init = 1;
+ 	}
+ 
+ 	row_of_query = 0;
+@@ -664,7 +656,7 @@ _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferre
+ 		case TDS_SUCCEED:
+ 			if (result_type == TDS_ROW_RESULT || result_type == TDS_COMPUTE_RESULT) {
+ 				if (result_type == TDS_ROW_RESULT) {
+-					if (_ct_bind_data( blkdesc->con->ctx, tds->current_results, blkdesc->bindinfo, temp_count))
++					if (_ct_bind_data( blkdesc->con->ctx, tds->current_results, blkdesc->bcpinfo.bindinfo, temp_count))
+ 						return CS_ROW_FAIL;
+ 					if (rows_xferred)
+ 						*rows_xferred = *rows_xferred + 1;
+@@ -702,7 +694,7 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 	 * do the query and get to the row data...
+ 	 */
+ 
+-	if (blkdesc->xfer_init == 0) {
++	if (blkdesc->bcpinfo.xfer_init == 0) {
+ 
+ 		/*
+ 		 * first call the start_copy function, which will
+@@ -720,7 +712,7 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 			_blk_send_colmetadata(blkdesc);
+ 		}
+ 
+-		blkdesc->xfer_init = 1;
++		blkdesc->bcpinfo.xfer_init = 1;
+ 	} 
+ 
+ 	for (each_row = 0; each_row < rows_to_xfer; each_row++ ) {
+@@ -741,62 +733,16 @@ _rowxfer_in_init(CS_BLKDESC * blkdesc)
+ 	TDSCOLUMN *bcpcol;
+ 
+ 	int i;
+-	int firstcol;
+ 
+ 	int fixed_col_len_tot     = 0;
+ 	int variable_col_len_tot  = 0;
+ 	int column_bcp_data_size  = 0;
+ 	int bcp_record_size       = 0;
++	
++	TDSBCPINFO *bcpinfo = &blkdesc->bcpinfo;
+ 
+-	char *query;
+-	char clause_buffer[4096] = { 0 };
+-
+-	TDS_PBCB colclause;
+-
+-	colclause.pb = clause_buffer;
+-	colclause.cb = sizeof(clause_buffer);
+-
+-	if (IS_TDS7_PLUS(tds)) {
+-		int erc;
+-
+-		firstcol = 1;
+-
+-		for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
+-			bcpcol = blkdesc->bindinfo->columns[i];
+-			if (blkdesc->identity_insert_on) {
+-				if (!bcpcol->column_timestamp) {
+-					_blk_build_bulk_insert_stmt(&colclause, bcpcol, firstcol);
+-					firstcol = 0;
+-				}
+-			} else {
+-				if (!bcpcol->column_identity && !bcpcol->column_timestamp) {
+-					_blk_build_bulk_insert_stmt(&colclause, bcpcol, firstcol);
+-					firstcol = 0;
+-				}
+-			}
+-		}
+-
+-		erc = asprintf(&query, "insert bulk %s (%s)", blkdesc->tablename, colclause.pb);
+-
+-		if (colclause.pb != clause_buffer)
+-			TDS_ZERO_FREE(colclause.pb);	/* just for good measure; not used beyond this point */
+-
+-		if (erc < 0) {
+-			return CS_FAIL;
+-		}
+-
+-	} else {
+-		/* NOTE: if we use "with nodescribe" for following inserts server do not send describe */
+-		if (asprintf(&query, "insert bulk %s", blkdesc->tablename) < 0) {
+-			return CS_FAIL;
+-		}
+-	}
+-
+-	tds_submit_query(tds, query);
+-
+-	/* save the statement for later... */
+-
+-	blkdesc->insert_stmt = query;
++	if (tds_bcp_start_insert_stmt(tds, bcpinfo) == TDS_FAIL)
++		return CS_FAIL;
+ 
+ 	/*
+ 	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
+@@ -814,12 +760,12 @@ _rowxfer_in_init(CS_BLKDESC * blkdesc)
+ 	 * Work out the number of "variable" columns.  These are either nullable or of 
+ 	 * varying length type e.g. varchar.   
+ 	 */
+-	blkdesc->var_cols = 0;
++	bcpinfo->var_cols = 0;
+ 
+ 	if (IS_TDS50(tds)) {
+-		for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+ 	
+-			bcpcol = blkdesc->bindinfo->columns[i];
++			bcpcol = bcpinfo->bindinfo->columns[i];
+ 
+ 			/*
+ 			 * work out storage required for this datatype
+@@ -840,7 +786,7 @@ _rowxfer_in_init(CS_BLKDESC * blkdesc)
+ 			 */
+ 
+ 			if (is_nullable_type(bcpcol->on_server.column_type) || bcpcol->column_nullable) {
+-				blkdesc->var_cols++;
++				bcpinfo->var_cols++;
+ 				variable_col_len_tot += column_bcp_data_size;
+ 			}
+ 			else {
+@@ -854,176 +800,22 @@ _rowxfer_in_init(CS_BLKDESC * blkdesc)
+ 							fixed_col_len_tot +
+ 							variable_col_len_tot +
+ 							( (int)(variable_col_len_tot / 256 ) + 1 ) +
+-							(blkdesc->var_cols + 1) +
++							(bcpinfo->var_cols + 1) +
+ 							2;
+ 
+-		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", blkdesc->bindinfo->row_size);
++		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
+ 		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
+ 
+-		if (bcp_record_size > blkdesc->bindinfo->row_size) {
+-			blkdesc->bindinfo->current_row = realloc(blkdesc->bindinfo->current_row, bcp_record_size);
+-			if (blkdesc->bindinfo->current_row == NULL) {
++		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
++			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
++			if (bcpinfo->bindinfo->current_row == NULL) {
+ 				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
+ 				return CS_FAIL;
+ 			}
+-			blkdesc->bindinfo->row_size = bcp_record_size;
+-		}
+-	}
+-
+-	return CS_SUCCEED;
+-}
+-
+-static CS_RETCODE
+-_blk_build_bulk_insert_stmt(TDS_PBCB * clause, TDSCOLUMN * bcpcol, int first)
+-{
+-	char buffer[32];
+-	char *column_type = buffer;
+-
+-	switch (bcpcol->on_server.column_type) {
+-	case SYBINT1:
+-		column_type = "tinyint";
+-		break;
+-	case SYBBIT:
+-		column_type = "bit";
+-		break;
+-	case SYBINT2:
+-		column_type = "smallint";
+-		break;
+-	case SYBINT4:
+-		column_type = "int";
+-		break;
+-	case SYBINT8:
+-		column_type = "bigint";
+-		break;
+-	case SYBDATETIME:
+-		column_type = "datetime";
+-		break;
+-	case SYBDATETIME4:
+-		column_type = "smalldatetime";
+-		break;
+-	case SYBREAL:
+-		column_type = "real";
+-		break;
+-	case SYBMONEY:
+-		column_type = "money";
+-		break;
+-	case SYBMONEY4:
+-		column_type = "smallmoney";
+-		break;
+-	case SYBFLT8:
+-		column_type = "float";
+-		break;
+-
+-	case SYBINTN:
+-		switch (bcpcol->column_size) {
+-		case 1:
+-			column_type = "tinyint";
+-			break;
+-		case 2:
+-			column_type = "smallint";
+-			break;
+-		case 4:
+-			column_type = "int";
+-			break;
+-		case 8:
+-			column_type = "bigint";
+-			break;
+-		}
+-		break;
+-
+-	case SYBBITN:
+-		column_type = "bit";
+-		break;
+-	case SYBFLTN:
+-		switch (bcpcol->column_size) {
+-		case 4:
+-			column_type = "real";
+-			break;
+-		case 8:
+-			column_type = "float";
+-			break;
+-		}
+-		break;
+-	case SYBMONEYN:
+-		switch (bcpcol->column_size) {
+-		case 4:
+-			column_type = "smallmoney";
+-			break;
+-		case 8:
+-			column_type = "money";
+-			break;
+-		}
+-		break;
+-	case SYBDATETIMN:
+-		switch (bcpcol->column_size) {
+-		case 4:
+-			column_type = "smalldatetime";
+-			break;
+-		case 8:
+-			column_type = "datetime";
+-			break;
++			bcpinfo->bindinfo->row_size = bcp_record_size;
+ 		}
+-		break;
+-	case SYBDECIMAL:
+-		sprintf(column_type, "decimal(%d,%d)", bcpcol->column_prec, bcpcol->column_scale);
+-		break;
+-	case SYBNUMERIC:
+-		sprintf(column_type, "numeric(%d,%d)", bcpcol->column_prec, bcpcol->column_scale);
+-		break;
+-
+-	case XSYBVARBINARY:
+-		sprintf(column_type, "varbinary(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBVARCHAR:
+-		sprintf(column_type, "varchar(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBBINARY:
+-		sprintf(column_type, "binary(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBCHAR:
+-		sprintf(column_type, "char(%d)", bcpcol->column_size);
+-		break;
+-	case SYBTEXT:
+-		sprintf(column_type, "text");
+-		break;
+-	case SYBIMAGE:
+-		sprintf(column_type, "image");
+-		break;
+-	case XSYBNVARCHAR:
+-		sprintf(column_type, "nvarchar(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBNCHAR:
+-		sprintf(column_type, "nchar(%d)", bcpcol->column_size);
+-		break;
+-	case SYBNTEXT:
+-		sprintf(column_type, "ntext");
+-		break;
+-	case SYBUNIQUE:
+-		sprintf(column_type, "uniqueidentifier");
+-		break;
+-	default:
+-		tdsdump_log(TDS_DBG_FUNC, "error: cannot build bulk insert statement. unrecognized server datatype %d\n",
+-					bcpcol->on_server.column_type);
+-		return CS_FAIL;
+ 	}
+ 
+-	if (clause->cb < strlen(clause->pb) + strlen(bcpcol->column_name) + strlen(column_type) + ((first) ? 2u : 4u)) {
+-		char *temp = malloc(2 * clause->cb);
+-
+-		if (!temp)
+-			return CS_FAIL;
+-		strcpy(temp, clause->pb);
+-		clause->pb = temp;
+-		clause->cb *= 2;
+-	}
+-
+-	if (!first)
+-		strcat(clause->pb, ", ");
+-
+-	strcat(clause->pb, bcpcol->column_name);
+-	strcat(clause->pb, " ");
+-	strcat(clause->pb, column_type);
+-
+ 	return CS_SUCCEED;
+ }
+ 
+@@ -1043,9 +835,9 @@ _blk_send_colmetadata(CS_BLKDESC * blkdesc)
+ 	tds_put_byte(tds, colmetadata_token);	/* 0x81 */
+ 
+ 	num_cols = 0;
+-	for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
+-		bcpcol = blkdesc->bindinfo->columns[i];
+-		if ((!blkdesc->identity_insert_on && bcpcol->column_identity) || 
++	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
++		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
++		if ((!blkdesc->bcpinfo.identity_insert_on && bcpcol->column_identity) || 
+ 			bcpcol->column_timestamp) {
+ 			continue;
+ 		}
+@@ -1054,15 +846,15 @@ _blk_send_colmetadata(CS_BLKDESC * blkdesc)
+ 
+ 	tds_put_smallint(tds, num_cols);
+ 
+-	for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
+-		bcpcol = blkdesc->bindinfo->columns[i];
++	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
++		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+ 
+ 		/*
+ 		 * dont send the (meta)data for timestamp columns, or
+ 		 * identity columns (unless indentity_insert is enabled
+ 		 */
+ 
+-		if ((!blkdesc->identity_insert_on && bcpcol->column_identity) || 
++		if ((!blkdesc->bcpinfo.identity_insert_on && bcpcol->column_identity) || 
+ 			bcpcol->column_timestamp) {
+ 			continue;
+ 		}
+@@ -1099,8 +891,8 @@ _blk_send_colmetadata(CS_BLKDESC * blkdesc)
+ 			tds_put_n(tds, bcpcol->column_collation, 5);
+ 		}
+ 		if (is_blob_type(bcpcol->on_server.column_type)) {
+-			tds_put_smallint(tds, strlen(blkdesc->tablename));
+-			tds_put_string(tds, blkdesc->tablename, strlen(blkdesc->tablename));
++			tds_put_smallint(tds, strlen(blkdesc->bcpinfo.tablename));
++			tds_put_string(tds, blkdesc->bcpinfo.tablename, strlen(blkdesc->bcpinfo.tablename));
+ 		}
+ 		/* FIXME support multibyte string */
+ 		tds_put_byte(tds, bcpcol->column_namelen);
+@@ -1145,22 +937,22 @@ _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_blk_build_bcp_record(offset %d)\n", offset);
+ 
+-	record = blkdesc->bindinfo->current_row;
+-	old_record_size = blkdesc->bindinfo->row_size;
++	record = blkdesc->bcpinfo.bindinfo->current_row;
++	old_record_size = blkdesc->bcpinfo.bindinfo->row_size;
+ 	new_record_size = 0;
+ 
+ 	if (IS_TDS7_PLUS(tds)) {
+ 
+-		for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
++		for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+ 	
+-			bindcol = blkdesc->bindinfo->columns[i];
++			bindcol = blkdesc->bcpinfo.bindinfo->columns[i];
+ 
+ 			/*
+ 			 * dont send the (meta)data for timestamp columns, or
+ 			 * identity columns (unless indentity_insert is enabled
+ 			 */
+ 
+-			if ((!blkdesc->identity_insert_on && bindcol->column_identity) || 
++			if ((!blkdesc->bcpinfo.identity_insert_on && bindcol->column_identity) || 
+ 				bindcol->column_timestamp) {
+ 				continue;
+ 			}
+@@ -1253,7 +1045,7 @@ _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset)
+ 		}
+ 
+ 		tds_put_byte(tds, row_token);   /* 0xd1 */
+-		tds_put_n(tds, blkdesc->bindinfo->current_row, new_record_size);
++		tds_put_n(tds, blkdesc->bcpinfo.bindinfo->current_row, new_record_size);
+ 	}  /* IS_TDS7_PLUS */
+ 	else {
+ 			memset(record, '\0', old_record_size);	/* zero the rowbuffer */
+@@ -1271,7 +1063,7 @@ _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset)
+ 
+ 			/* potential variable columns to write */
+ 
+-			if (blkdesc->var_cols) {
++			if (blkdesc->bcpinfo.var_cols) {
+ 				if ((row_pos = _blk_add_variable_columns(blkdesc, offset, record, row_pos, &var_cols_written)) == CS_FAIL)
+ 					return CS_FAIL;
+ 			}
+@@ -1293,8 +1085,8 @@ _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset)
+ 
+ 			blob_cols = 0;
+ 
+-			for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
+-				bindcol = blkdesc->bindinfo->columns[i];
++			for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
++				bindcol = blkdesc->bcpinfo.bindinfo->columns[i];
+ 				if (is_blob_type(bindcol->column_type)) {
+ 					if ((_blk_get_col_data(blkdesc, bindcol, offset)) != CS_SUCCEED) {
+ 			 			return CS_FAIL;
+@@ -1331,9 +1123,9 @@ _blk_add_fixed_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuff
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_blk_add_fixed_columns (offset %d)\n", offset);
+ 
+-	for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
++	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+ 
+-		bcpcol = blkdesc->bindinfo->columns[i];
++		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+ 
+ 		if (!is_nullable_type(bcpcol->column_type) && !(bcpcol->column_nullable)) {
+ 
+@@ -1405,9 +1197,9 @@ _blk_add_variable_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowb
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_blk_add_variable_columns (offset %d)\n", offset);
+ 
+-	for (i = 0; i < blkdesc->bindinfo->num_cols; i++) {
++	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+ 
+-		bcpcol = blkdesc->bindinfo->columns[i];
++		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+ 
+ 		/*
+ 		 * is this column of "variable" type, i.e. NULLable
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 4e780a0..bb6a2e1 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -63,15 +63,7 @@ typedef enum { BCP_REC_NOFETCH_DATA = 0, BCP_REC_FETCH_DATA = 1 } BEHAVIOUR;
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-typedef struct _pbcb
+-{
+-	char *pb;
+-	int cb;
+-	unsigned int from_malloc;
+-}
+-TDS_PBCB;
+-
+-TDS_RCSID(var, "$Id: bcp.c,v 1.173 2008/11/25 22:58:28 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.174 2008/12/12 13:56:11 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -88,7 +80,6 @@ typedef long offset_type;
+ #endif
+ 
+ static RETCODE _bcp_send_bcp_record(DBPROCESS * dbproc, BEHAVIOUR behaviour);
+-static RETCODE _bcp_build_bulk_insert_stmt(TDSSOCKET *, TDS_PBCB *, TDSCOLUMN *, int);
+ static void _bcp_free_storage(DBPROCESS * dbproc);
+ static void _bcp_free_columns(DBPROCESS * dbproc);
+ static RETCODE _bcp_get_col_data(DBPROCESS * dbproc, TDSCOLUMN *bindcol);
+@@ -186,7 +177,7 @@ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char
+ 
+ 	/* Allocate storage */
+ 	
+-	dbproc->bcpinfo = calloc(1, sizeof(DB_BCPINFO));
++	dbproc->bcpinfo = calloc(1, sizeof(TDSBCPINFO));
+ 	if (dbproc->bcpinfo == NULL)
+ 		goto memory_error;
+ 
+@@ -2125,75 +2116,19 @@ _bcp_start_copy_in(DBPROCESS * dbproc)
+ {
+ 	TDSSOCKET *tds = dbproc->tds_socket;
+ 	TDSCOLUMN *bcpcol;
+-	int i, firstcol;
++	int i;
+ 	int fixed_col_len_tot     = 0;
+ 	int variable_col_len_tot  = 0;
+ 	int column_bcp_data_size  = 0;
+ 	int bcp_record_size       = 0;
+-	char *query;
++	TDSBCPINFO *bcpinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_bcp_start_copy_in(%p)\n", dbproc);
+ 	assert(dbproc);
++	bcpinfo = dbproc->bcpinfo;
+ 
+-	if (IS_TDS7_PLUS(tds)) {
+-		int erc;
+-		char *hint;
+-		TDS_PBCB colclause;
+-		char clause_buffer[4096] = { 0 };
+-
+-		colclause.pb = clause_buffer;
+-		colclause.cb = sizeof(clause_buffer);
+-		colclause.from_malloc = 0;
+-
+-		firstcol = 1;
+-
+-		for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-			bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
+-
+-			if (dbproc->bcpinfo->identity_insert_on) {
+-				if (!bcpcol->column_timestamp) {
+-					_bcp_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
+-					firstcol = 0;
+-				}
+-			} else {
+-				if (!bcpcol->column_identity && !bcpcol->column_timestamp) {
+-					_bcp_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
+-					firstcol = 0;
+-				}
+-			}
+-		}
+-
+-		if (dbproc->bcpinfo->hint) {
+-			if (asprintf(&hint, " with (%s)", dbproc->bcpinfo->hint) < 0) {
+-				return FAIL;
+-			}
+-		} else {
+-			hint = strdup("");
+-		}
+-		if (!hint)
+-			return FAIL;
+-
+-		erc = asprintf(&query, "insert bulk %s (%s) %s", dbproc->bcpinfo->tablename, colclause.pb, hint);
+-
+-		free(hint);
+-		if (colclause.from_malloc)
+-			TDS_ZERO_FREE(colclause.pb);	/* just for good measure; not used beyond this point */
+-
+-		if (erc < 0) {
+-			return FAIL;
+-		}
+-
+-	} else {
+-		if (asprintf(&query, "insert bulk %s", dbproc->bcpinfo->tablename) < 0) {
+-			return FAIL;
+-		}
+-	}
+-
+-	tds_submit_query(tds, query);
+-
+-	/* save the statement for later... */
+-
+-	dbproc->bcpinfo->insert_stmt = query;
++	if (tds_bcp_start_insert_stmt(tds, bcpinfo) == TDS_FAIL)
++		return FAIL;
+ 
+ 	/*
+ 	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
+@@ -2206,16 +2141,18 @@ _bcp_start_copy_in(DBPROCESS * dbproc)
+ 	 * Work out the number of "variable" columns.  These are either nullable or of 
+ 	 * varying length type e.g. varchar.   
+ 	 */
+-	dbproc->bcpinfo->var_cols = 0;
++	bcpinfo->var_cols = 0;
+ 
+ 	if (IS_TDS50(tds)) {
+-		for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+ 	
+-			bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
++			bcpcol = bcpinfo->bindinfo->columns[i];
+ 
+-			/* work out storage required for thsi datatype */
+-			/* blobs always require 16, numerics vary, the */
+-			/* rest can be taken from the server           */
++			/*
++			 * work out storage required for this datatype
++			 * blobs always require 16, numerics vary, the
++			 * rest can be taken from the server
++			 */
+ 
+ 			if (is_blob_type(bcpcol->on_server.column_type))
+ 				column_bcp_data_size  = 16;
+@@ -2224,11 +2161,13 @@ _bcp_start_copy_in(DBPROCESS * dbproc)
+ 			else
+ 				column_bcp_data_size  = bcpcol->column_size;
+ 
+-			/* now add that size into either fixed or variable */
+-			/* column totals...                                */
++			/*
++			 * now add that size into either fixed or variable
++			 * column totals...
++			 */
+ 
+ 			if (is_nullable_type(bcpcol->on_server.column_type) || bcpcol->column_nullable) {
+-				dbproc->bcpinfo->var_cols++;
++				bcpinfo->var_cols++;
+ 				variable_col_len_tot += column_bcp_data_size;
+ 			}
+ 			else {
+@@ -2242,34 +2181,34 @@ _bcp_start_copy_in(DBPROCESS * dbproc)
+ 							fixed_col_len_tot +
+ 							variable_col_len_tot +
+ 							( (int)(variable_col_len_tot / 256 ) + 1 ) +
+-							(dbproc->bcpinfo->var_cols + 1) +
++							(bcpinfo->var_cols + 1) +
+ 							2;
+ 
+-		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", dbproc->bcpinfo->bindinfo->row_size);
++		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
+ 		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
+ 
+-		if (bcp_record_size > dbproc->bcpinfo->bindinfo->row_size) {
++		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
+ 			/* FIXME remove memory leak */
+-			dbproc->bcpinfo->bindinfo->current_row = realloc(dbproc->bcpinfo->bindinfo->current_row, bcp_record_size);
+-			dbproc->bcpinfo->bindinfo->row_free = bcp_row_free;
+-			if (dbproc->bcpinfo->bindinfo->current_row == NULL) {
++			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
++			bcpinfo->bindinfo->row_free = bcp_row_free;
++			if (bcpinfo->bindinfo->current_row == NULL) {
+ 				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
+ 				return FAIL;
+ 			}
+-			dbproc->bcpinfo->bindinfo->row_size = bcp_record_size;
++			bcpinfo->bindinfo->row_size = bcp_record_size;
+ 		}
+ 	}
+ 	if (IS_TDS7_PLUS(tds)) {
+-		for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+ 	
+-			bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
++			bcpcol = bcpinfo->bindinfo->columns[i];
+ 
+ 			/*
+ 			 * dont send the (meta)data for timestamp columns, or
+ 			 * identity columns (unless indentity_insert is enabled
+ 			 */
+ 
+-			if ((!dbproc->bcpinfo->identity_insert_on && bcpcol->column_identity) || 
++			if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || 
+ 				bcpcol->column_timestamp) {
+ 				continue;
+ 			}
+@@ -2297,198 +2236,20 @@ _bcp_start_copy_in(DBPROCESS * dbproc)
+ 				bcp_record_size += bcpcol->column_size;
+ 			}
+ 		}
+-		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", dbproc->bcpinfo->bindinfo->row_size);
++		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
+ 		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
+ 
+-		if (bcp_record_size > dbproc->bcpinfo->bindinfo->row_size) {
+-			dbproc->bcpinfo->bindinfo->current_row = realloc(dbproc->bcpinfo->bindinfo->current_row, bcp_record_size);
+-			dbproc->bcpinfo->bindinfo->row_free = bcp_row_free;
+-			if (dbproc->bcpinfo->bindinfo->current_row == NULL) {
++		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
++			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
++			bcpinfo->bindinfo->row_free = bcp_row_free;
++			if (bcpinfo->bindinfo->current_row == NULL) {
+ 				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
+ 				return FAIL;
+ 			}
+-			dbproc->bcpinfo->bindinfo->row_size = bcp_record_size;
+-		}
+-	}
+-
+-	return SUCCEED;
+-}
+-
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+- * \param tds 
+- * \param clause 
+- * \param bcpcol 
+- * \param first 
+- * 
+- * \return SUCCEED or FAIL.
+- * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+- */
+-static RETCODE
+-_bcp_build_bulk_insert_stmt(TDSSOCKET * tds, TDS_PBCB * clause, TDSCOLUMN * bcpcol, int first)
+-{
+-	char buffer[32];
+-	char *column_type = buffer;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_build_bulk_insert_stmt(%p, %p, %p, %d)\n", tds, clause, bcpcol, first);
+-
+-	/* TODO reuse function in tds/query.c */
+-	switch (bcpcol->on_server.column_type) {
+-	case SYBINT1:
+-		column_type = "tinyint";
+-		break;
+-	case SYBBIT:
+-		column_type = "bit";
+-		break;
+-	case SYBINT2:
+-		column_type = "smallint";
+-		break;
+-	case SYBINT4:
+-		column_type = "int";
+-		break;
+-	case SYBINT8:
+-		column_type = "bigint";
+-		break;
+-	case SYBDATETIME:
+-		column_type = "datetime";
+-		break;
+-	case SYBDATETIME4:
+-		column_type = "smalldatetime";
+-		break;
+-	case SYBREAL:
+-		column_type = "real";
+-		break;
+-	case SYBMONEY:
+-		column_type = "money";
+-		break;
+-	case SYBMONEY4:
+-		column_type = "smallmoney";
+-		break;
+-	case SYBFLT8:
+-		column_type = "float";
+-		break;
+-
+-	case SYBINTN:
+-		switch (bcpcol->column_size) {
+-		case 1:
+-			column_type = "tinyint";
+-			break;
+-		case 2:
+-			column_type = "smallint";
+-			break;
+-		case 4:
+-			column_type = "int";
+-			break;
+-		case 8:
+-			column_type = "bigint";
+-			break;
++			bcpinfo->bindinfo->row_size = bcp_record_size;
+ 		}
+-		break;
+-
+-	case SYBBITN:
+-		column_type = "bit";
+-		break;
+-	case SYBFLTN:
+-		switch (bcpcol->column_size) {
+-		case 4:
+-			column_type = "real";
+-			break;
+-		case 8:
+-			column_type = "float";
+-			break;
+-		}
+-		break;
+-	case SYBMONEYN:
+-		switch (bcpcol->column_size) {
+-		case 4:
+-			column_type = "smallmoney";
+-			break;
+-		case 8:
+-			column_type = "money";
+-			break;
+-		}
+-		break;
+-	case SYBDATETIMN:
+-		switch (bcpcol->column_size) {
+-		case 4:
+-			column_type = "smalldatetime";
+-			break;
+-		case 8:
+-			column_type = "datetime";
+-			break;
+-		}
+-		break;
+-	case SYBDECIMAL:
+-		sprintf(column_type, "decimal(%d,%d)", bcpcol->column_prec, bcpcol->column_scale);
+-		break;
+-	case SYBNUMERIC:
+-		sprintf(column_type, "numeric(%d,%d)", bcpcol->column_prec, bcpcol->column_scale);
+-		break;
+-
+-	case XSYBVARBINARY:
+-		sprintf(column_type, "varbinary(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBVARCHAR:
+-		sprintf(column_type, "varchar(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBBINARY:
+-		sprintf(column_type, "binary(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBCHAR:
+-		sprintf(column_type, "char(%d)", bcpcol->column_size);
+-		break;
+-	case SYBTEXT:
+-		sprintf(column_type, "text");
+-		break;
+-	case SYBIMAGE:
+-		sprintf(column_type, "image");
+-		break;
+-	case XSYBNVARCHAR:
+-		sprintf(column_type, "nvarchar(%d)", bcpcol->column_size);
+-		break;
+-	case XSYBNCHAR:
+-		sprintf(column_type, "nchar(%d)", bcpcol->column_size);
+-		break;
+-	case SYBNTEXT:
+-		sprintf(column_type, "ntext");
+-		break;
+-	case SYBUNIQUE:
+-		sprintf(column_type, "uniqueidentifier  ");
+-		break;
+-	default:
+-		dbperror( NULL, SYBEBPROBADTYP, 0);
+-		tdsdump_log(TDS_DBG_FUNC, "error: cannot build bulk insert statement. unrecognized server datatype %d\n",
+-				bcpcol->on_server.column_type);
+-		return FAIL;
+ 	}
+ 
+-	if (clause->cb < strlen(clause->pb) 
+-		       + tds_quote_id(tds, NULL, bcpcol->column_name, bcpcol->column_namelen) 
+-		       + strlen(column_type) 
+-		       + ((first) ? 2 : 4)) {
+-		char *temp = malloc(2 * clause->cb);
+-
+-		if (!temp) {
+-			dbperror(NULL, SYBEMEM, errno);
+-			return FAIL;
+-		}
+-		strcpy(temp, clause->pb);
+-		if (clause->from_malloc)
+-			free(clause->pb);
+-		clause->from_malloc = 1;
+-		clause->pb = temp;
+-		clause->cb *= 2;
+-	}
+-
+-	if (!first)
+-		strcat(clause->pb, ", ");
+-
+-	tds_quote_id(tds, strchr(clause->pb, 0), bcpcol->column_name, bcpcol->column_namelen);
+-	strcat(clause->pb, " ");
+-	strcat(clause->pb, column_type);
+-
+ 	return SUCCEED;
+ }
+ 
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index 4872270..a2d4974 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.67 2008/11/12 00:47:35 jklowden Exp $
++# $Id: Makefile.am,v 1.68 2008/12/12 13:56:11 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -9,7 +9,7 @@ libtds_la_SOURCES=	mem.c token.c util.c login.c read.c \
+ 	locale.c challenge.c threadsafe.c vstrbuild.c md4.c md5.c \
+ 	des.c tdsstring.c getmac.c data.c net.c \
+ 	tds_checks.c tds_checks.h enum_cap.h log.c \
+-	gssapi.c hmac_md5.c
++	gssapi.c hmac_md5.c bulk.c
+ libtds_la_LDFLAGS=
+ libtds_la_LIBADD=
+ 
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+new file mode 100644
+index 0000000..3dc46fb
+--- /dev/null
++++ b/src/tds/bulk.c
+@@ -0,0 +1,289 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2008  Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif /* HAVE_CONFIG_H */
++
++#if HAVE_STRING_H
++#include <string.h>
++#endif /* HAVE_STRING_H */
++
++#if HAVE_ERRNO_H
++#include <errno.h>
++#endif /* HAVE_ERRNO_H */
++
++#if HAVE_STDLIB_H
++#include <stdlib.h>
++#endif /* HAVE_STDLIB_H */
++
++#include <assert.h>
++
++#include "tds.h"
++#include "tds_checks.h"
++#include "replacements.h"
++#ifdef DMALLOC
++#include <dmalloc.h>
++#endif
++
++TDS_RCSID(var, "$Id: bulk.c,v 1.1 2008/12/12 13:56:11 freddy77 Exp $");
++
++typedef struct tds_pbcb
++{
++	char *pb;
++	unsigned int cb;
++	unsigned int from_malloc;
++} TDSPBCB;
++
++/** 
++ * \return TDS_SUCCEED or TDS_FAIL.
++ */
++static int
++tds_build_bulk_insert_stmt(TDSSOCKET * tds, TDSPBCB * clause, TDSCOLUMN * bcpcol, int first)
++{
++	char buffer[32];
++	char *column_type = buffer;
++
++	tdsdump_log(TDS_DBG_FUNC, "tds_build_bulk_insert_stmt(%p, %p, %p, %d)\n", tds, clause, bcpcol, first);
++
++	/* TODO reuse function in tds/query.c */
++	switch (bcpcol->on_server.column_type) {
++	case SYBINT1:
++		column_type = "tinyint";
++		break;
++	case SYBBIT:
++		column_type = "bit";
++		break;
++	case SYBINT2:
++		column_type = "smallint";
++		break;
++	case SYBINT4:
++		column_type = "int";
++		break;
++	case SYBINT8:
++		column_type = "bigint";
++		break;
++	case SYBDATETIME:
++		column_type = "datetime";
++		break;
++	case SYBDATETIME4:
++		column_type = "smalldatetime";
++		break;
++	case SYBREAL:
++		column_type = "real";
++		break;
++	case SYBMONEY:
++		column_type = "money";
++		break;
++	case SYBMONEY4:
++		column_type = "smallmoney";
++		break;
++	case SYBFLT8:
++		column_type = "float";
++		break;
++
++	case SYBINTN:
++		switch (bcpcol->column_size) {
++		case 1:
++			column_type = "tinyint";
++			break;
++		case 2:
++			column_type = "smallint";
++			break;
++		case 4:
++			column_type = "int";
++			break;
++		case 8:
++			column_type = "bigint";
++			break;
++		}
++		break;
++
++	case SYBBITN:
++		column_type = "bit";
++		break;
++	case SYBFLTN:
++		switch (bcpcol->column_size) {
++		case 4:
++			column_type = "real";
++			break;
++		case 8:
++			column_type = "float";
++			break;
++		}
++		break;
++	case SYBMONEYN:
++		switch (bcpcol->column_size) {
++		case 4:
++			column_type = "smallmoney";
++			break;
++		case 8:
++			column_type = "money";
++			break;
++		}
++		break;
++	case SYBDATETIMN:
++		switch (bcpcol->column_size) {
++		case 4:
++			column_type = "smalldatetime";
++			break;
++		case 8:
++			column_type = "datetime";
++			break;
++		}
++		break;
++	case SYBDECIMAL:
++		sprintf(column_type, "decimal(%d,%d)", bcpcol->column_prec, bcpcol->column_scale);
++		break;
++	case SYBNUMERIC:
++		sprintf(column_type, "numeric(%d,%d)", bcpcol->column_prec, bcpcol->column_scale);
++		break;
++
++	case XSYBVARBINARY:
++		sprintf(column_type, "varbinary(%d)", bcpcol->column_size);
++		break;
++	case XSYBVARCHAR:
++		sprintf(column_type, "varchar(%d)", bcpcol->column_size);
++		break;
++	case XSYBBINARY:
++		sprintf(column_type, "binary(%d)", bcpcol->column_size);
++		break;
++	case XSYBCHAR:
++		sprintf(column_type, "char(%d)", bcpcol->column_size);
++		break;
++	case SYBTEXT:
++		sprintf(column_type, "text");
++		break;
++	case SYBIMAGE:
++		sprintf(column_type, "image");
++		break;
++	case XSYBNVARCHAR:
++		sprintf(column_type, "nvarchar(%d)", bcpcol->column_size);
++		break;
++	case XSYBNCHAR:
++		sprintf(column_type, "nchar(%d)", bcpcol->column_size);
++		break;
++	case SYBNTEXT:
++		sprintf(column_type, "ntext");
++		break;
++	case SYBUNIQUE:
++		sprintf(column_type, "uniqueidentifier  ");
++		break;
++	default:
++		tdserror(tds->tds_ctx, tds, TDSEBPROBADTYP, errno);
++		tdsdump_log(TDS_DBG_FUNC, "error: cannot build bulk insert statement. unrecognized server datatype %d\n",
++			    bcpcol->on_server.column_type);
++		return TDS_FAIL;
++	}
++
++	if (clause->cb < strlen(clause->pb)
++	    + tds_quote_id(tds, NULL, bcpcol->column_name, bcpcol->column_namelen)
++	    + strlen(column_type)
++	    + ((first) ? 2u : 4u)) {
++		char *temp = malloc(2 * clause->cb);
++
++		if (!temp) {
++			tdserror(tds->tds_ctx, tds, TDSEMEM, errno);
++			return TDS_FAIL;
++		}
++		strcpy(temp, clause->pb);
++		if (clause->from_malloc)
++			free(clause->pb);
++		clause->from_malloc = 1;
++		clause->pb = temp;
++		clause->cb *= 2;
++	}
++
++	if (!first)
++		strcat(clause->pb, ", ");
++
++	tds_quote_id(tds, strchr(clause->pb, 0), bcpcol->column_name, bcpcol->column_namelen);
++	strcat(clause->pb, " ");
++	strcat(clause->pb, column_type);
++
++	return TDS_SUCCEED;
++}
++
++int
++tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo)
++{
++	char *query;
++
++	if (IS_TDS7_PLUS(tds)) {
++		int i, firstcol, erc;
++		char *hint;
++		TDSCOLUMN *bcpcol;
++		TDSPBCB colclause;
++		char clause_buffer[4096] = { 0 };
++
++		colclause.pb = clause_buffer;
++		colclause.cb = sizeof(clause_buffer);
++		colclause.from_malloc = 0;
++
++		firstcol = 1;
++
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++			bcpcol = bcpinfo->bindinfo->columns[i];
++
++			if (bcpinfo->identity_insert_on) {
++				if (!bcpcol->column_timestamp) {
++					tds_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
++					firstcol = 0;
++				}
++			} else {
++				if (!bcpcol->column_identity && !bcpcol->column_timestamp) {
++					tds_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
++					firstcol = 0;
++				}
++			}
++		}
++
++		if (bcpinfo->hint) {
++			if (asprintf(&hint, " with (%s)", bcpinfo->hint) < 0)
++				hint = NULL;
++		} else {
++			hint = strdup("");
++		}
++		if (!hint) {
++			if (colclause.from_malloc)
++				TDS_ZERO_FREE(colclause.pb);
++			return TDS_FAIL;
++		}
++
++		erc = asprintf(&query, "insert bulk %s (%s)%s", bcpinfo->tablename, colclause.pb, hint);
++
++		free(hint);
++		if (colclause.from_malloc)
++			TDS_ZERO_FREE(colclause.pb);	/* just for good measure; not used beyond this point */
++
++		if (erc < 0)
++			return TDS_FAIL;
++	} else {
++		/* NOTE: if we use "with nodescribe" for following inserts server do not send describe */
++		if (asprintf(&query, "insert bulk %s", bcpinfo->tablename) < 0)
++			return TDS_FAIL;
++	}
++
++	tds_submit_query(tds, query);
++	/* save the statement for later... */
++
++	bcpinfo->insert_stmt = query;
++
++	return TDS_SUCCEED;
++}
+
+commit 9a5f3d56a8c936a54b77b3d2d94f665332dca909
+Author: jklowden <jklowden>
+Date:   Sat Dec 13 01:48:35 2008 +0000
+
+    add -L to tsql to list servers using MC-SQLR CLNT_UCAST_EX.  This message type can be used to discover the default  port for Microsoft servers beginning with SQL Server 2000.
+
+diff --git a/ChangeLog b/ChangeLog
+index fbf2c02..3307039 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Dec 12 20:40:56 EST 2008	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/apps/tsql.c src/tds/log.c src/tds/net.c
++	- add -L to tsql to list servers using MC-SQLR CLNT_UCAST_EX. 
++	- This message type can be used to discover the default 
++	- port for Microsoft servers beginning with SQL Server 2000. 
++
+ Fri Dec 12 14:53:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/ctlib.h include/dblib.h include/tds.h src/ctlib/blk.c:
+ 	* src/dblib/bcp.c src/tds/Makefile.am src/tds/bulk.c(added):
+@@ -1038,4 +1044,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2677 2008/12/12 13:56:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2678 2008/12/13 01:48:35 jklowden Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 2149602..123fe18 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.302 2008/12/12 13:56:11 freddy77 Exp $ */
++/* $Id: tds.h,v 1.303 2008/12/13 01:48:35 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1065,13 +1065,14 @@ typedef enum _TDS_STATE
+ 	TDS_DEAD	/**< no connection */
+ } TDS_STATE;
+ 
+-#define TDS_DBG_FUNC    __FILE__, ((__LINE__ << 4) | 7)
+-#define TDS_DBG_INFO2   __FILE__, ((__LINE__ << 4) | 6)
+-#define TDS_DBG_INFO1   __FILE__, ((__LINE__ << 4) | 5)
+-#define TDS_DBG_NETWORK __FILE__, ((__LINE__ << 4) | 4)
+-#define TDS_DBG_WARN    __FILE__, ((__LINE__ << 4) | 3)
+-#define TDS_DBG_ERROR   __FILE__, ((__LINE__ << 4) | 2)
+-#define TDS_DBG_SEVERE  __FILE__, ((__LINE__ << 4) | 1)
++#define TDS_DBG_LOGIN   __FILE__, ((__LINE__ << 4) | 11)
++#define TDS_DBG_FUNC    __FILE__, ((__LINE__ << 4) |  7)
++#define TDS_DBG_INFO2   __FILE__, ((__LINE__ << 4) |  6)
++#define TDS_DBG_INFO1   __FILE__, ((__LINE__ << 4) |  5)
++#define TDS_DBG_NETWORK __FILE__, ((__LINE__ << 4) |  4)
++#define TDS_DBG_WARN    __FILE__, ((__LINE__ << 4) |  3)
++#define TDS_DBG_ERROR   __FILE__, ((__LINE__ << 4) |  2)
++#define TDS_DBG_SEVERE  __FILE__, ((__LINE__ << 4) |  1)
+ 
+ #define TDS_DBGFLAG_FUNC    0x80
+ #define TDS_DBGFLAG_INFO2   0x40
+@@ -1080,12 +1081,14 @@ typedef enum _TDS_STATE
+ #define TDS_DBGFLAG_WARN    0x08
+ #define TDS_DBGFLAG_ERROR   0x04
+ #define TDS_DBGFLAG_SEVERE  0x02
+-#define TDS_DBGFLAG_ALLLVL  0xfff
++#define TDS_DBGFLAG_ALL     0xfff
++#define TDS_DBGFLAG_LOGIN   0x0800
+ #define TDS_DBGFLAG_PID     0x1000
+ #define TDS_DBGFLAG_TIME    0x2000
+ #define TDS_DBGFLAG_SOURCE  0x4000
+ #define TDS_DBGFLAG_THREAD  0x8000
+ 
++#if 0
+ /**
+  * An attempt at better logging.
+  * Using these bitmapped values, various logging features can be turned on and off.
+@@ -1106,6 +1109,7 @@ enum TDS_DBG_LOG_STATE
+ 	, TDS_DBG_CONFIG = (1 << 7)	/**< replaces TDSDUMPCONFIG */
+ 	, TDS_DBG_DEFAULT = 0xFE	/**< all above except login packets */
+ };
++#endif
+ 
+ typedef struct tds_result_info TDSCOMPUTEINFO;
+ 
+@@ -1566,6 +1570,7 @@ int tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int
+ int tds_close_socket(TDSSOCKET * tds);
+ int tds_read_packet(TDSSOCKET * tds);
+ int tds_write_packet(TDSSOCKET * tds, unsigned char final);
++int tds7_get_instance_ports(FILE *output, const char *ip_addr);
+ int tds7_get_instance_port(const char *ip_addr, const char *instance);
+ int tds_ssl_init(TDSSOCKET *tds);
+ void tds_ssl_deinit(TDSSOCKET *tds);
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 5914c97..e1cc25b 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.122 2008/12/10 14:56:26 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.123 2008/12/13 01:48:35 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -96,11 +96,13 @@ enum
+ 	OPT_NOFOOTER = 0x04,
+ 	OPT_NOHEADER = 0x08,
+ 	OPT_QUIET =    0x10,
+-	OPT_VERBOSE =  0x20
++	OPT_VERBOSE =  0x20,
++	OPT_INSTANCES= 0x40
+ };
+ 
+ static int istty = 0;
+ static int global_opt_flags = 0;
++
+ #define QUIET (global_opt_flags & OPT_QUIET)
+ #define VERBOSE (global_opt_flags & OPT_VERBOSE)
+ 
+@@ -194,6 +196,7 @@ do_query(TDSSOCKET * tds, char *buf, int opt_flags)
+ 	}
+ 
+ 	while ((rc = tds_process_tokens(tds, &resulttype, NULL, TDS_TOKEN_RESULTS)) == TDS_SUCCEED) {
++		const int stop_mask = TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE;
+ 		if (opt_flags & OPT_TIMER) {
+ 			gettimeofday(&start, NULL);
+ 			print_rows = 0;
+@@ -211,7 +214,7 @@ do_query(TDSSOCKET * tds, char *buf, int opt_flags)
+ 		case TDS_COMPUTE_RESULT:
+ 		case TDS_ROW_RESULT:
+ 			rows = 0;
+-			while ((rc = tds_process_tokens(tds, &resulttype, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE)) == TDS_SUCCEED) {
++			while ((rc = tds_process_tokens(tds, &resulttype, NULL, stop_mask)) == TDS_SUCCEED) {
+ 				if (resulttype != TDS_ROW_RESULT && resulttype != TDS_COMPUTE_RESULT)
+ 					break;
+ 
+@@ -339,7 +342,7 @@ get_opt_flags(char *s, int *opt_flags)
+ 	*opt_flags = 0;
+ 	reset_getopt();
+ 	opterr = 0;		/* suppress error messages */
+-	while ((opt = getopt(argc, argv, "fhqtv")) != -1) {
++	while ((opt = getopt(argc, argv, "fhLqtv")) != -1) {
+ 		switch (opt) {
+ 		case 'f':
+ 			*opt_flags |= OPT_NOFOOTER;
+@@ -394,7 +397,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ #endif
+ 
+ 
+-	while ((opt = getopt(argc, argv, "H:S:I:P:U:p:Co:t:r:D:v")) != -1) {
++	while ((opt = getopt(argc, argv, "H:S:I:P:U:p:Co:t:r:D:Lv")) != -1) {
+ 		switch (opt) {
+ 		case 't':
+ 			opt_col_term = strdup(optarg);
+@@ -431,6 +434,9 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		case 'p':
+ 			port = atoi(optarg);
+ 			break;
++		case 'L':
++			global_opt_flags |= OPT_INSTANCES;
++			break;
+ 		case 'v':
+ 			global_opt_flags |= OPT_VERBOSE;
+ 			break;
+@@ -477,6 +483,21 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		charset = "ISO-8859-1";
+ 		if (!QUIET) printf("using default charset \"%s\"\n", charset);
+ 	}
++	
++	if ((global_opt_flags & OPT_INSTANCES) && hostname) {
++		static const char suffix[] = ".instances";
++		char *filename = getenv("TDSDUMP");
++		if (filename) {
++			if ((filename = malloc(1+sizeof(suffix) + strlen(filename))) == NULL) 
++				exit(1);
++			strcpy(filename, getenv("TDSDUMP"));
++			strcat(filename, suffix);
++			tdsdump_open(filename);
++			free(filename);
++		}
++		tds7_get_instance_ports(stderr, hostname); /* must be dotted-decimal ip address */
++		tdsdump_close();
++	}
+ 
+ 	/* validate parameters */
+ 	if (!servername && !hostname) {
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 58518e1..abbbf05 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,10 +66,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.8 2008/12/11 12:37:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.9 2008/12/13 01:48:35 jklowden Exp $");
+ 
+ /* for now all messages go to the log */
+-int tds_debug_flags = TDS_DBGFLAG_ALLLVL | TDS_DBGFLAG_SOURCE;
++int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+ int tds_g_append_mode = 0;
+ static char *g_dump_filename = NULL;
+ static int write_dump = 0;	/* is TDS stream debug log turned on? */
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 72399b5..6bd57e2 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.78 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.79 2008/12/13 01:48:35 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -801,6 +801,170 @@ tds_write_packet(TDSSOCKET * tds, unsigned char final)
+ }
+ 
+ /**
++ * Get port of all instances
++ * @return default port number or 0 if error
++ * @remark experimental, cf. MS-SQLR.pdf.
++ */
++int
++tds7_get_instance_ports(FILE *output, const char *ip_addr)
++{
++	int num_try;
++	struct sockaddr_in sin;
++	ioctl_nonblocking_t ioctl_nonblocking;
++#if USE_POLL
++	struct pollfd fd;
++#else
++	struct timeval selecttimeout;
++	fd_set fds;
++#endif
++	int retval;
++	TDS_SYS_SOCKET s;
++	char msg[16*1024];
++	size_t msg_len = 0;
++	int port = 0;
++
++	tdsdump_log(TDS_DBG_ERROR, "tds7_get_instance_ports(%s)\n", ip_addr);
++
++	sin.sin_addr.s_addr = inet_addr(ip_addr);
++	if (sin.sin_addr.s_addr == INADDR_NONE) {
++		tdsdump_log(TDS_DBG_ERROR, "inet_addr() failed, IP = %s\n", ip_addr);
++		return 0;
++	}
++
++	sin.sin_family = AF_INET;
++	sin.sin_port = htons(1434);
++
++	/* create an UDP socket */
++	if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_DGRAM, 0))) {
++		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", strerror(sock_errno));
++		return 0;
++	}
++
++#if !USE_POLL
++#if !defined(WIN32) && defined(FD_SETSIZE)
++	if (s >= FD_SETSIZE) {
++		sock_errno = EINVAL;
++		return 0;
++	}
++#endif
++#endif
++
++	/*
++	 * on cluster environment is possible that reply packet came from
++	 * different IP so do not filter by ip with connect
++	 */
++
++	ioctl_nonblocking = 1;
++	if (IOCTLSOCKET(s, FIONBIO, &ioctl_nonblocking) < 0) {
++		CLOSESOCKET(s);
++		return 0;
++	}
++
++	/* 
++	 * Request the instance's port from the server.  
++	 * There is no easy way to detect if port is closed so we always try to
++	 * get a reply from server 16 times. 
++	 */
++	for (num_try = 0; num_try < 16 && msg_len == 0; ++num_try) {
++		/* send the request */
++		msg[0] = 3;
++		sendto(s, msg, 1, 0, (struct sockaddr *) &sin, sizeof(sin));
++
++#if USE_POLL
++		fd.fd = s;
++		fd.events = POLLIN;
++		fd.revents = 0;
++
++		retval = poll(&fd, 1, 1000);
++#else
++		FD_ZERO(&fds);
++		FD_SET(s, &fds);
++		selecttimeout.tv_sec = 1;
++		selecttimeout.tv_usec = 0;
++		
++		retval = select(s + 1, &fds, NULL, NULL, &selecttimeout);
++#endif
++		
++		/* on interrupt ignore */
++		if (retval < 0 && sock_errno == TDSSOCK_EINTR)
++			continue;
++		
++		if (retval == 0) { /* timed out */
++#if 1
++			tdsdump_log(TDS_DBG_ERROR, "tds7_get_instance_port: timed out on try %d of 16\n", num_try);
++			continue;
++#else
++			int rc;
++			tdsdump_log(TDS_DBG_INFO1, "timed out\n");
++
++			switch(rc = tdserror(NULL, NULL, TDSETIME, 0)) {
++			case TDS_INT_CONTINUE:
++				continue;	/* try again */
++
++			default:
++				tdsdump_log(TDS_DBG_ERROR, "error: client error handler returned %d\n", rc);
++			case TDS_INT_CANCEL: 
++				CLOSESOCKET(s);
++				return 0;
++			}
++#endif
++		}
++		if (retval < 0)
++			break;
++
++		/* got data, read and parse */
++		if ((msg_len = recv(s, msg, sizeof(msg) - 1, 0)) > 3 && msg[0] == 5) {
++			char *name, sep[2] = ";";
++
++			/* assure null terminated */
++			msg[msg_len] = 0;
++			tdsdump_dump_buf(TDS_DBG_INFO1, "instance info", msg, msg_len);
++			
++			if (0) {	/* To debug, print the whole string. */
++				char *p;
++
++				for (*sep = '\n', p=msg+3; p < msg + msg_len; p++) {
++					if( *p == ';' )
++						*p = *sep;
++				}
++				fprintf(output, msg + 3);
++			}
++
++			/*
++			 * Parse and print message.
++			 */
++			name = strtok(msg+3, sep);
++			while (name && output) {
++				int i;
++				static const char *names[] = { "ServerName", "InstanceName", "IsClustered", "Version", 
++							       "tcp", "np", "via" };
++				
++				for (i=0; name && i < TDS_VECTOR_SIZE(names); i++) {
++					const char *value = strtok(NULL, sep);
++					
++					if (strcmp(name, names[i]) != 0)
++						fprintf(output, "error: expecting '%s', found '%s'\n", names[i], name);
++					if (value) 
++						fprintf(output, "%15s %s\n", name, value);
++					else 
++						break;
++
++					name = strtok(NULL, sep);
++					
++					if (name && strcmp(name, names[0]) == 0)
++						break;
++				}
++				if (name) 
++					fprintf(output, "\n");
++			}
++		}
++	}
++	CLOSESOCKET(s);
++	tdsdump_log(TDS_DBG_ERROR, "default instance port is %d\n", port);
++	return port;
++}
++
++/**
+  * Get port of given instance
+  * @return port number or 0 if error
+  */
+
+commit 3d12873cf648506acff66566356f469bd3a451c6
+Author: jklowden <jklowden>
+Date:   Mon Dec 15 05:31:13 2008 +0000
+
+    Remove TDSSOCKET::last_packet, added tds_lastpacket().  Rename tds_connect to tds_connect_and_login.  Change tds_connect_and_login to return TDSERROR.  Remove tdserror calls from tds_open_socket.  Add tds_connect as wrapper to tds_open_socket.  Connecting with TDSVER 0.0 works without producing spurious messages.
+
+diff --git a/ChangeLog b/ChangeLog
+index 3307039..69d951e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,19 @@
++Mon Dec 15 00:15:18 EST 2008	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/apps/tsql.c
++	* src/ctlib/ct.c src/dblib/dblib.c
++	* src/odbc/odbc.c src/pool/member.c
++	* src/server/query.c src/tds/config.c
++	* src/tds/log.c src/tds/login.c
++	* src/tds/net.c src/tds/util.c
++	* src/tds/unittests/common.c
++	- Remove TDSSOCKET::last_packet, added tds_lastpacket(). 
++	- Rename tds_connect to tds_connect_and_login. 
++	- Change tds_connect_and_login to return TDSERROR. 
++	- Remove tdserror calls from tds_open_socket. 
++	- Add tds_connect as wrapper to tds_open_socket. 
++	- Connecting with TDSVER 0.0 works without producing
++	- spurious messages. 
++		
+ Fri Dec 12 20:40:56 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h src/apps/tsql.c src/tds/log.c src/tds/net.c
+ 	- add -L to tsql to list servers using MC-SQLR CLNT_UCAST_EX. 
+@@ -1044,4 +1060,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2678 2008/12/13 01:48:35 jklowden Exp $
++$Id: ChangeLog,v 1.2679 2008/12/15 05:31:13 jklowden Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 123fe18..d882be6 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.303 2008/12/13 01:48:35 jklowden Exp $ */
++/* $Id: tds.h,v 1.304 2008/12/15 05:31:14 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -280,7 +280,8 @@ enum tds_end
+  * These match the db-lib msgno, because the same values have the same meaning
+  * in db-lib and ODBC.  ct-lib maps them to ct-lib numbers (todo). 
+  */
+-typedef enum {	TDSEICONVIU    = 2400, 
++typedef enum {	TDSEOK    = TDS_SUCCEED, 
++		TDSEICONVIU    = 2400, 
+ 		TDSEICONVAVAIL = 2401, 
+ 		TDSEICONVO     = 2402, 
+ 		TDSEICONVI     = 2403, 
+@@ -1257,6 +1258,7 @@ typedef struct tds_multiple
+ 
+ /* forward declaration */
+ typedef struct tds_context TDSCONTEXT;
++typedef int (*err_handler_t) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
+ 
+ struct tds_context
+ {
+@@ -1292,6 +1294,7 @@ typedef struct tds_authentication TDSAUTHENTICATION;
+ struct tds_socket
+ {
+ 	TDS_SYS_SOCKET s;		/**< tcp socket, INVALID_SOCKET if not connected */
++	int oserr;
+ 	TDS_SMALLINT major_version;
+ 	TDS_SMALLINT minor_version;
+ 	TDS_UINT product_version;	/**< version of product (Sybase/MS and full version) */
+@@ -1312,7 +1315,6 @@ struct tds_socket
+ 
+ 	unsigned char in_flag;		/**< input buffer type */
+ 	unsigned char out_flag;		/**< output buffer type */
+-	unsigned char last_packet;	/**< true if current input buffer is the last one */
+ 	void *parent;
+ 
+ 	/**
+@@ -1388,6 +1390,7 @@ void tds_free_context(TDSCONTEXT * locale);
+ TDSSOCKET *tds_alloc_socket(TDSCONTEXT * context, int bufsize);
+ 
+ /* config.c */
++int tds_default_port(int major, int minor);
+ const TDS_COMPILETIME_SETTINGS *tds_get_compiletime_settings(void);
+ typedef void (*TDSCONFPARSE) (const char *option, const char *value, void *param);
+ int tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *parse_param);
+@@ -1395,7 +1398,7 @@ int tds_read_conf_file(TDSCONNECTION * connection, const char *server);
+ void tds_parse_conf_section(const char *option, const char *value, void *param);
+ TDSCONNECTION *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale);
+ void tds_fix_connection(TDSCONNECTION * connection);
+-void tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
++unsigned char tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
+ void tds_lookup_host(const char *servername, char *ip);
+ int tds_set_interfaces_file_loc(const char *interfloc);
+ extern const char STD_DATETIME_FMT[];
+@@ -1462,7 +1465,7 @@ void tds_set_client_charset(TDSLOGIN * tds_login, const char *charset);
+ void tds_set_language(TDSLOGIN * tds_login, const char *language);
+ void tds_set_version(TDSLOGIN * tds_login, TDS_TINYINT major_ver, TDS_TINYINT minor_ver);
+ void tds_set_capabilities(TDSLOGIN * tds_login, unsigned char *capabilities, int size);
+-int tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection);
++int tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ 
+ /* query.c */
+ int tds_submit_query(TDSSOCKET * tds, const char *query);
+@@ -1546,6 +1549,7 @@ unsigned int tds_gettime_ms(void);
+ /* log.c */
+ void tdsdump_off(void);
+ void tdsdump_on(void);
++int tdsdump_isopen(void);
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility pop
+ #endif
+@@ -1566,7 +1570,8 @@ extern int tds_debug_flags;
+ extern int tds_g_append_mode;
+ 
+ /* net.c */
+-int tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
++int tds_lastpacket(TDSSOCKET * tds);
++TDSERRNO tds_connect(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
+ int tds_close_socket(TDSSOCKET * tds);
+ int tds_read_packet(TDSSOCKET * tds);
+ int tds_write_packet(TDSSOCKET * tds, unsigned char final);
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index e1cc25b..632955b 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.123 2008/12/13 01:48:35 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.124 2008/12/15 05:31:14 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -370,6 +370,19 @@ get_opt_flags(char *s, int *opt_flags)
+ 	return 1;
+ }
+ 
++int
++get_default_instance_port(const char hostname[])
++{
++	char ip[24] = {'\0'};
++	
++	tds_lookup_host(hostname, ip);
++	
++	if (!*ip) 
++		return 0;
++	
++	return tds7_get_instance_port(ip, "MSSQLSERVER");
++}
++
+ static void
+ populate_login(TDSLOGIN * login, int argc, char **argv)
+ {
+@@ -485,17 +498,19 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 	}
+ 	
+ 	if ((global_opt_flags & OPT_INSTANCES) && hostname) {
+-		static const char suffix[] = ".instances";
++		static const char template[] = "%s.instances";
++		char ip[24] = {'\0'};
+ 		char *filename = getenv("TDSDUMP");
++
+ 		if (filename) {
+-			if ((filename = malloc(1+sizeof(suffix) + strlen(filename))) == NULL) 
++			if ((filename = malloc(sizeof(template) + strlen(filename))) == NULL) 
+ 				exit(1);
+-			strcpy(filename, getenv("TDSDUMP"));
+-			strcat(filename, suffix);
++			sprintf(filename, template, getenv("TDSDUMP"));
+ 			tdsdump_open(filename);
+ 			free(filename);
+ 		}
+-		tds7_get_instance_ports(stderr, hostname); /* must be dotted-decimal ip address */
++		tds_lookup_host(hostname, ip);
++		tds7_get_instance_ports(stderr, ip);
+ 		tdsdump_close();
+ 	}
+ 
+@@ -506,9 +521,25 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		exit(1);
+ 	}
+ 	if (hostname && !port) {
+-		fprintf(stderr, "Missing argument -p \n");
+-		tsql_print_usage(argv[0]);
+-		exit(1);
++		/*
++		 * TODO: It would be convenient to have a function that looks up a reasonable port based on:
++		 * 	- TDSPORT environment variable
++		 * 	- config files
++		 * 	- get_default_instance_port
++		 *	- TDS version
++		 *	in that order. 
++		 */
++		if (!QUIET) {
++			printf("Missing argument -p, looking for default instance ... ", port);
++		}
++		if (0 == (port = get_default_instance_port(hostname))) {
++			printf("no reply from server\n");
++			tsql_print_usage(argv[0]);
++			exit(1);
++		} 
++		if (!QUIET)
++			printf("found default instance, port %d\n", port);
++		
+ 	}
+ 	if (!username) {
+ 		fprintf(stderr, "Missing argument -U \n");
+@@ -682,8 +713,8 @@ main(int argc, char **argv)
+ #if HAVE_FORK
+ 	if (connection && !QUIET) {
+ 		/*
+-		 * Here we use a pipe so if even main program core the counter stops
+-		 * Note that we do not read or write nothing from this pipe
++		 * We use a pipe so that the child is killed even main program aborts. 
++		 * Note that we do not read or write from this pipe. 
+ 		 */
+ 		if (pipe(pipes) < 0) {
+ 			perror("tsql: pipe");
+@@ -715,7 +746,7 @@ main(int argc, char **argv)
+ 		close(pipes[0]);
+ 	}
+ #endif
+-	if (!connection || tds_connect(tds, connection) == TDS_FAIL) {
++	if (!connection || tds_connect_and_login(tds, connection) != TDS_SUCCEED) {
+ 		if( VERBOSE ) 
+ 			print_instance_data(connection);
+ 		tds_free_socket(tds);
+@@ -724,12 +755,12 @@ main(int argc, char **argv)
+ 		fprintf(stderr, "There was a problem connecting to the server\n");
+ 		exit(1);
+ 	}
+-	if( VERBOSE ) 
++	if (VERBOSE) 
+ 		print_instance_data(connection);
+ 	tds_free_connection(connection);
+ 	/* give the buffer an initial size */
+ 	bufsz = 4096;
+-	mybuf = (char *) malloc(bufsz);
++	mybuf = malloc(bufsz);
+ 	mybuf[0] = '\0';
+ 	buflen = 0;
+ 
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 2dcfb42..24b3bbc 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.181 2008/07/29 14:07:09 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.182 2008/12/15 05:31:14 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -616,7 +616,7 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 		*/
+ 	}
+ 
+-	if (tds_connect(con->tds_socket, connection) == TDS_FAIL)
++	if (tds_connect_and_login(con->tds_socket, connection) == TDS_FAIL)
+ 		goto Cleanup;
+ 
+ 	tds_free_connection(connection);
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 94838ad..a1eb2ca 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.334 2008/12/11 12:37:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.335 2008/12/15 05:31:14 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1146,7 +1146,7 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 
+ 	TDS_MUTEX_UNLOCK(&dblib_mutex);
+ 
+-	if (tds_connect(dbproc->tds_socket, connection) == TDS_FAIL) {
++	if (tds_connect_and_login(dbproc->tds_socket, connection) == TDS_FAIL) {
+ 		tds_free_connection(connection);
+ 		dbclose(dbproc);
+ 		return NULL;
+@@ -2714,7 +2714,10 @@ dbclrbuf(DBPROCESS * dbproc, DBINT n)
+  * 
+  * \param srctype type converting from
+  * \param desttype type converting to
+- * \remarks dbwillconvert() lies sometimes.  Some datatypes \em should be convertible but aren't yet in our implementation.   * \retval TRUE convertible, or should be. Legal unimplemented conversions return \em TRUE.  
++ * \remarks dbwillconvert() lies sometimes.  Some datatypes \em should be convertible but aren't yet in our implementation.  
++ *          Legal unimplemented conversions return \em TRUE.  
++ * \retval TRUE convertible, or should be. For conversions from a fix-length type to a character type (e.g. INT to VARCHAR), the value 
++ *         returned is the number of bytes needed hold the output.  
+  * \retval FAIL not convertible.  
+  * \sa dbaltbind(), dbbind(), dbconvert(), dbconvert_ps(), \c src/dblib/unittests/convert().c().
+  */
+@@ -4612,6 +4615,10 @@ dbsqlok(DBPROCESS * dbproc)
+ 
+ 				tdsdump_log(TDS_DBG_FUNC, "dbsqlok: returning %s with %s (%#x)\n", 
+ 						prdbretcode(retcode), prdbresults_state(dbproc->dbresults_state), done_flags);
++						
++				if (retcode == SUCCEED && (done_flags & TDS_DONE_MORE_RESULTS))
++					continue;
++					 
+ 				return retcode;
+ #endif
+ 			default:
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index b44ce5f..3786b54 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.506 2008/12/03 08:37:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.507 2008/12/15 05:31:14 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -381,7 +381,7 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 
+ 	connection->connect_timeout = dbc->attr.connection_timeout;
+ 
+-	if (tds_connect(dbc->tds_socket, connection) == TDS_FAIL) {
++	if (tds_connect_and_login(dbc->tds_socket, connection) == TDS_FAIL) {
+ 		tds_free_socket(dbc->tds_socket);
+ 		dbc->tds_socket = NULL;
+ 		odbc_errs_add(&dbc->errs, "08001", NULL);
+diff --git a/src/pool/member.c b/src/pool/member.c
+index b82e25d..418213c 100644
+--- a/src/pool/member.c
++++ b/src/pool/member.c
+@@ -59,7 +59,7 @@
+ #define MAXHOSTNAMELEN 256
+ #endif /* MAXHOSTNAMELEN */
+ 
+-TDS_RCSID(var, "$Id: member.c,v 1.42 2008/11/15 09:57:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: member.c,v 1.43 2008/12/15 05:31:14 jklowden Exp $");
+ 
+ static int pool_packet_read(TDS_POOL_MEMBER * pmbr);
+ static TDSSOCKET *pool_mbr_login(TDS_POOL * pool);
+@@ -96,7 +96,7 @@ pool_mbr_login(TDS_POOL * pool)
+ 	context = tds_alloc_context(NULL);
+ 	tds = tds_alloc_socket(context, 512);
+ 	connection = tds_read_config_info(NULL, login, context->locale);
+-	if (!connection || tds_connect(tds, connection) == TDS_FAIL) {
++	if (!connection || tds_connect_and_login(tds, connection) == TDS_FAIL) {
+ 		tds_free_socket(tds);
+ 		tds_free_connection(connection);
+ 		/* what to do? */
+@@ -105,7 +105,7 @@ pool_mbr_login(TDS_POOL * pool)
+ 	}
+ 	tds_free_connection(connection);
+ 	/*
+-	 * FIXME -- tds_connect no longer preallocates the in_buf need to 
++	 * FIXME -- tds_connect_and_login no longer preallocates the in_buf need to 
+ 	 * do something like what tds_read_packet does
+ 	 */
+ 	tds->in_buf = (unsigned char *) malloc(BLOCKSIZ);
+diff --git a/src/server/query.c b/src/server/query.c
+index 8ebd212..adf16e6 100644
+--- a/src/server/query.c
++++ b/src/server/query.c
+@@ -29,7 +29,7 @@
+ #include "tds.h"
+ #include "tdssrv.h"
+ 
+-static char software_version[] = "$Id: query.c,v 1.17 2007/09/24 10:02:14 freddy77 Exp $";
++static char software_version[] = "$Id: query.c,v 1.18 2008/12/15 05:31:14 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char *query;
+@@ -138,7 +138,7 @@ char *tds_get_generic_query(TDSSOCKET * tds)
+ 				/* TODO: WE DON'T HANDLE PARAMETERS YET! */
+ 
+ 				/* eat the rest of the packet */
+-				while (!tds->last_packet && tds_read_packet(tds) > 0) {
++				while (!tds_lastpacket(tds) && tds_read_packet(tds) > 0) {
+ 				}
+ 				return query;
+ 
+@@ -146,7 +146,7 @@ char *tds_get_generic_query(TDSSOCKET * tds)
+ 				/* unexpected token */
+ 
+ 				/* eat the rest of the packet */
+-				while (!tds->last_packet && tds_read_packet(tds) > 0) {
++				while (!tds_lastpacket(tds) && tds_read_packet(tds) > 0) {
+ 				}
+ 				return NULL;
+ 			}
+@@ -181,7 +181,7 @@ char *tds_get_generic_query(TDSSOCKET * tds)
+ 				}
+ 
+ 				/* if more then read it */
+-				if (tds->last_packet)
++				if (tds_lastpacket(tds))
+ 					break;
+ 				if (tds_read_packet(tds) < 0)
+ 					return NULL;
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 220c253..5863e9f 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.138 2008/12/10 14:56:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.139 2008/12/15 05:31:15 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -110,6 +110,19 @@ static const char pid_logpath[] = "c:\\freetds.log.%d";
+ static const char interfaces_path[] = "c:\\";
+ #endif
+ 
++int
++tds_default_port(int major, int minor)
++{
++	switch(major) {
++	case 4:
++		if (minor == 6)
++			break;
++	case 5:
++		return 4000;
++	}
++	return 1433;
++}
++
+ /**
+  * \ingroup libtds
+  * \defgroup config Configuration
+@@ -675,41 +688,43 @@ tds_config_env_tdshost(TDSCONNECTION * connection)
+  * Set TDS version from given string
+  * @param tdsver tds string version
+  * @param connection where to store information
++ * @return as encoded hex value: high nybble major, low nybble minor.  
+  */
+-void
++unsigned char
+ tds_config_verstr(const char *tdsver, TDSCONNECTION * connection)
+ {
++	TDSCONNECTION dummy, *c = &dummy;
++	
++	if (connection) 
++		c = connection;
++	
+ 	if (!strcmp(tdsver, "42") || !strcmp(tdsver, "4.2")) {
+-		connection->major_version = 4;
+-		connection->minor_version = 2;
+-		return;
++		c->major_version = 4;
++		c->minor_version = 2;
+ 	} else if (!strcmp(tdsver, "46") || !strcmp(tdsver, "4.6")) {
+-		connection->major_version = 4;
+-		connection->minor_version = 6;
+-		return;
++		c->major_version = 4;
++		c->minor_version = 6;
+ 	} else if (!strcmp(tdsver, "50") || !strcmp(tdsver, "5.0")) {
+-		connection->major_version = 5;
+-		connection->minor_version = 0;
+-		return;
++		c->major_version = 5;
++		c->minor_version = 0;
+ 	} else if (!strcmp(tdsver, "70") || !strcmp(tdsver, "7.0")) {
+-		connection->major_version = 7;
+-		connection->minor_version = 0;
+-		return;
++		c->major_version = 7;
++		c->minor_version = 0;
+ 	} else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0")) {
+-		connection->major_version = 8;
+-		connection->minor_version = 0;
+-		return;
++		c->major_version = 8;
++		c->minor_version = 0;
+ #ifdef ENABLE_DEVELOPING
+ 	} else if (!strcmp(tdsver, "90") || !strcmp(tdsver, "9.0")) {
+-		connection->major_version = 9;
+-		connection->minor_version = 0;
+-		return;
++		c->major_version = 9;
++		c->minor_version = 0;
+ #endif
+ 	} else if (!strcmp(tdsver, "0.0")) {
+-		connection->major_version = 0;
+-		connection->minor_version = 0;
+-		return;
+-	}
++		c->major_version = 0;
++		c->minor_version = 0;
++	} else 
++		return 0;
++	
++	return (c->major_version << 4) | c->minor_version;
+ }
+ 
+ /**
+@@ -778,7 +793,7 @@ tds_lookup_host(const char *servername,	/* (I) name of the server
+ /**
+  * Given a portname lookup the port.
+  *
+- * If we can't determine the port number than function return 0.
++ * If we can't determine the port number then return 0.
+  */
+ static int
+ tds_lookup_port(const char *portname)
+@@ -945,7 +960,7 @@ search_interface_file(TDSCONNECTION * connection, const char *dir, const char *f
+ static void
+ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ {
+-	int founded = 0;
++	int found = 0;
+ 
+ 	/* read $SYBASE/interfaces */
+ 
+@@ -964,18 +979,18 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 	 */
+ 	if (interf_file) {
+ 		tdsdump_log(TDS_DBG_INFO1, "Looking for server in file %s.\n", interf_file);
+-		founded = search_interface_file(connection, "", interf_file, server);
++		found = search_interface_file(connection, "", interf_file, server);
+ 	}
+ 
+ 	/*
+ 	 * if we haven't found the server yet then look for a $HOME/.interfaces file
+ 	 */
+-	if (!founded) {
++	if (!found) {
+ 		char *path = tds_get_home_file(".interfaces");
+ 
+ 		if (path) {
+ 			tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s.\n", path);
+-			founded = search_interface_file(connection, "", path, server);
++			found = search_interface_file(connection, "", path, server);
+ 			free(path);
+ 		}
+ 	}
+@@ -983,7 +998,7 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 	/*
+ 	 * if we haven't found the server yet then look in $SYBBASE/interfaces file
+ 	 */
+-	if (!founded) {
++	if (!found) {
+ 		const char *sybase = getenv("SYBASE");
+ #ifdef __VMS
+ 		/* We've got to be in unix syntax for later slash-joined concatenation. */
+@@ -995,14 +1010,14 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 			sybase = interfaces_path;
+ 
+ 		tdsdump_log(TDS_DBG_INFO1, "Looking for server in %s/interfaces.\n", sybase);
+-		founded = search_interface_file(connection, sybase, "interfaces", server);
++		found = search_interface_file(connection, sybase, "interfaces", server);
+ 	}
+ 
+ 	/*
+ 	 * If we still don't have the server and port then assume the user
+ 	 * typed an actual server name.
+ 	 */
+-	if (!founded) {
++	if (!found) {
+ 		char ip_addr[255];
+ 		int ip_port;
+ 		const char *env_port;
+diff --git a/src/tds/log.c b/src/tds/log.c
+index abbbf05..4beb990 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.9 2008/12/13 01:48:35 jklowden Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.10 2008/12/15 05:31:15 jklowden Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+@@ -107,7 +107,13 @@ tdsdump_on(void)
+ 	TDS_MUTEX_LOCK(&g_dump_mutex);
+ 	write_dump = 1;
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+-}				/* tdsdump_on()  */
++}
++
++int
++tdsdump_isopen()
++{
++	return NULL != g_dumpfile;
++}
+ 
+ 
+ /**
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 1c12428..984ed12 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.176 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.177 2008/12/15 05:31:15 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -306,12 +306,18 @@ free_save_context(TDSSAVECONTEXT *ctx)
+  * Do a connection to socket
+  * @param tds connection structure. This should be a non-connected connection.
+  * @param connection info for connection
+- * @return TDS_FAIL or TDS_SUCCEED
++ * @return TDS_FAIL or TDS_SUCCEED if a connection was made to the server's port.
++ * @return TDSERROR enumerated type if no TCP/IP connection could be formed. 
++ * @remark Possible error conditions:
++ *		- TDSESOCK: socket(2) failed: insufficient local resources
++ * 		- TDSECONN: connect(2) failed: invalid hostname or port (ETIMEDOUT, ECONNREFUSED, ENETUNREACH)
++ * 		- TDSEFCON: connect(2) succeeded, login packet not acknowledged.  
++ *		- TDS_FAIL: connect(2) succeeded, login failed.  
+  */
+ int
+-tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
++tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ {
+-	int retval;
++	int erc;
+ 	int connect_timeout = 0;
+ 	int db_selected = 0;
+ 
+@@ -335,32 +341,45 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		const TDSCONTEXT *old_ctx = tds->tds_ctx;
+ 		typedef void (*env_chg_func_t) (TDSSOCKET * tds, int type, char *oldval, char *newval);
+ 		env_chg_func_t old_env_chg = tds->env_chg_func;
++		/* the context of a socket is const; we have to modify it to suppress error messages during multiple tries. */
++		TDSCONTEXT *mod_ctx = (TDSCONTEXT *)tds->tds_ctx;
++		err_handler_t err_handler = tds->tds_ctx->err_handler;
+ 
+ 		init_save_context(&save_ctx, old_ctx);
+ 		tds->tds_ctx = &save_ctx.ctx;
+ 		tds->env_chg_func = tds_save_env;
++		mod_ctx->err_handler = NULL;
++
+ 		for (i=0; i < TDS_VECTOR_SIZE(versions); ++i) {
+ 			connection->major_version = versions[i].major_version;
+ 			connection->minor_version = versions[i].minor_version;
+-			/* fprintf(stdout, "trying TDSVER %d.%d\n", connection->major_version, connection->minor_version); */
+ 			reset_save_context(&save_ctx);
+-			retval = tds_connect(tds, connection);
+-			if (TDS_SUCCEED == retval)
++
++			if ((erc = tds_connect_and_login(tds, connection)) == TDS_FAIL) {
++				tds_close_socket(tds);
++			}
++			
++			if (erc != TDSEFCON)	/* TDSEFCON indicates wrong TDS version */
+ 				break;
+-			tds_close_socket(tds);
+ 		}
++		
++		mod_ctx->err_handler = err_handler;
+ 		tds->env_chg_func = old_env_chg;
+ 		tds->tds_ctx = old_ctx;
+ 		replay_save_context(tds, &save_ctx);
+ 		free_save_context(&save_ctx);
+-		return retval;
++		
++		if (erc != TDS_SUCCEED)
++			tdserror(tds->tds_ctx, tds, erc, tds->oserr); 
++
++		return erc;
+ 	}
+ 	
+ 
+ 	/*
+ 	 * If a dump file has been specified, start logging
+ 	 */
+-	if (!tds_dstr_isempty(&connection->dump_file)) {
++	if (!tds_dstr_isempty(&connection->dump_file) && !tdsdump_isopen()) {
+ 		if (connection->debug_flags)
+ 			tds_debug_flags = connection->debug_flags;
+ 		tdsdump_open(tds_dstr_cstr(&connection->dump_file));
+@@ -405,7 +424,7 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		} else {
+ 			tdsdump_log(TDS_DBG_ERROR, "No server specified!\n");
+ 		}
+-		return TDS_FAIL;
++		return TDSECONN;
+ 	}
+ 
+ 	if (!IS_TDS50(tds) && !tds_dstr_isempty(&connection->instance_name))
+@@ -413,30 +432,37 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	if (connection->port < 1) {
+ 		tdsdump_log(TDS_DBG_ERROR, "invalid port number\n");
+-		return TDS_FAIL;
++		return TDSECONN;
+ 	}
+ 
+ 	memcpy(tds->capabilities, connection->capabilities, TDS_MAX_CAPABILITY);
+ 
+-	if (tds_open_socket(tds, tds_dstr_cstr(&connection->ip_addr), connection->port, connect_timeout) != TDS_SUCCEED)
+-		return TDS_FAIL;
++	if ((erc = tds_connect(tds, tds_dstr_cstr(&connection->ip_addr), connection->port, connect_timeout)) != TDS_SUCCEED)
++		return erc;
++		
++	/*
++	 * Beyond this point, we're connected to the server.  We know we have a valid TCP/IP address+socket pair.  
++	 * Although network errors *might* happen, most problems from here on out will be TDS-level errors, 
++	 * either TDS version problems or authentication problems.  
++	 */
++		
+ 	tds_set_state(tds, TDS_IDLE);
+ 
+ 	if (IS_TDS8_PLUS(tds)) {
+-		retval = tds8_do_login(tds, connection);
++		erc = tds8_do_login(tds, connection);
+ 		db_selected = 1;
+ 	} else if (IS_TDS7_PLUS(tds)) {
+-		retval = tds7_send_login(tds, connection);
++		erc = tds7_send_login(tds, connection);
+ 		db_selected = 1;
+ 	} else {
+ 		tds->out_flag = TDS_LOGIN;
+-		retval = tds_send_login(tds, connection);
++		erc = tds_send_login(tds, connection);
+ 	}
+-	if (retval == TDS_FAIL || !tds_process_login_tokens(tds)) {
++	if (erc == TDS_FAIL || !tds_process_login_tokens(tds)) {
++		tdsdump_log(TDS_DBG_ERROR, "login packet %s\n", erc==TDS_SUCCEED? "accepted":"rejected");
+ 		tds_close_socket(tds);
+ 		tdserror(tds->tds_ctx, tds, TDSEFCON, 0); 	/* "Adaptive Server connection failed" */
+-								/* If it's a bad login, the server will send that mesasge */
+-		return TDS_FAIL;
++		return TDSEFCON;
+ 	}
+ 
+ 	if (connection->text_size || (!db_selected && !tds_dstr_isempty(&connection->database))) {
+@@ -455,9 +481,9 @@ tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 			strcat(str, "use ");
+ 			tds_quote_id(tds, strchr(str, 0), tds_dstr_cstr(&connection->database), -1);
+ 		}
+-		retval = tds_submit_query(tds, str);
++		erc = tds_submit_query(tds, str);
+ 		free(str);
+-		if (retval != TDS_SUCCEED)
++		if (erc != TDS_SUCCEED)
+ 			return TDS_FAIL;
+ 
+ 		if (tds_process_simple_query(tds) != TDS_SUCCEED)
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 6bd57e2..8552192 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.79 2008/12/13 01:48:35 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.80 2008/12/15 05:31:15 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -119,7 +119,8 @@ TDS_RCSID(var, "$Id: net.c,v 1.79 2008/12/13 01:48:35 jklowden Exp $");
+ # define TDSSELERR   4
+ #endif
+ 
+-static int tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
++static int      tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
++static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
+ 
+ 
+ /**
+@@ -179,7 +180,17 @@ typedef unsigned int ioctl_nonblocking_t;
+ typedef u_long ioctl_nonblocking_t;
+ #endif
+ 
+-int
++TDSERRNO
++tds_connect(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout)
++{
++	TDSERRNO erc = tds_open_socket(tds, ip_addr, port, timeout);
++	if (TDSEOK != erc) {
++		tdserror(tds->tds_ctx, tds, erc, tds->oserr);  
++	}
++	return erc;
++}
++
++static TDSERRNO
+ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout)
+ {
+ 	struct sockaddr_in sin;
+@@ -190,12 +201,14 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	int tds_error = TDSECONN;
+ 	char ip[20];
+ 
++	tds->oserr = 0;
++
+ 	memset(&sin, 0, sizeof(sin));
+ 
+ 	sin.sin_addr.s_addr = inet_addr(ip_addr);
+ 	if (sin.sin_addr.s_addr == INADDR_NONE) {
+ 		tdsdump_log(TDS_DBG_ERROR, "inet_addr() failed, IP = %s\n", ip_addr);
+-		return TDS_FAIL;
++		return TDSESOCK;
+ 	}
+ 
+ 	sin.sin_family = AF_INET;
+@@ -206,9 +219,9 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 			tds->major_version, tds->minor_version);
+ 
+ 	if (TDS_IS_SOCKET_INVALID(tds->s = socket(AF_INET, SOCK_STREAM, 0))) {
+-		tdserror(tds->tds_ctx, tds, TDSESOCK, 0);  
++		tds->oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", strerror(sock_errno));
+-		return TDS_FAIL;
++		return TDSESOCK;
+ 	}
+ 
+ #ifdef SO_KEEPALIVE
+@@ -230,13 +243,13 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	if (connect(tds->s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+ 		char *message;
+ 
++		tds->oserr = sock_errno;
+ 		if (asprintf(&message, "tds_open_socket(): %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)) >= 0) {
+ 			perror(message);
+ 			free(message);
+ 		}
+ 		tds_close_socket(tds);
+-		tdserror(tds->tds_ctx, tds, TDSECONN, 0);
+-		return TDS_FAIL;
++		return TDSECONN;
+ 	}
+ #else
+ 	if (!timeout) {
+@@ -247,14 +260,16 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	/* enable non-blocking mode */
+ 	ioctl_nonblocking = 1;
+ 	if (IOCTLSOCKET(tds->s, FIONBIO, &ioctl_nonblocking) < 0) {
++		tds->oserr = sock_errno;
+ 		tds_close_socket(tds);
+-		return TDS_FAIL;
++		return TDSEUSCT; 	/* close enough: "Unable to set communications timer" */
+ 	}
+ 
+ 	retval = connect(tds->s, (struct sockaddr *) &sin, sizeof(sin));
+ 	if (retval == 0) {
+ 		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
+ 	} else {
++		tds->oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", strerror(sock_errno));
+ #if DEBUGGING_CONNECTING_PROBLEM
+ 		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != EINPROGRESS) {
+@@ -275,7 +290,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 			goto not_available;
+ 		
+ 		if (tds_select(tds, TDSSELWRITE|TDSSELERR, timeout) <= 0) {
+-			tds_error = TDSESOCK;
++			tds_error = TDSECONN;
+ 			goto not_available;
+ 		}
+ 	}
+@@ -285,23 +300,24 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	optlen = sizeof(len);
+ 	len = 0;
+ 	if (getsockopt(tds->s, SOL_SOCKET, SO_ERROR, (char *) &len, &optlen) != 0) {
++		tds->oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) failed: %s\n", strerror(sock_errno));
+ 		goto not_available;
+ 	}
+ 	if (len != 0) {
++		tds->oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) reported: %s\n", strerror(len));
+ 		goto not_available;
+ 	}
+ 
+ 	tdsdump_log(TDS_DBG_ERROR, "tds_open_socket() succeeded\n");
+-	return TDS_SUCCEED;
++	return TDSEOK;
+ 	
+     not_available:
+ 	
+ 	tds_close_socket(tds);
+-	tdserror(tds->tds_ctx, tds, tds_error, sock_errno);
+ 	tdsdump_log(TDS_DBG_ERROR, "tds_open_socket() failed\n");
+-	return TDS_FAIL;
++	return tds_error;
+ }
+ 
+ int
+@@ -310,11 +326,10 @@ tds_close_socket(TDSSOCKET * tds)
+ 	int rc = -1;
+ 
+ 	if (!IS_TDSDEAD(tds)) {
+-		rc = CLOSESOCKET(tds->s);
++		if ((rc = CLOSESOCKET(tds->s)) == -1) 
++			tdserror(tds->tds_ctx, tds,  TDSECLOS, sock_errno);
+ 		tds->s = INVALID_SOCKET;
+ 		tds_set_state(tds, TDS_DEAD);
+-		if (-1 == rc) 
+-			tdserror(tds->tds_ctx, tds,  TDSECLOS, sock_errno);
+ 	}
+ 	return rc;
+ }
+@@ -574,35 +589,12 @@ tds_read_packet(TDSSOCKET * tds)
+ 
+ 		tds->in_len = 0;
+ 		tds->in_pos = 0;
+-		tds->last_packet = 1;
+ 		if (tds->state != TDS_IDLE && len == 0) {
+ 			tds_close_socket(tds);
+ 		}
+ 		return -1;
+ 	}
+ 
+-#if 0
+-	/*
+-	 * Note:
+-	 * this was done by Gregg, I don't think its the real solution (it breaks
+-	 * under 5.0, but I haven't gotten a result big enough to test this yet.
+- 	 */
+-	if (IS_TDS42(tds)) {
+-		if (header[0] != 0x04 && header[0] != 0x0f) {
+-			tdsdump_log(TDS_DBG_ERROR, "Invalid packet header %d\n", header[0]);
+-			/*
+-			 * Not sure if this is the best way to do the error 
+-			 * handling here but this is the way it is currently 
+-			 * being done.
+-			 */
+-			tds->in_len = 0;
+-			tds->in_pos = 0;
+-			tds->last_packet = 1;
+-			return (-1);
+-		}
+-	}
+-#endif
+-
+ 	/* Convert our packet length from network to host byte order */
+ 	len = (((unsigned int) header[2]) << 8) | header[3];
+ 
+@@ -643,16 +635,12 @@ tds_read_packet(TDSSOCKET * tds)
+ 			/* no need to call tdserror(), because goodread() already did */
+ 			tds->in_len = 0;
+ 			tds->in_pos = 0;
+-			tds->last_packet = 1;
+ 			tds_close_socket(tds);
+ 			return -1;
+ 		}
+ 		have += nbytes;
+ 	}
+ 
+-	/* Set the last packet flag */
+-	tds->last_packet = (header[1] != 0);
+-
+ 	/* set the received packet type flag */
+ 	tds->in_flag = header[0];
+ 
+@@ -664,6 +652,15 @@ tds_read_packet(TDSSOCKET * tds)
+ 	return (tds->in_len);
+ }
+ 
++int
++tds_lastpacket(TDSSOCKET * tds) 
++{
++	if (!tds || !tds->in_buf || tds->in_buf_max < 2)
++		return 1;
++	
++	return tds->in_buf[1] != 0;
++}
++
+ /**
+  * \param tds the famous socket
+  * \param p pointer to buffer
+diff --git a/src/tds/unittests/common.c b/src/tds/unittests/common.c
+index fc9d2b0..48896fb 100644
+--- a/src/tds/unittests/common.c
++++ b/src/tds/unittests/common.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.27 2008/09/09 14:48:04 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.28 2008/12/15 05:31:15 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -97,13 +97,13 @@ try_tds_login(TDSLOGIN ** login, TDSSOCKET ** tds, const char *appname, int verb
+ 	*tds = tds_alloc_socket(test_context, 512);
+ 	tds_set_parent(*tds, NULL);
+ 	connection = tds_read_config_info(NULL, *login, test_context->locale);
+-	if (!connection || tds_connect(*tds, connection) == TDS_FAIL) {
++	if (!connection || tds_connect_and_login(*tds, connection) == TDS_FAIL) {
+ 		if (connection) {
+ 			tds_free_socket(*tds);
+ 			*tds = NULL;
+ 			tds_free_connection(connection);
+ 		}
+-		fprintf(stderr, "tds_connect() failed\n");
++		fprintf(stderr, "tds_connect_and_login() failed\n");
+ 		return TDS_FAIL;
+ 	}
+ 	tds_free_connection(connection);
+diff --git a/src/tds/util.c b/src/tds/util.c
+index 6ccb429..a4a2fc8 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.83 2007/12/07 05:27:55 jklowden Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.84 2008/12/15 05:31:15 jklowden Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -361,11 +361,15 @@ tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum)
+ 		 * The client library must return a valid code.  It is not checked again here.
+ 		 */
+ 		rc = tds_ctx->err_handler(tds_ctx, tds, &msg);
++	 	tdsdump_log(TDS_DBG_FUNC, "tdserror: client library returned %s(%d)\n", retname(rc), rc);
+ 
+ 		TDS_ZERO_FREE(msg.sql_state);
++	} else {
++		const static char msg[] = "tdserror: client library not called because either "
++					  "tds_ctx (%x) or tds_ctx->err_handler is NULL\n";
++	 	tdsdump_log(TDS_DBG_FUNC, msg, tds_ctx);
+ 	}
+ 
+- 	tdsdump_log(TDS_DBG_FUNC, "tdserror: client library returned %s(%d)\n", retname(rc), rc);
+   
+   	assert(!(msgno != TDSETIME && rc == TDS_INT_TIMEOUT));   /* client library should prevent */
+ 	assert(!(msgno != TDSETIME && rc == TDS_INT_CONTINUE));  /* client library should prevent */
+
+commit 8523e906e47b345331798fe84b11e2440ef6ea66
+Author: freddy77 <freddy77>
+Date:   Mon Dec 15 12:33:57 2008 +0000
+
+    add and reuse tds_bcp_send_record
+
+diff --git a/ChangeLog b/ChangeLog
+index 69d951e..547c5b4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Dec 15 13:33:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
++	- add and reuse tds_bcp_send_record
++
+ Mon Dec 15 00:15:18 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h src/apps/tsql.c
+ 	* src/ctlib/ct.c src/dblib/dblib.c
+@@ -1060,4 +1064,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2679 2008/12/15 05:31:13 jklowden Exp $
++$Id: ChangeLog,v 1.2680 2008/12/15 12:33:57 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index d882be6..02972ee 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.304 2008/12/15 05:31:14 jklowden Exp $ */
++/* $Id: tds.h,v 1.305 2008/12/15 12:33:57 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1612,7 +1612,10 @@ typedef struct tds_bcpinfo
+ 	TDSRESULTINFO *bindinfo;
+ } TDSBCPINFO;
+ 
++typedef int  (*tds_bcp_get_col_data) (TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
++typedef void (*tds_bcp_null_error)   (TDSBCPINFO *bulk, int index, int offset);
+ int tds_bcp_start_insert_stmt(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++int tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset);
+ 
+ #define IS_TDS42(x) (x->major_version==4 && x->minor_version==2)
+ #define IS_TDS46(x) (x->major_version==4 && x->minor_version==6)
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 881fe89..18f6560 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,12 +38,10 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.44 2008/12/12 13:56:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.45 2008/12/15 12:33:57 freddy77 Exp $");
+ 
+-static CS_RETCODE _blk_get_col_data(CS_BLKDESC *, TDSCOLUMN *, int );
+-static int _blk_add_variable_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start, int *var_cols);
+-static CS_RETCODE _blk_add_fixed_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start);
+-static CS_RETCODE _blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset);
++static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
++static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+ static CS_RETCODE _blk_send_colmetadata(CS_BLKDESC * blkdesc);
+ static CS_RETCODE _rowxfer_in_init(CS_BLKDESC * blkdesc);
+ static CS_RETCODE _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+@@ -715,9 +713,10 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 		blkdesc->bcpinfo.xfer_init = 1;
+ 	} 
+ 
++	blkdesc->bcpinfo.parent = &blkdesc;
+ 	for (each_row = 0; each_row < rows_to_xfer; each_row++ ) {
+ 
+-		if (_blk_build_bcp_record(blkdesc, each_row) == CS_SUCCEED) {
++		if (tds_bcp_send_record(tds, &blkdesc->bcpinfo, _blk_get_col_data, _blk_null_error, each_row) == TDS_SUCCEED) {
+ 	
+ 		}
+ 	}
+@@ -902,428 +901,15 @@ _blk_send_colmetadata(CS_BLKDESC * blkdesc)
+ 	return CS_SUCCEED;
+ }
+ 
+-static CS_RETCODE
+-_blk_build_bcp_record(CS_BLKDESC *blkdesc, CS_INT offset)
++static void
++_blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset)
+ {
+-	TDSSOCKET  *tds = blkdesc->con->tds_socket;
+-	TDSCOLUMN  *bindcol;
+-
+-	static const unsigned char CHARBIN_NULL[] = { 0xff, 0xff };
+-	static const unsigned char GEN_NULL = 0x00;
+-	static const unsigned char textptr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+-											 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
+-	};
+-	static const unsigned char timestamp[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+-
+-	static const TDS_TINYINT textptr_size = 16;
+-	const unsigned char row_token = 0xd1;
+-
+-	unsigned char *record;
+-	TDS_INT	 old_record_size;
+-	TDS_INT	 new_record_size;
+-
+-	TDS_INT	     varint_4;
+-	TDS_SMALLINT varint_2;
+-	TDS_TINYINT  varint_1;
+-
+-	int row_pos;
+-	int row_sz_pos;
+-	TDS_SMALLINT row_size;
+-
+-	int blob_cols = 0;
+-	int var_cols_written = 0;
+-
+-	int i;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_blk_build_bcp_record(offset %d)\n", offset);
+-
+-	record = blkdesc->bcpinfo.bindinfo->current_row;
+-	old_record_size = blkdesc->bcpinfo.bindinfo->row_size;
+-	new_record_size = 0;
+-
+-	if (IS_TDS7_PLUS(tds)) {
+-
+-		for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+-	
+-			bindcol = blkdesc->bcpinfo.bindinfo->columns[i];
+-
+-			/*
+-			 * dont send the (meta)data for timestamp columns, or
+-			 * identity columns (unless indentity_insert is enabled
+-			 */
+-
+-			if ((!blkdesc->bcpinfo.identity_insert_on && bindcol->column_identity) || 
+-				bindcol->column_timestamp) {
+-				continue;
+-			}
+-
+-			if ((_blk_get_col_data(blkdesc, bindcol, offset)) != CS_SUCCEED) {
+-				tdsdump_log(TDS_DBG_INFO1, "blk_get_colData (column %d) failed\n", i + 1);
+-	 			return CS_FAIL;
+-			}
+-			tdsdump_log(TDS_DBG_INFO1, "gotten column %d length %d null %d\n",
+-					i + 1, bindcol->bcp_column_data->datalen, bindcol->bcp_column_data->is_null);
+-	
+-			if (bindcol->bcp_column_data->is_null) {
+-				if (bindcol->column_nullable) {
+-					switch (bindcol->on_server.column_type) {
+-					case XSYBCHAR:
+-					case XSYBVARCHAR:
+-					case XSYBBINARY:
+-					case XSYBVARBINARY:
+-					case XSYBNCHAR:
+-					case XSYBNVARCHAR:
+-						memcpy(record, CHARBIN_NULL, 2);
+-						record +=2;
+-						new_record_size +=2;
+-						break;
+-					default:
+-						*record = GEN_NULL;
+-						record++;
+-						new_record_size ++;
+-						break;
+-					}
+-				} else {
+-					/* No value or default value available and NULL not allowed. col = %d row = %d. */
+-					_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 7, 1, 142, "%d, %d",  i + 1, offset + 1);
+-					return CS_FAIL;
+-				}
+-			} else {
+-
+-				switch (bindcol->column_varint_size) {
+-				case 4:
+-					if (is_blob_type(bindcol->on_server.column_type)) {
+-						*record = textptr_size; record++;
+-						memcpy(record, textptr, 16); record += 16;
+-						memcpy(record, timestamp, 8); record += 8;
+-						new_record_size += 25;
+-					}
+-					varint_4 = bindcol->bcp_column_data->datalen;
+-#if WORDS_BIGENDIAN
+-					tds_swap_datatype(SYBINT4, (unsigned char *)&varint_4);
+-#endif
+-					memcpy(record, &varint_4, 4); record += 4; new_record_size +=4;
+-					break;
+-				case 2:
+-					varint_2 = bindcol->bcp_column_data->datalen;
+-#if WORDS_BIGENDIAN
+-					tds_swap_datatype(SYBINT2, (unsigned char *)&varint_2);
+-#endif
+-					memcpy(record, &varint_2, 2); record += 2; new_record_size +=2;
+-					break;
+-				case 1:
+-					varint_1 = bindcol->bcp_column_data->datalen;
+-					if (is_numeric_type(bindcol->on_server.column_type)) 
+-						varint_1 = tds_numeric_bytes_per_prec[bindcol->column_prec];
+-					else
+-						varint_1 = bindcol->bcp_column_data->datalen;
+-					*record = varint_1; record++; new_record_size++;
+-					break;
+-				case 0:
+-					break;
+-				}
+-
+-#if WORDS_BIGENDIAN
+-				tds_swap_datatype(bindcol->on_server.column_type, bindcol->bcp_column_data->data);
+-#endif
+-
+-				if (is_numeric_type(bindcol->on_server.column_type)) {
+-					CS_NUMERIC *num = (CS_NUMERIC *) bindcol->bcp_column_data->data;
+-					if (IS_TDS7_PLUS(tds))
+-						tds_swap_numeric((TDS_NUMERIC *) num);
+-					memcpy(record, num->array, tds_numeric_bytes_per_prec[num->precision]);
+-					record += tds_numeric_bytes_per_prec[num->precision]; 
+-					new_record_size += tds_numeric_bytes_per_prec[num->precision];
+-				} else {
+-					memcpy(record, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
+-					record += bindcol->bcp_column_data->datalen; new_record_size += bindcol->bcp_column_data->datalen;
+-				}
+-
+-			}
+-			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n",
+-					old_record_size, new_record_size);
+-		}
+-
+-		tds_put_byte(tds, row_token);   /* 0xd1 */
+-		tds_put_n(tds, blkdesc->bcpinfo.bindinfo->current_row, new_record_size);
+-	}  /* IS_TDS7_PLUS */
+-	else {
+-			memset(record, '\0', old_record_size);	/* zero the rowbuffer */
+-
+-			/*
+-			 * offset 0 = number of var columns
+-			 * offset 1 = row number.  zeroed (datasever assigns)
+-			 */
+-			row_pos = 2;
+-
+-			if ((row_pos = _blk_add_fixed_columns(blkdesc, offset, record, row_pos)) == CS_FAIL)
+-				return CS_FAIL;
+-
+-			row_sz_pos = row_pos;
+-
+-			/* potential variable columns to write */
+-
+-			if (blkdesc->bcpinfo.var_cols) {
+-				if ((row_pos = _blk_add_variable_columns(blkdesc, offset, record, row_pos, &var_cols_written)) == CS_FAIL)
+-					return CS_FAIL;
+-			}
+-
+-			row_size = row_pos;
+-
+-			if (var_cols_written) {
+-				memcpy(&record[row_sz_pos], &row_size, sizeof(row_size));
+-				record[0] = var_cols_written;
+-			}
+-
+-			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n",
+-					old_record_size, row_size);
+-
+-			tds_put_smallint(tds, row_size);
+-			tds_put_n(tds, record, row_size);
+-
+-			/* row is done, now handle any text/image data */
+-
+-			blob_cols = 0;
+-
+-			for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+-				bindcol = blkdesc->bcpinfo.bindinfo->columns[i];
+-				if (is_blob_type(bindcol->column_type)) {
+-					if ((_blk_get_col_data(blkdesc, bindcol, offset)) != CS_SUCCEED) {
+-			 			return CS_FAIL;
+-					}
+-					/* unknown but zero */
+-					tds_put_smallint(tds, 0);
+-					tds_put_byte(tds, bindcol->column_type);
+-					tds_put_byte(tds, 0xff - blob_cols);
+-					/*
+-					 * offset of txptr we stashed during variable
+-					 * column processing 
+-					 */
+-					tds_put_smallint(tds, bindcol->column_textpos);
+-					tds_put_int(tds, bindcol->bcp_column_data->datalen);
+-					tds_put_n(tds, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
+-					blob_cols++;
+-
+-				}
+-			}
+-	}
+-
+-	return CS_SUCCEED;
++	CS_BLKDESC *blkdesc = (CS_BLKDESC *) bcpinfo->parent;
++	_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 7, 1, 142, "%d, %d",  index + 1, offset + 1);
+ }
+ 
+-static CS_RETCODE
+-_blk_add_fixed_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start)
+-{
+-	TDS_NUMERIC *num;
+-	int row_pos = start;
+-	TDSCOLUMN *bcpcol;
+-	int cpbytes;
+-
+-	int i, j;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_blk_add_fixed_columns (offset %d)\n", offset);
+-
+-	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+-
+-		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+-
+-		if (!is_nullable_type(bcpcol->column_type) && !(bcpcol->column_nullable)) {
+-
+-			tdsdump_log(TDS_DBG_FUNC, "_blk_add_fixed_columns column %d is a fixed column\n", i + 1);
+-
+-			if (( _blk_get_col_data(blkdesc, bcpcol, offset)) != CS_SUCCEED) {
+-		 		return CS_FAIL;
+-			}
+-
+-			if (bcpcol->bcp_column_data->is_null) {
+-				/* No value or default value available and NULL not allowed. col = %d row = %d. */
+-				_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 7, 1, 142, "%d, %d",  i + 1, offset + 1);
+-				return CS_FAIL;
+-			}
+-
+-			if (is_numeric_type(bcpcol->column_type)) {
+-				num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
+-				cpbytes = tds_numeric_bytes_per_prec[num->precision];
+-				memcpy(&rowbuffer[row_pos], num->array, cpbytes);
+-			} else {
+-				cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ? bcpcol->column_size : bcpcol->bcp_column_data->datalen;
+-				memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);
+-
+-				/* CHAR data may need padding out to the database length with blanks */
+-
+-				if (bcpcol->column_type == SYBCHAR && cpbytes < bcpcol->column_size) {
+-					for (j = cpbytes; j <  bcpcol->column_size; j++)
+-						rowbuffer[row_pos + j] = ' ';
+-				}
+-			}
+-
+-			row_pos += bcpcol->column_size;
+-
+-		}
+-	}
+-	return row_pos;
+-}
+-
+-/**
+- * Add variable size columns to the row
+- */
+ static int
+-_blk_add_variable_columns(CS_BLKDESC * blkdesc, int offset, unsigned char * rowbuffer, int start, int *var_cols)
+-{
+-	TDSCOLUMN   *bcpcol;
+-	TDS_NUMERIC *num;
+-	int row_pos;
+-	int cpbytes;
+-
+-	unsigned char offset_table[256];
+-	unsigned char adjust_table[256];
+-
+-	int offset_pos     = 0;
+-	int adjust_pos     = 0;
+-	int num_cols       = 0;
+-	int last_adjustment_increment = 0;
+-	int this_adjustment_increment = 0;
+-
+-	int i, adjust_table_entries_required;
+-
+-	/*
+-	 * Skip over two bytes. These will be used to hold the entire record length
+-	 * once the record has been completely built.
+-	 */
+-
+-	row_pos = start + 2;
+-
+-	/* for each column in the target table */
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_blk_add_variable_columns (offset %d)\n", offset);
+-
+-	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+-
+-		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+-
+-		/*
+-		 * is this column of "variable" type, i.e. NULLable
+-		 * or naturally variable length e.g. VARCHAR
+-		 */
+-
+-		if (is_nullable_type(bcpcol->column_type) || bcpcol->column_nullable) {
+-
+-			tdsdump_log(TDS_DBG_FUNC, "_blk_add_variable_columns column %d is a variable column\n", i + 1);
+-
+-			if ((_blk_get_col_data(blkdesc, bcpcol, offset)) != CS_SUCCEED) {
+-		 		return CS_FAIL;
+-			}
+-
+-			/*
+-			 * but if its a NOT NULL column, and we have no data
+-			 * throw an error
+-			 */
+-
+-			if (!(bcpcol->column_nullable) && bcpcol->bcp_column_data->is_null) {
+-				/* No value or default value available and NULL not allowed. col = %d row = %d. */
+-				_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 7, 1, 142, "%d, %d",  i + 1, offset + 1);
+-				return CS_FAIL;
+-			}
+-
+-			if (is_blob_type(bcpcol->column_type)) {
+-				cpbytes = 16;
+-				bcpcol->column_textpos = row_pos;               /* save for data write */
+-			} else if (is_numeric_type(bcpcol->column_type)) {
+-				num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
+-				cpbytes = tds_numeric_bytes_per_prec[num->precision];
+-				memcpy(&rowbuffer[row_pos], num->array, cpbytes);
+-			} else {
+-				/* compute the length to copy to the row ** buffer */
+-				if (bcpcol->bcp_column_data->is_null) {
+-					cpbytes = 0;
+-				} else {
+-					cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ? bcpcol->column_size : bcpcol->bcp_column_data->datalen;
+-					memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);
+-				}
+-			}
+-
+-			/* if we have written data to the record for this column */
+-
+-			if (cpbytes > 0) {
+-
+-				/*
+-				 * update offset table. Each entry in the offset table is a single byte
+-				 * so can only hold a maximum value of 255. If the real offset is more
+-				 * than 255 we will have to add one or more entries in the adjust table
+-				 */
+-
+-				offset_table[offset_pos++] = row_pos % 256;
+-
+-				/* increment count of variable columns added to the record */
+-
+-				num_cols++;
+-
+-				/*
+-				 * how many times does 256 have to be added to the one byte offset to
+-				 * calculate the REAL offset...
+-				 */
+-
+-				this_adjustment_increment = row_pos / 256;
+-
+-				/* has this changed since we did the last column...      */
+-
+-				if (this_adjustment_increment > last_adjustment_increment) {
+-
+-					/*
+-					 * add n entries to the adjust table. each entry represents
+-					 * an adjustment of 256 bytes, and each entry holds the
+-					 * column number for which the adjustment needs to be made
+-					 */
+-
+-					for ( adjust_table_entries_required = this_adjustment_increment - last_adjustment_increment;
+-						  adjust_table_entries_required > 0;
+-						  adjust_table_entries_required-- ) {
+-							adjust_table[adjust_pos++] = num_cols;
+-					}
+-					last_adjustment_increment = this_adjustment_increment;
+-				}
+-
+-				row_pos += cpbytes;
+-			}
+-		}
+-	}
+-
+-	if (num_cols) {	
+-		/* 
+-		 * If we have written any variable columns to the record, add entries 
+-		 * to the offset and adjust tables for the end of data offset (as above). 
+-		 */
+-
+-		offset_table[offset_pos++] = row_pos % 256;
+-
+-		/*
+-		 * Write the offset data etc. to the end of the record, starting with 
+-		 * a count of variable columns (plus 1 for the eod offset)       
+-		 */
+-
+-		rowbuffer[row_pos++] = num_cols + 1;
+-	
+-		/* write the adjust table (right to left) */
+-		for (i = adjust_pos - 1; i >= 0; i--) {
+-			rowbuffer[row_pos++] = adjust_table[i];
+-		}
+-	
+-		/* write the offset table (right to left) */
+-		for (i = offset_pos - 1; i >= 0; i--) {
+-			rowbuffer[row_pos++] = offset_table[i];
+-		}
+-	}
+-
+-	*var_cols = num_cols;
+-
+-	if (num_cols == 0) /* we haven't written anything */
+-		return start;
+-	else
+-		return row_pos;
+-}
+-
+-static CS_RETCODE
+-_blk_get_col_data(CS_BLKDESC *blkdesc, TDSCOLUMN *bindcol, int offset) 
++_blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset)
+ {
+ 	int result = 0;
+ 
+@@ -1336,6 +922,7 @@ _blk_get_col_data(CS_BLKDESC *blkdesc, TDSCOLUMN *bindcol, int offset)
+ 	CS_INT      destlen  = 0;
+ 	CS_SMALLINT *nullind = NULL;
+ 	CS_INT      *datalen = NULL;
++	CS_BLKDESC *blkdesc = (CS_BLKDESC *) bulk->parent;
+ 	CS_CONTEXT *ctx = blkdesc->con->ctx;
+ 	CS_DATAFMT srcfmt, destfmt;
+ 
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index bb6a2e1..6a53df9 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -57,13 +57,11 @@
+ #define HOST_COL_CONV_ERROR 1
+ #define HOST_COL_NULL_ERROR 2
+ 
+-typedef enum { BCP_REC_NOFETCH_DATA = 0, BCP_REC_FETCH_DATA = 1 } BEHAVIOUR;
+-
+ #ifndef MAX
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.174 2008/12/12 13:56:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.175 2008/12/15 12:33:57 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -79,10 +77,11 @@ typedef __int64 offset_type;
+ typedef long offset_type;
+ #endif
+ 
+-static RETCODE _bcp_send_bcp_record(DBPROCESS * dbproc, BEHAVIOUR behaviour);
+ static void _bcp_free_storage(DBPROCESS * dbproc);
+ static void _bcp_free_columns(DBPROCESS * dbproc);
+-static RETCODE _bcp_get_col_data(DBPROCESS * dbproc, TDSCOLUMN *bindcol);
++static void _bcp_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
++static int _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset);
++static int _bcp_no_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset);
+ static RETCODE _bcp_send_colmetadata(DBPROCESS *);
+ static RETCODE _bcp_start_copy_in(DBPROCESS *);
+ static RETCODE _bcp_start_new_batch(DBPROCESS *);
+@@ -1581,226 +1580,6 @@ _bcp_measure_terminated_field(FILE * hostfile, BYTE * terminator, int term_len)
+ 	return -1;
+ }
+ 
+-/**
+- * Add fixed size columns to the row
+- */
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+- * \param dbproc contains all information needed by db-lib to manage communications with the server.
+- * \param behaviour 
+- * \param rowbuffer 
+- * \param start 
+- * 
+- * \return SUCCEED or FAIL.
+- * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+- */
+-static int
+-_bcp_add_fixed_columns(DBPROCESS * dbproc, BEHAVIOUR behaviour, BYTE * rowbuffer, int start)
+-{
+-	TDS_NUMERIC *num;
+-	int row_pos = start;
+-	TDSCOLUMN *bcpcol;
+-	int cpbytes;
+-	int i, j;
+-
+-	assert(dbproc);
+-	assert(rowbuffer);
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_add_fixed_columns(%p, %d, %p, %d)\n", dbproc, behaviour, rowbuffer, start);
+-
+-	for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-
+-		bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
+-
+-		if (!is_nullable_type(bcpcol->column_type) && !(bcpcol->column_nullable)) {
+-
+-			tdsdump_log(TDS_DBG_FUNC, "_bcp_add_fixed_columns column %d is a fixed column\n", i + 1);
+-
+-			if (behaviour == BCP_REC_FETCH_DATA) { 
+-				if ((_bcp_get_col_data(dbproc, bcpcol)) != SUCCEED) {
+-					tdsdump_log(TDS_DBG_INFO1, "bcp_get_colData (column %d) failed\n", i + 1);
+-		 			return FAIL;
+-				}
+-			}
+-
+-			if (bcpcol->bcp_column_data->is_null) {
+-				dbperror(dbproc, SYBEBCNN, 0);
+-				return FAIL;
+-			}
+-
+-			if (is_numeric_type(bcpcol->column_type)) {
+-				num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
+-				cpbytes = tds_numeric_bytes_per_prec[num->precision];
+-				memcpy(&rowbuffer[row_pos], num->array, cpbytes);
+-			} else {
+-				cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ? 
+-					  bcpcol->column_size : bcpcol->bcp_column_data->datalen;
+-				memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);
+-
+-				/* CHAR data may need padding out to the database length with blanks */
+-
+-				if (bcpcol->column_type == SYBCHAR && cpbytes < bcpcol->column_size) {
+-					for (j = cpbytes; j <  bcpcol->column_size; j++)
+-						rowbuffer[row_pos + j] = ' ';
+-
+-				}
+-			}
+-
+-			row_pos += bcpcol->column_size;
+-		}
+-	}
+-	return row_pos;
+-}
+-
+-/*
+- * Add variable size columns to the row
+- */
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+- * \param dbproc contains all information needed by db-lib to manage communications with the server.
+- * \param behaviour Whether the data are already in the TDSCOLUMN or should by copied from the buffer bound by bcp_bind().
+- * \param rowbuffer The row image that will be sent to the server. 
+- * \param start Where to begin copying data into the rowbuffer. 
+- * \param pncols Address of output variable holding the count of columns added to the rowbuffer.  
+- * 
+- * \return length of (potentially modified) rowbuffer, or FAIL.
+- * \sa 	_bcp_send_bcp_record(), _bcp_get_col_data
+- */
+-static int
+-_bcp_add_variable_columns(DBPROCESS * dbproc, BEHAVIOUR behaviour, BYTE * rowbuffer, int start, int *pncols)
+-{
+-	TDS_SMALLINT offsets[256];
+-	int i, row_pos;
+-	int ncols = 0;
+-
+-	assert(dbproc);
+-	assert(rowbuffer);
+-	assert(pncols);
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_add_variable_columns(%p, %s, %p, start=%d, %p)\n", 
+-				dbproc, 
+-				(behaviour == BCP_REC_NOFETCH_DATA)? "BCP_REC_NOFETCH_DATA" : "BCP_REC_FETCH_DATA", 
+-				rowbuffer, start, pncols);
+-
+-	tdsdump_log(TDS_DBG_FUNC, "%4s %8s %18s %18s %8s\n", 	"col", 
+-								"type", 
+-								"is_nullable_type", 
+-								"column_nullable", 
+-								"is null" );
+-	for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-		TDSCOLUMN *bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
+-		tdsdump_log(TDS_DBG_FUNC, "%4d %8d %18s %18s %8s\n", 	i, 
+-									bcpcol->column_type,  
+-									is_nullable_type(bcpcol->column_type)? "yes" : "no", 
+-									bcpcol->column_nullable? "yes" : "no", 
+-									bcpcol->bcp_column_data->is_null? "yes" : "no" );
+-	}
+-
+-	/* the first two bytes of the rowbuffer are reserved to hold the entire record length */
+-	row_pos = start + 2;
+-	offsets[0] = row_pos;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "%4s %8s %8s %8s\n", "col", "ncols", "row_pos", "cpbytes");
+-
+-	for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-		int cpbytes = 0;
+-		TDSCOLUMN *bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
+-
+-		/* 
+-		 * Is this column of "variable" type, i.e. NULLable 
+-		 * or naturally variable length e.g. VARCHAR
+-		 */
+-		if (is_nullable_type(bcpcol->column_type) || bcpcol->column_nullable) {
+-
+-			tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d %8d\n", i, ncols, row_pos, cpbytes);
+-
+-			if (behaviour == BCP_REC_FETCH_DATA) { 
+-				if ((_bcp_get_col_data(dbproc, bcpcol)) != SUCCEED) {
+-		 			return FAIL;
+-				}
+-				tdsdump_log(TDS_DBG_FUNC, "column %d is %d bytes and is %sNULL\n", 
+-						i+1, 
+-						bcpcol->bcp_column_data->datalen, 
+-						bcpcol->bcp_column_data->is_null? "":"not ");
+-			}
+-
+-			/* If it's a NOT NULL column, and we have no data, throw an error. */
+-			if (!(bcpcol->column_nullable) && bcpcol->bcp_column_data->is_null) {
+-				dbperror(dbproc, SYBEBCNN, 0);
+-				return FAIL;
+-			}
+-
+-			/* move the column buffer into the rowbuffer */
+-			if (!bcpcol->bcp_column_data->is_null) {
+-				if (is_blob_type(bcpcol->column_type)) {
+-					cpbytes = 16;
+-					bcpcol->column_textpos = row_pos;               /* save for data write */
+-				} else if (is_numeric_type(bcpcol->column_type)) {
+-					TDS_NUMERIC *num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
+-					cpbytes = tds_numeric_bytes_per_prec[num->precision];
+-					memcpy(&rowbuffer[row_pos], num->array, cpbytes);
+-				} else {
+-					cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ? 
+-						  bcpcol->column_size : bcpcol->bcp_column_data->datalen;
+-					memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);
+-				}
+-			}
+-
+-			row_pos += cpbytes;
+-			offsets[++ncols] = row_pos;
+-			tdsdump_dump_buf(TDS_DBG_NETWORK, "BCP row buffer so far", rowbuffer,  row_pos);
+-		}
+-	}
+-
+-	tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d\n", i, ncols, row_pos);
+-
+-	/*
+-	 * The rowbuffer ends with an offset table and, optionally, an adjustment table.  
+-	 * The offset table has 1-byte elements that describe the locations of the start of each column in
+-	 * the rowbuffer.  If the largest offset is greater than 255, another table -- the adjustment table --
+-	 * is inserted just before the offset table.  It holds the high bytes. 
+-	 * 
+-	 * Both tables are laid out in reverse:
+-	 * 	#elements, offset N+1, offset N, offset N-1, ... offset 0
+-	 * E.g. for 2 columns you have 4 data points:
+-	 *	1.  How many elements (4)
+-	 *	2.  Start of column 3 (non-existent, "one off the end")
+-	 *	3.  Start of column 2
+-	 *	4.  Start of column 1
+-	 *  The length of each column is computed by subtracting its start from the its successor's start. 
+-	 *
+-	 * The algorithm below computes both tables. If the adjustment table isn't needed, the 
+-	 * effect is to overwrite it with the offset table.  
+-	 */
+-	while (ncols && offsets[ncols] == offsets[ncols-1])
+-		ncols--;	/* trailing NULL columns are not sent and are not included in the offset table */
+-		
+-	if (ncols) {
+-		BYTE *padj = rowbuffer + row_pos;
+-		BYTE *poff = offsets[ncols] > 0xFF? padj + ncols + 1 : padj;
+-
+-		*padj++ = 1 + ncols;
+-		*poff++ = 1 + ncols;
+-		
+-		for (i=0; i <= ncols; i++) {
+-			padj[i] = offsets[ncols-i] >> 8;
+-			poff[i] = offsets[ncols-i] & 0xFF;
+-		}
+-		row_pos = poff + ncols + 1 - rowbuffer;
+-	}
+-
+-	tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d\n", i, ncols, row_pos);
+-	tdsdump_dump_buf(TDS_DBG_NETWORK, "BCP row buffer", rowbuffer,  row_pos);
+-	
+-	*pncols = ncols;
+-
+-	return ncols == 0? start : row_pos;
+-}
+-
+ /** 
+  * \ingroup dblib_bcp
+  * \brief Write data in host variables to the table.  
+@@ -1860,7 +1639,8 @@ bcp_sendrow(DBPROCESS * dbproc)
+ 
+ 	}
+ 
+-	return _bcp_send_bcp_record(dbproc, BCP_REC_FETCH_DATA);
++	dbproc->bcpinfo->parent = dbproc;
++	return tds_bcp_send_record(dbproc->tds_socket, dbproc->bcpinfo, _bcp_get_col_data, _bcp_null_error, 0);
+ }
+ 
+ 
+@@ -1917,6 +1697,7 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 	row_start = ftello(hostfile);
+ 	row_error_count = 0;
+ 	row_error = 0;
++	dbproc->bcpinfo->parent = dbproc;
+ 
+ 	while ((ret=_bcp_read_hostfile(dbproc, hostfile, &row_error)) == MORE_ROWS) {
+ 
+@@ -1995,7 +1776,7 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 			if (dbproc->hostfileinfo->firstrow <= row_of_hostfile && 
+ 							      row_of_hostfile <= MAX(dbproc->hostfileinfo->lastrow, 0x7FFFFFFF)) {
+ 
+-				if (_bcp_send_bcp_record(dbproc, BCP_REC_NOFETCH_DATA) == SUCCEED) {
++				if (tds_bcp_send_record(dbproc->tds_socket, dbproc->bcpinfo, _bcp_no_get_col_data, _bcp_null_error, 0) == TDS_SUCCEED) {
+ 			
+ 					rows_written_so_far++;
+ 	
+@@ -2925,233 +2706,11 @@ bcp_bind(DBPROCESS * dbproc, BYTE * varaddr, int prefixlen, DBINT varlen,
+ 	return SUCCEED;
+ }
+ 
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+- * \param dbproc contains all information needed by db-lib to manage communications with the server.
+- * \param behaviour 
+- * 
+- * \return SUCCEED or FAIL.
+- * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+- */
+-static RETCODE
+-_bcp_send_bcp_record(DBPROCESS * dbproc, BEHAVIOUR behaviour)
++static void
++_bcp_null_error(TDSBCPINFO *bcpinfo, int index, int offset)
+ {
+-	TDSSOCKET  *tds = dbproc->tds_socket;
+-	TDSCOLUMN  *bindcol;
+-
+-	static const TDS_TINYINT textptr_size = 16;
+-	static const unsigned char GEN_NULL = 0x00;
+-
+-	static const unsigned char CHARBIN_NULL[] =  { 0xff, 0xff };
+-	static const unsigned char textptr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
+-						 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+-	static const unsigned char timestamp[]={ 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+-
+-	unsigned char *record;
+-	TDS_INT	 old_record_size;
+-	TDS_INT	 new_record_size;
+-	TDS_INT	     varint_4;
+-	TDS_SMALLINT varint_2;
+-	TDS_TINYINT  varint_1;
+-
+-	int row_pos;
+-	int row_sz_pos;
+-	TDS_SMALLINT row_size;
+-	int blob_cols = 0;
+-	int var_cols_written = 0;
+-	int i;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_send_bcp_record(%p, %d)\n", dbproc, behaviour);
+-	CHECK_DBPROC();
+-	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+-
+-	record = dbproc->bcpinfo->bindinfo->current_row;
+-	old_record_size = dbproc->bcpinfo->bindinfo->row_size;
+-	new_record_size = 0;
+-
+-	if (IS_TDS7_PLUS(tds)) {
+-
+-		for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-	
+-			bindcol = dbproc->bcpinfo->bindinfo->columns[i];
+-
+-			/*
+-			 * Don't send the (meta)data for timestamp columns or
+-			 * identity columns unless indentity_insert is enabled.
+-			 */
+-
+-			if ((!dbproc->bcpinfo->identity_insert_on && bindcol->column_identity) || 
+-				bindcol->column_timestamp) {
+-				continue;
+-			}
+-
+-			if (behaviour == BCP_REC_FETCH_DATA) { 
+-				if ((_bcp_get_col_data(dbproc, bindcol)) != SUCCEED) {
+-					tdsdump_log(TDS_DBG_INFO1, "_bcp_get_col_data (column %d) failed\n", i + 1);
+-		 			return FAIL;
+-				}
+-			}
+-			tdsdump_log(TDS_DBG_INFO1, "parsed column %d, length %d (%snull)\n", i + 1, 
+-				    bindcol->bcp_column_data->datalen, bindcol->bcp_column_data->is_null? "":"not ");
+-	
+-			if (bindcol->bcp_column_data->is_null) {
+-				if (bindcol->column_nullable) {
+-					switch (bindcol->on_server.column_type) {
+-					case XSYBCHAR:
+-					case XSYBVARCHAR:
+-					case XSYBBINARY:
+-					case XSYBVARBINARY:
+-					case XSYBNCHAR:
+-					case XSYBNVARCHAR:
+-						memcpy(record, CHARBIN_NULL, 2);
+-						record +=2;
+-						new_record_size +=2;
+-						break;
+-					default:
+-						*record = GEN_NULL;
+-						record++;
+-						new_record_size ++;
+-						break;
+-					}
+-				} else {
+-					dbperror(dbproc, SYBEBCNN, 0);
+-					return FAIL;
+-				}
+-			} else {
+-
+-				switch (bindcol->column_varint_size) {
+-				case 4:
+-					if (is_blob_type(bindcol->column_type)) {
+-						*record = textptr_size; record++;
+-						memcpy(record, textptr, 16); record += 16;
+-						memcpy(record, timestamp, 8); record += 8;
+-						new_record_size += 25;
+-					}
+-					varint_4 = bindcol->bcp_column_data->datalen;
+-#if WORDS_BIGENDIAN
+-					tds_swap_datatype(SYBINT4, (unsigned char *)&varint_4);
+-#endif
+-					memcpy(record, &varint_4, 4); record += 4; new_record_size +=4;
+-					break;
+-				case 2:
+-					varint_2 = bindcol->bcp_column_data->datalen;
+-#if WORDS_BIGENDIAN
+-					tds_swap_datatype(SYBINT2, (unsigned char *)&varint_2);
+-#endif
+-					memcpy(record, &varint_2, 2); record += 2; new_record_size +=2;
+-					break;
+-				case 1:
+-					varint_1 = bindcol->bcp_column_data->datalen;
+-					if (is_numeric_type(bindcol->column_type)) { 
+-						varint_1 = tds_numeric_bytes_per_prec[bindcol->column_prec];
+-						tdsdump_log(TDS_DBG_INFO1, "numeric type prec = %d varint_1 = %d\n",
+-										 bindcol->column_prec, varint_1);
+-					}
+-					else {
+-						varint_1 = bindcol->bcp_column_data->datalen;
+-						tdsdump_log(TDS_DBG_INFO1, "varint_1 = %d\n", varint_1);
+-					}
+-					*record = varint_1; record++; new_record_size++;
+-					break;
+-				case 0:
+-					break;
+-				}
+-
+-				tdsdump_log(TDS_DBG_INFO1, "new_record_size = %d datalen = %d \n", 
+-							new_record_size, bindcol->bcp_column_data->datalen);
+-
+-#if WORDS_BIGENDIAN
+-				tds_swap_datatype(tds_get_conversion_type(bindcol->column_type, bindcol->bcp_column_data->datalen),
+-									bindcol->bcp_column_data->data);
+-#endif
+-				if (is_numeric_type(bindcol->column_type)) {
+-					TDS_NUMERIC *num = (TDS_NUMERIC *) bindcol->bcp_column_data->data;
+-					int size;
+-					tdsdump_log(TDS_DBG_INFO1, "numeric type prec = %d\n", num->precision);
+-					if (IS_TDS7_PLUS(tds))
+-						tds_swap_numeric(num);
+-					size = tds_numeric_bytes_per_prec[num->precision];
+-					memcpy(record, num->array, size);
+-					record += size; 
+-					new_record_size += size;
+-				} else {
+-					memcpy(record, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
+-					record += bindcol->bcp_column_data->datalen;
+-					new_record_size += bindcol->bcp_column_data->datalen;
+-				}
+-
+-			}
+-			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n",
+-					old_record_size, new_record_size);
+-		}
+-
+-		tds_put_byte(tds, TDS_ROW_TOKEN);   /* 0xd1 */
+-		tds_put_n(tds, dbproc->bcpinfo->bindinfo->current_row, new_record_size);
+-	}  /* IS_TDS7_PLUS */
+-	else {
+-			memset(record, '\0', old_record_size);	/* zero the rowbuffer */
+-
+-			/* offset 0 = number of var columns */
+-			/* offset 1 = row number.  zeroed (datasever assigns) */
+-			row_pos = 2;
+-
+-			if ((row_pos = _bcp_add_fixed_columns(dbproc, behaviour, record, row_pos)) == FAIL)
+-				return FAIL;
+-
+-			row_sz_pos = row_pos;
+-
+-			/* potential variable columns to write */
+-
+-			if (dbproc->bcpinfo->var_cols) {
+-				if ((row_pos = _bcp_add_variable_columns(dbproc, behaviour, record, row_pos, &var_cols_written)) == FAIL)
+-					return FAIL;
+-			}
+-
+-			row_size = row_pos;
+-
+-			if (var_cols_written) {
+-				memcpy(&record[row_sz_pos], &row_size, sizeof(row_size));
+-				record[0] = var_cols_written;
+-			}
+-
+-			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n", old_record_size, row_size);
+-
+-			tds_put_smallint(tds, row_size);
+-			tds_put_n(tds, record, row_size);
+-
+-			/* row is done, now handle any text/image data */
+-
+-			blob_cols = 0;
+-
+-			for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-				bindcol = dbproc->bcpinfo->bindinfo->columns[i];
+-				if (is_blob_type(bindcol->column_type)) {
+-					if (behaviour == BCP_REC_FETCH_DATA) { 
+-						if ((_bcp_get_col_data(dbproc, bindcol)) != SUCCEED) {
+-				 			return FAIL;
+-						}
+-					}
+-					/* unknown but zero */
+-					tds_put_smallint(tds, 0);
+-					tds_put_byte(tds, bindcol->column_type);
+-					tds_put_byte(tds, 0xff - blob_cols);
+-					/*
+-					 * offset of txptr we stashed during variable
+-					 * column processing 
+-					 */
+-					tds_put_smallint(tds, bindcol->column_textpos);
+-					tds_put_int(tds, bindcol->bcp_column_data->datalen);
+-					tds_put_n(tds, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
+-					blob_cols++;
+-
+-				}
+-			}
+-			return SUCCEED;
+-	}
+-
+-	return SUCCEED;
++	DBPROCESS *dbproc = (DBPROCESS *) bcpinfo->parent;
++	dbperror(dbproc, SYBEBCNN, 0);
+ }
+ 
+ /** 
+@@ -3164,8 +2723,8 @@ _bcp_send_bcp_record(DBPROCESS * dbproc, BEHAVIOUR behaviour)
+  * \return SUCCEED or FAIL.
+  * \sa 	_bcp_add_fixed_columns, _bcp_add_variable_columns, _bcp_send_bcp_record
+  */
+-static RETCODE
+-_bcp_get_col_data(DBPROCESS * dbproc, TDSCOLUMN *bindcol)
++static int
++_bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset)
+ {
+ 	TDS_TINYINT ti;
+ 	TDS_SMALLINT si;
+@@ -3176,8 +2735,9 @@ _bcp_get_col_data(DBPROCESS * dbproc, TDSCOLUMN *bindcol)
+ 	int bytes_read;
+ 	int converted_data_size;
+ 	BYTE *dataptr;
++	DBPROCESS *dbproc = (DBPROCESS *) bcpinfo->parent;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_get_col_data(%p, %p)\n", dbproc, bindcol);
++	tdsdump_log(TDS_DBG_FUNC, "_bcp_get_col_data(%p, %p)\n", bcpinfo, bindcol);
+ 	CHECK_DBPROC();
+ 	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+ 	CHECK_NULP(bindcol, "_bcp_get_col_data", 2, FAIL);
+@@ -3256,7 +2816,7 @@ _bcp_get_col_data(DBPROCESS * dbproc, TDSCOLUMN *bindcol)
+ 		     dbconvert(dbproc, bindcol->column_bindtype,
+ 			       (BYTE *) dataptr, collen,
+ 			       desttype, bindcol->bcp_column_data->data, bindcol->column_size)) == FAIL) {
+-			return (FAIL);
++			return TDS_FAIL;
+ 		}
+ 
+ 		bindcol->bcp_column_data->datalen = converted_data_size;
+@@ -3264,7 +2824,13 @@ _bcp_get_col_data(DBPROCESS * dbproc, TDSCOLUMN *bindcol)
+ 		assert(converted_data_size > 0);
+ 	}
+ 
+-	return SUCCEED;
++	return TDS_SUCCEED;
++}
++
++static int
++_bcp_no_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset)
++{
++	return TDS_SUCCEED;
+ }
+ 
+ /**
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 3dc46fb..ed99070 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.1 2008/12/12 13:56:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.2 2008/12/15 12:33:57 freddy77 Exp $");
+ 
+ typedef struct tds_pbcb
+ {
+@@ -51,6 +51,9 @@ typedef struct tds_pbcb
+ 	unsigned int from_malloc;
+ } TDSPBCB;
+ 
++static int tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, unsigned char * rowbuffer, int start);
++static int tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, TDS_UCHAR *rowbuffer, int start, int *pncols);
++
+ /** 
+  * \return TDS_SUCCEED or TDS_FAIL.
+  */
+@@ -287,3 +290,408 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo)
+ 
+ 	return TDS_SUCCEED;
+ }
++
++/** 
++ * \return TDS_SUCCEED or TDS_FAIL.
++ */
++int
++tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset)
++{
++	TDSCOLUMN  *bindcol;
++
++	static const TDS_TINYINT textptr_size = 16;
++	static const unsigned char GEN_NULL = 0x00;
++
++	static const unsigned char CHARBIN_NULL[] = { 0xff, 0xff };
++	static const unsigned char textptr[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
++											 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
++	static const unsigned char timestamp[] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
++
++	unsigned char *record;
++	TDS_INT	 old_record_size;
++	TDS_INT	 new_record_size;
++	TDS_INT	     varint_4;
++	TDS_SMALLINT varint_2;
++	TDS_TINYINT  varint_1;
++
++	int row_pos;
++	int row_sz_pos;
++	TDS_SMALLINT row_size;
++	int blob_cols = 0;
++	int var_cols_written = 0;
++	int i;
++
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_bcp_record(offset %d)\n", offset);
++
++	record = bcpinfo->bindinfo->current_row;
++	old_record_size = bcpinfo->bindinfo->row_size;
++	new_record_size = 0;
++
++	if (IS_TDS7_PLUS(tds)) {
++
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++	
++			bindcol = bcpinfo->bindinfo->columns[i];
++
++			/*
++			 * Don't send the (meta)data for timestamp columns or
++			 * identity columns unless indentity_insert is enabled.
++			 */
++
++			if ((!bcpinfo->identity_insert_on && bindcol->column_identity) || 
++				bindcol->column_timestamp) {
++				continue;
++			}
++
++			if ((get_col_data(bcpinfo, bindcol, offset)) != TDS_SUCCEED) {
++				tdsdump_log(TDS_DBG_INFO1, "blk_get_colData (column %d) failed\n", i + 1);
++	 			return TDS_FAIL;
++			}
++			tdsdump_log(TDS_DBG_INFO1, "gotten column %d length %d null %d\n",
++					i + 1, bindcol->bcp_column_data->datalen, bindcol->bcp_column_data->is_null);
++	
++			if (bindcol->bcp_column_data->is_null) {
++				if (bindcol->column_nullable) {
++					switch (bindcol->on_server.column_type) {
++					case XSYBCHAR:
++					case XSYBVARCHAR:
++					case XSYBBINARY:
++					case XSYBVARBINARY:
++					case XSYBNCHAR:
++					case XSYBNVARCHAR:
++						memcpy(record, CHARBIN_NULL, 2);
++						record +=2;
++						new_record_size +=2;
++						break;
++					default:
++						*record = GEN_NULL;
++						record++;
++						new_record_size ++;
++						break;
++					}
++				} else {
++					/* No value or default value available and NULL not allowed. */
++					null_error(bcpinfo, i, offset);
++					return TDS_FAIL;
++				}
++			} else {
++
++				switch (bindcol->column_varint_size) {
++				case 4:
++					if (is_blob_type(bindcol->on_server.column_type)) {
++						*record = textptr_size; record++;
++						memcpy(record, textptr, 16); record += 16;
++						memcpy(record, timestamp, 8); record += 8;
++						new_record_size += 25;
++					}
++					varint_4 = bindcol->bcp_column_data->datalen;
++#if WORDS_BIGENDIAN
++					tds_swap_datatype(SYBINT4, (unsigned char *)&varint_4);
++#endif
++					memcpy(record, &varint_4, 4); record += 4; new_record_size +=4;
++					break;
++				case 2:
++					varint_2 = bindcol->bcp_column_data->datalen;
++#if WORDS_BIGENDIAN
++					tds_swap_datatype(SYBINT2, (unsigned char *)&varint_2);
++#endif
++					memcpy(record, &varint_2, 2); record += 2; new_record_size +=2;
++					break;
++				case 1:
++					varint_1 = bindcol->bcp_column_data->datalen;
++					if (is_numeric_type(bindcol->on_server.column_type)) {
++						varint_1 = tds_numeric_bytes_per_prec[bindcol->column_prec];
++						tdsdump_log(TDS_DBG_INFO1, "numeric type prec = %d varint_1 = %d\n",
++										 bindcol->column_prec, varint_1);
++					} else {
++						varint_1 = bindcol->bcp_column_data->datalen;
++						tdsdump_log(TDS_DBG_INFO1, "varint_1 = %d\n", varint_1);
++					}
++					*record = varint_1; record++; new_record_size++;
++					break;
++				case 0:
++					break;
++				}
++
++				tdsdump_log(TDS_DBG_INFO1, "new_record_size = %d datalen = %d \n", 
++							new_record_size, bindcol->bcp_column_data->datalen);
++
++#if WORDS_BIGENDIAN
++				tds_swap_datatype(tds_get_conversion_type(bindcol->column_type, bindcol->bcp_column_data->datalen),
++									bindcol->bcp_column_data->data);
++#endif
++				if (is_numeric_type(bindcol->on_server.column_type)) {
++					TDS_NUMERIC *num = (TDS_NUMERIC *) bindcol->bcp_column_data->data;
++					int size;
++					tdsdump_log(TDS_DBG_INFO1, "numeric type prec = %d\n", num->precision);
++					if (IS_TDS7_PLUS(tds))
++						tds_swap_numeric(num);
++					size = tds_numeric_bytes_per_prec[num->precision];
++					memcpy(record, num->array, size);
++					record += size; 
++					new_record_size += size;
++				} else {
++					memcpy(record, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
++					record += bindcol->bcp_column_data->datalen;
++					new_record_size += bindcol->bcp_column_data->datalen;
++				}
++
++			}
++			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n",
++					old_record_size, new_record_size);
++		}
++
++		tds_put_byte(tds, TDS_ROW_TOKEN);   /* 0xd1 */
++		tds_put_n(tds, bcpinfo->bindinfo->current_row, new_record_size);
++	}  /* IS_TDS7_PLUS */
++	else {
++		memset(record, '\0', old_record_size);	/* zero the rowbuffer */
++
++		/*
++		 * offset 0 = number of var columns
++		 * offset 1 = row number.  zeroed (datasever assigns)
++		 */
++		row_pos = 2;
++
++		if ((row_pos = tds_bcp_add_fixed_columns(bcpinfo, get_col_data, null_error, offset, record, row_pos)) == TDS_FAIL)
++			return TDS_FAIL;
++
++		row_sz_pos = row_pos;
++
++		/* potential variable columns to write */
++
++		if (bcpinfo->var_cols) {
++			if ((row_pos = tds_bcp_add_variable_columns(bcpinfo, get_col_data, null_error, offset, record, row_pos, &var_cols_written)) == TDS_FAIL)
++				return TDS_FAIL;
++		}
++
++		row_size = row_pos;
++
++		if (var_cols_written) {
++			memcpy(&record[row_sz_pos], &row_size, sizeof(row_size));
++			record[0] = var_cols_written;
++		}
++
++		tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n", old_record_size, row_size);
++
++		tds_put_smallint(tds, row_size);
++		tds_put_n(tds, record, row_size);
++
++		/* row is done, now handle any text/image data */
++
++		blob_cols = 0;
++
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++			bindcol = bcpinfo->bindinfo->columns[i];
++			if (is_blob_type(bindcol->column_type)) {
++				if ((get_col_data(bcpinfo, bindcol, offset)) != TDS_SUCCEED) {
++					return TDS_FAIL;
++				}
++				/* unknown but zero */
++				tds_put_smallint(tds, 0);
++				tds_put_byte(tds, bindcol->column_type);
++				tds_put_byte(tds, 0xff - blob_cols);
++				/*
++				 * offset of txptr we stashed during variable
++				 * column processing 
++				 */
++				tds_put_smallint(tds, bindcol->column_textpos);
++				tds_put_int(tds, bindcol->bcp_column_data->datalen);
++				tds_put_n(tds, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
++				blob_cols++;
++
++			}
++		}
++	}
++
++	return TDS_SUCCEED;
++}
++
++/**
++ * Add fixed size columns to the row
++ */
++static int
++tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, unsigned char * rowbuffer, int start)
++{
++	TDS_NUMERIC *num;
++	int row_pos = start;
++	TDSCOLUMN *bcpcol;
++	int cpbytes;
++	int i, j;
++
++	assert(bcpinfo);
++	assert(rowbuffer);
++
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns(%p, %p, %d)\n", bcpinfo, rowbuffer, start);
++
++	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++
++		bcpcol = bcpinfo->bindinfo->columns[i];
++
++		if (!is_nullable_type(bcpcol->column_type) && !(bcpcol->column_nullable)) {
++
++			tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns column %d is a fixed column\n", i + 1);
++
++			if ((get_col_data(bcpinfo, bcpcol, offset)) != TDS_SUCCEED) {
++				tdsdump_log(TDS_DBG_INFO1, "bcp_get_colData (column %d) failed\n", i + 1);
++		 		return TDS_FAIL;
++			}
++
++			if (bcpcol->bcp_column_data->is_null) {
++				/* No value or default value available and NULL not allowed. */
++				null_error(bcpinfo, i, offset);
++				return TDS_FAIL;
++			}
++
++			if (is_numeric_type(bcpcol->column_type)) {
++				num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
++				cpbytes = tds_numeric_bytes_per_prec[num->precision];
++				memcpy(&rowbuffer[row_pos], num->array, cpbytes);
++			} else {
++				cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ?
++					  bcpcol->column_size : bcpcol->bcp_column_data->datalen;
++				memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);
++
++				/* CHAR data may need padding out to the database length with blanks */
++
++				if (bcpcol->column_type == SYBCHAR && cpbytes < bcpcol->column_size) {
++					for (j = cpbytes; j <  bcpcol->column_size; j++)
++						rowbuffer[row_pos + j] = ' ';
++
++				}
++			}
++
++			row_pos += bcpcol->column_size;
++		}
++	}
++	return row_pos;
++}
++
++/**
++ * Add variable size columns to the row
++ *
++ * \param rowbuffer The row image that will be sent to the server. 
++ * \param start Where to begin copying data into the rowbuffer. 
++ * \param pncols Address of output variable holding the count of columns added to the rowbuffer.  
++ * 
++ * \return length of (potentially modified) rowbuffer, or TDS_FAIL.
++ */
++static int
++tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, TDS_UCHAR* rowbuffer, int start, int *pncols)
++{
++	TDS_SMALLINT offsets[256];
++	int i, row_pos;
++	int ncols = 0;
++
++	assert(bcpinfo);
++	assert(rowbuffer);
++	assert(pncols);
++
++	tdsdump_log(TDS_DBG_FUNC, "%4s %8s %18s %18s %8s\n", 	"col", 
++								"type", 
++								"is_nullable_type", 
++								"column_nullable", 
++								"is null" );
++	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++		TDSCOLUMN *bcpcol = bcpinfo->bindinfo->columns[i];
++		tdsdump_log(TDS_DBG_FUNC, "%4d %8d %18s %18s %8s\n", 	i, 
++									bcpcol->column_type,  
++									is_nullable_type(bcpcol->column_type)? "yes" : "no", 
++									bcpcol->column_nullable? "yes" : "no", 
++									bcpcol->bcp_column_data->is_null? "yes" : "no" );
++	}
++
++	/* the first two bytes of the rowbuffer are reserved to hold the entire record length */
++	row_pos = start + 2;
++	offsets[0] = row_pos;
++
++	tdsdump_log(TDS_DBG_FUNC, "%4s %8s %8s %8s\n", "col", "ncols", "row_pos", "cpbytes");
++
++	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++		int cpbytes = 0;
++		TDSCOLUMN *bcpcol = bcpinfo->bindinfo->columns[i];
++
++		/*
++		 * Is this column of "variable" type, i.e. NULLable
++		 * or naturally variable length e.g. VARCHAR
++		 */
++		if (is_nullable_type(bcpcol->column_type) || bcpcol->column_nullable) {
++
++			tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d %8d\n", i, ncols, row_pos, cpbytes);
++
++			if ((get_col_data(bcpinfo, bcpcol, offset)) != TDS_SUCCEED)
++		 		return TDS_FAIL;
++
++			/* If it's a NOT NULL column, and we have no data, throw an error. */
++			if (!(bcpcol->column_nullable) && bcpcol->bcp_column_data->is_null) {
++				/* No value or default value available and NULL not allowed. */
++				null_error(bcpinfo, i, offset);
++				return TDS_FAIL;
++			}
++
++			/* move the column buffer into the rowbuffer */
++			if (!bcpcol->bcp_column_data->is_null) {
++				if (is_blob_type(bcpcol->column_type)) {
++					cpbytes = 16;
++					bcpcol->column_textpos = row_pos;               /* save for data write */
++				} else if (is_numeric_type(bcpcol->column_type)) {
++						TDS_NUMERIC *num = (TDS_NUMERIC *) bcpcol->bcp_column_data->data;
++					cpbytes = tds_numeric_bytes_per_prec[num->precision];
++					memcpy(&rowbuffer[row_pos], num->array, cpbytes);
++				} else {
++					cpbytes = bcpcol->bcp_column_data->datalen > bcpcol->column_size ?
++					bcpcol->column_size : bcpcol->bcp_column_data->datalen;
++					memcpy(&rowbuffer[row_pos], bcpcol->bcp_column_data->data, cpbytes);
++				}
++			}
++
++			row_pos += cpbytes;
++			offsets[++ncols] = row_pos;
++			tdsdump_dump_buf(TDS_DBG_NETWORK, "BCP row buffer so far", rowbuffer,  row_pos);
++		}
++	}
++
++	tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d\n", i, ncols, row_pos);
++
++	/*
++	 * The rowbuffer ends with an offset table and, optionally, an adjustment table.  
++	 * The offset table has 1-byte elements that describe the locations of the start of each column in
++	 * the rowbuffer.  If the largest offset is greater than 255, another table -- the adjustment table --
++	 * is inserted just before the offset table.  It holds the high bytes. 
++	 * 
++	 * Both tables are laid out in reverse:
++	 * 	#elements, offset N+1, offset N, offset N-1, ... offset 0
++	 * E.g. for 2 columns you have 4 data points:
++	 *	1.  How many elements (4)
++	 *	2.  Start of column 3 (non-existent, "one off the end")
++	 *	3.  Start of column 2
++	 *	4.  Start of column 1
++	 *  The length of each column is computed by subtracting its start from the its successor's start. 
++	 *
++	 * The algorithm below computes both tables. If the adjustment table isn't needed, the 
++	 * effect is to overwrite it with the offset table.  
++	 */
++	while (ncols && offsets[ncols] == offsets[ncols-1])
++		ncols--;	/* trailing NULL columns are not sent and are not included in the offset table */
++
++	if (ncols) {
++		TDS_UCHAR *padj = rowbuffer + row_pos;
++		TDS_UCHAR *poff = offsets[ncols] > 0xFF? padj + ncols + 1 : padj;
++
++		*padj++ = 1 + ncols;
++		*poff++ = 1 + ncols;
++		
++		for (i=0; i <= ncols; i++) {
++			padj[i] = offsets[ncols-i] >> 8;
++			poff[i] = offsets[ncols-i] & 0xFF;
++		}
++		row_pos = poff + ncols + 1 - rowbuffer;
++	}
++
++	tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d\n", i, ncols, row_pos);
++	tdsdump_dump_buf(TDS_DBG_NETWORK, "BCP row buffer", rowbuffer,  row_pos);
++
++	*pncols = ncols;
++
++	return ncols == 0? start : row_pos;
++}
+
+commit 2c8839bf64b3d30f83429dc8983ef77952fe1042
+Author: freddy77 <freddy77>
+Date:   Mon Dec 15 13:21:45 2008 +0000
+
+    add and reuse tds_bcp_send_colmetadata
+
+diff --git a/ChangeLog b/ChangeLog
+index 547c5b4..5e66c86 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Dec 15 14:18:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
++	- add and reuse tds_bcp_send_colmetadata
++	- fix some tdsdump_log in bulk.c
++
+ Mon Dec 15 13:33:10 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
+ 	- add and reuse tds_bcp_send_record
+@@ -1064,4 +1069,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2680 2008/12/15 12:33:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2681 2008/12/15 13:21:45 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 02972ee..a25c018 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.305 2008/12/15 12:33:57 freddy77 Exp $ */
++/* $Id: tds.h,v 1.306 2008/12/15 13:21:45 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1616,6 +1616,8 @@ typedef int  (*tds_bcp_get_col_data) (TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int o
+ typedef void (*tds_bcp_null_error)   (TDSBCPINFO *bulk, int index, int offset);
+ int tds_bcp_start_insert_stmt(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ int tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset);
++int tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++
+ 
+ #define IS_TDS42(x) (x->major_version==4 && x->minor_version==2)
+ #define IS_TDS46(x) (x->major_version==4 && x->minor_version==6)
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 18f6560..52939f0 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,11 +38,10 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.45 2008/12/15 12:33:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.46 2008/12/15 13:21:45 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+-static CS_RETCODE _blk_send_colmetadata(CS_BLKDESC * blkdesc);
+ static CS_RETCODE _rowxfer_in_init(CS_BLKDESC * blkdesc);
+ static CS_RETCODE _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+ static CS_RETCODE _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+@@ -246,9 +245,8 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow)
+ 
+ 		tds->out_flag = TDS_BULK;
+ 
+-		if (IS_TDS7_PLUS(tds)) {
+-			_blk_send_colmetadata(blkdesc);
+-		}
++		if (IS_TDS7_PLUS(tds))
++			tds_bcp_send_colmetadata(tds, &blkdesc->bcpinfo);
+ 
+ 		break;
+ 		
+@@ -706,9 +704,8 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 		/* set packet type to send bulk data */
+ 		tds->out_flag = TDS_BULK;
+ 
+-		if (IS_TDS7_PLUS(tds)) {
+-			_blk_send_colmetadata(blkdesc);
+-		}
++		if (IS_TDS7_PLUS(tds))
++			tds_bcp_send_colmetadata(tds, &blkdesc->bcpinfo);
+ 
+ 		blkdesc->bcpinfo.xfer_init = 1;
+ 	} 
+@@ -818,89 +815,6 @@ _rowxfer_in_init(CS_BLKDESC * blkdesc)
+ 	return CS_SUCCEED;
+ }
+ 
+-static CS_RETCODE
+-_blk_send_colmetadata(CS_BLKDESC * blkdesc)
+-{
+-
+-	TDSSOCKET *tds = blkdesc->con->tds_socket;
+-	unsigned char colmetadata_token = 0x81;
+-	TDSCOLUMN *bcpcol;
+-	int i;
+-	TDS_SMALLINT num_cols;
+-
+-	/* 
+-	 * Deep joy! For TDS 8 we have to send a colmetadata message followed by row data 
+-	 */
+-	tds_put_byte(tds, colmetadata_token);	/* 0x81 */
+-
+-	num_cols = 0;
+-	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+-		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+-		if ((!blkdesc->bcpinfo.identity_insert_on && bcpcol->column_identity) || 
+-			bcpcol->column_timestamp) {
+-			continue;
+-		}
+-		num_cols++;
+-	}
+-
+-	tds_put_smallint(tds, num_cols);
+-
+-	for (i = 0; i < blkdesc->bcpinfo.bindinfo->num_cols; i++) {
+-		bcpcol = blkdesc->bcpinfo.bindinfo->columns[i];
+-
+-		/*
+-		 * dont send the (meta)data for timestamp columns, or
+-		 * identity columns (unless indentity_insert is enabled
+-		 */
+-
+-		if ((!blkdesc->bcpinfo.identity_insert_on && bcpcol->column_identity) || 
+-			bcpcol->column_timestamp) {
+-			continue;
+-		}
+-
+-		if (IS_TDS90(tds))
+-			tds_put_int(tds, bcpcol->column_usertype);
+-		else
+-			tds_put_smallint(tds, bcpcol->column_usertype);
+-		tds_put_smallint(tds, bcpcol->column_flags);
+-		tds_put_byte(tds, bcpcol->on_server.column_type);
+-
+-		switch (bcpcol->column_varint_size) {
+-		case 4:
+-			tds_put_int(tds, bcpcol->column_size);
+-			break;
+-		case 2:
+-			tds_put_smallint(tds, bcpcol->column_size);
+-			break;
+-		case 1:
+-			tds_put_byte(tds, bcpcol->column_size);
+-			break;
+-		case 0:
+-			break;
+-		default:
+-			break;
+-		}
+-
+-		if (is_numeric_type(bcpcol->on_server.column_type)) {
+-			tds_put_byte(tds, bcpcol->column_prec);
+-			tds_put_byte(tds, bcpcol->column_scale);
+-		}
+-		if (IS_TDS8_PLUS(tds)
+-			&& is_collate_type(bcpcol->on_server.column_type)) {
+-			tds_put_n(tds, bcpcol->column_collation, 5);
+-		}
+-		if (is_blob_type(bcpcol->on_server.column_type)) {
+-			tds_put_smallint(tds, strlen(blkdesc->bcpinfo.tablename));
+-			tds_put_string(tds, blkdesc->bcpinfo.tablename, strlen(blkdesc->bcpinfo.tablename));
+-		}
+-		/* FIXME support multibyte string */
+-		tds_put_byte(tds, bcpcol->column_namelen);
+-		tds_put_string(tds, bcpcol->column_name, bcpcol->column_namelen);
+-
+-	}
+-	return CS_SUCCEED;
+-}
+-
+ static void
+ _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset)
+ {
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 6a53df9..85b5e31 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.175 2008/12/15 12:33:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.176 2008/12/15 13:21:45 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -82,7 +82,6 @@ static void _bcp_free_columns(DBPROCESS * dbproc);
+ static void _bcp_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset);
+ static int _bcp_no_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset);
+-static RETCODE _bcp_send_colmetadata(DBPROCESS *);
+ static RETCODE _bcp_start_copy_in(DBPROCESS *);
+ static RETCODE _bcp_start_new_batch(DBPROCESS *);
+ 
+@@ -1631,9 +1630,8 @@ bcp_sendrow(DBPROCESS * dbproc)
+ 		tds->out_flag = TDS_BULK;
+ 		tds_set_state(tds, TDS_QUERYING);
+ 
+-		if (IS_TDS7_PLUS(tds)) {
+-			_bcp_send_colmetadata(dbproc);
+-		}
++		if (IS_TDS7_PLUS(tds))
++			tds_bcp_send_colmetadata(tds, dbproc->bcpinfo);
+ 
+ 		dbproc->bcpinfo->xfer_init = 1;
+ 
+@@ -1687,9 +1685,8 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 	tds->out_flag = TDS_BULK;
+ 	tds_set_state(tds, TDS_QUERYING);
+ 
+-	if (IS_TDS7_PLUS(tds)) {
+-		_bcp_send_colmetadata(dbproc);
+-	}
++	if (IS_TDS7_PLUS(tds))
++		tds_bcp_send_colmetadata(tds, dbproc->bcpinfo);
+ 
+ 	row_of_hostfile = 0;
+ 	rows_written_so_far = 0;
+@@ -2060,9 +2057,8 @@ _bcp_start_new_batch(DBPROCESS * dbproc)
+ 	tds->out_flag = TDS_BULK;
+ 	tds_set_state(tds, TDS_QUERYING);
+ 
+-	if (IS_TDS7_PLUS(tds)) {
+-		_bcp_send_colmetadata(dbproc);
+-	}
++	if (IS_TDS7_PLUS(tds))
++		tds_bcp_send_colmetadata(tds, dbproc->bcpinfo);
+ 	
+ 	return SUCCEED;
+ }
+@@ -2071,101 +2067,6 @@ _bcp_start_new_batch(DBPROCESS * dbproc)
+  * \ingroup dblib_bcp_internal
+  * \brief 
+  *
+- * \param dbproc contains all information needed by db-lib to manage communications with the server.
+- * 
+- * \return SUCCEED or FAIL.
+- * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+- */
+-static RETCODE
+-_bcp_send_colmetadata(DBPROCESS * dbproc)
+-{
+-	const static unsigned char colmetadata_token = 0x81;
+-	TDSSOCKET *tds = dbproc->tds_socket;
+-	TDSCOLUMN *bcpcol;
+-	int i, num_cols;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_send_colmetadata(%p)\n", dbproc);
+-	assert(dbproc);
+-
+-	/* 
+-	 * Deep joy! For TDS 8 we have to send a colmetadata message followed by row data 
+-	 */
+-	tds_put_byte(tds, colmetadata_token);	/* 0x81 */
+-
+-	num_cols = 0;
+-	for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-		bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
+-		if ((!dbproc->bcpinfo->identity_insert_on && bcpcol->column_identity) ||
+-			bcpcol->column_timestamp) {
+-			continue;
+-		}
+-		num_cols++;
+-	}
+-
+-	tds_put_smallint(tds, num_cols);
+-
+-	for (i = 0; i < dbproc->bcpinfo->bindinfo->num_cols; i++) {
+-		bcpcol = dbproc->bcpinfo->bindinfo->columns[i];
+-
+-	/*
+-	 * dont send the (meta)data for timestamp columns, or
+-	 * identity columns (unless indentity_insert is enabled
+-	 */
+-
+-        if ((!dbproc->bcpinfo->identity_insert_on && bcpcol->column_identity) ||
+-            bcpcol->column_timestamp) {
+-            continue;
+-        }
+-
+-		if (IS_TDS90(tds))
+-			tds_put_int(tds, bcpcol->column_usertype);
+-		else
+-			tds_put_smallint(tds, bcpcol->column_usertype);
+-		tds_put_smallint(tds, bcpcol->column_flags);
+-		tds_put_byte(tds, bcpcol->on_server.column_type);
+-
+-		switch (bcpcol->column_varint_size) {
+-		case 4:
+-			tds_put_int(tds, bcpcol->column_size);
+-			break;
+-		case 2:
+-			tds_put_smallint(tds, bcpcol->column_size);
+-			break;
+-		case 1:
+-			tds_put_byte(tds, bcpcol->column_size);
+-			break;
+-		case 0:
+-			break;
+-		default:
+-			break;
+-		}
+-
+-		if (is_numeric_type(bcpcol->on_server.column_type)) {
+-			tds_put_byte(tds, bcpcol->column_prec);
+-			tds_put_byte(tds, bcpcol->column_scale);
+-		}
+-		if (IS_TDS8_PLUS(tds)
+-		    && is_collate_type(bcpcol->on_server.column_type)) {
+-			tds_put_n(tds, bcpcol->column_collation, 5);
+-		}
+-		if (is_blob_type(bcpcol->on_server.column_type)) {
+-			/* FIXME strlen return len in bytes not in characters required here */
+-			tds_put_smallint(tds, strlen(dbproc->bcpinfo->tablename));
+-			tds_put_string(tds, dbproc->bcpinfo->tablename, strlen(dbproc->bcpinfo->tablename));
+-		}
+-		/* FIXME column_namelen contains len in bytes not in characters required here */
+-		tds_put_byte(tds, bcpcol->column_namelen);
+-		tds_put_string(tds, bcpcol->column_name, bcpcol->column_namelen);
+-
+-	}
+-
+-	return SUCCEED;
+-}
+-
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+  * \param buffer 
+  * \param size 
+  * \param f 
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index ed99070..89f0b9a 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.2 2008/12/15 12:33:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.3 2008/12/15 13:21:45 freddy77 Exp $");
+ 
+ typedef struct tds_pbcb
+ {
+@@ -344,7 +344,7 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 			}
+ 
+ 			if ((get_col_data(bcpinfo, bindcol, offset)) != TDS_SUCCEED) {
+-				tdsdump_log(TDS_DBG_INFO1, "blk_get_colData (column %d) failed\n", i + 1);
++				tdsdump_log(TDS_DBG_INFO1, "get_col_data (column %d) failed\n", i + 1);
+ 	 			return TDS_FAIL;
+ 			}
+ 			tdsdump_log(TDS_DBG_INFO1, "gotten column %d length %d null %d\n",
+@@ -522,7 +522,7 @@ tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data
+ 	assert(bcpinfo);
+ 	assert(rowbuffer);
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns(%p, %p, %d)\n", bcpinfo, rowbuffer, start);
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns(%p, %p, %p, %d, %p, %d)\n", bcpinfo, get_col_data, null_error, offset, rowbuffer, start);
+ 
+ 	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+ 
+@@ -533,7 +533,7 @@ tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data
+ 			tdsdump_log(TDS_DBG_FUNC, "tds_bcp_add_fixed_columns column %d is a fixed column\n", i + 1);
+ 
+ 			if ((get_col_data(bcpinfo, bcpcol, offset)) != TDS_SUCCEED) {
+-				tdsdump_log(TDS_DBG_INFO1, "bcp_get_colData (column %d) failed\n", i + 1);
++				tdsdump_log(TDS_DBG_INFO1, "get_col_data (column %d) failed\n", i + 1);
+ 		 		return TDS_FAIL;
+ 			}
+ 
+@@ -695,3 +695,91 @@ tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_d
+ 
+ 	return ncols == 0? start : row_pos;
+ }
++
++/** 
++ * \return TDS_SUCCEED or TDS_FAIL.
++ */
++int
++tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
++{
++	const static unsigned char colmetadata_token = 0x81;
++	TDSCOLUMN *bcpcol;
++	int i, num_cols;
++
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_colmetadata(%p, %p)\n", tds, bcpinfo);
++	assert(tds && bcpinfo);
++
++	/* 
++	 * Deep joy! For TDS 8 we have to send a colmetadata message followed by row data 
++	 */
++	tds_put_byte(tds, colmetadata_token);	/* 0x81 */
++
++	num_cols = 0;
++	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++		bcpcol = bcpinfo->bindinfo->columns[i];
++		if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || 
++			bcpcol->column_timestamp) {
++			continue;
++		}
++		num_cols++;
++	}
++
++	tds_put_smallint(tds, num_cols);
++
++	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++		bcpcol = bcpinfo->bindinfo->columns[i];
++
++		/*
++		 * dont send the (meta)data for timestamp columns, or
++		 * identity columns (unless indentity_insert is enabled
++		 */
++
++		if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || 
++			bcpcol->column_timestamp) {
++			continue;
++		}
++
++		if (IS_TDS90(tds))
++			tds_put_int(tds, bcpcol->column_usertype);
++		else
++			tds_put_smallint(tds, bcpcol->column_usertype);
++		tds_put_smallint(tds, bcpcol->column_flags);
++		tds_put_byte(tds, bcpcol->on_server.column_type);
++
++		switch (bcpcol->column_varint_size) {
++		case 4:
++			tds_put_int(tds, bcpcol->column_size);
++			break;
++		case 2:
++			tds_put_smallint(tds, bcpcol->column_size);
++			break;
++		case 1:
++			tds_put_byte(tds, bcpcol->column_size);
++			break;
++		case 0:
++			break;
++		default:
++			break;
++		}
++
++		if (is_numeric_type(bcpcol->on_server.column_type)) {
++			tds_put_byte(tds, bcpcol->column_prec);
++			tds_put_byte(tds, bcpcol->column_scale);
++		}
++		if (IS_TDS8_PLUS(tds)
++			&& is_collate_type(bcpcol->on_server.column_type)) {
++			tds_put_n(tds, bcpcol->column_collation, 5);
++		}
++		if (is_blob_type(bcpcol->on_server.column_type)) {
++			/* FIXME strlen return len in bytes not in characters required here */
++			tds_put_smallint(tds, strlen(bcpinfo->tablename));
++			tds_put_string(tds, bcpinfo->tablename, strlen(bcpinfo->tablename));
++		}
++		/* FIXME support multibyte string */
++		tds_put_byte(tds, bcpcol->column_namelen);
++		tds_put_string(tds, bcpcol->column_name, bcpcol->column_namelen);
++
++	}
++
++	return TDS_SUCCEED;
++}
+
+commit 0b7bd5c227cd8c9d720bea2cb3363ece3d7b21e7
+Author: freddy77 <freddy77>
+Date:   Mon Dec 15 15:52:10 2008 +0000
+
+    add and reuse tds_bcp_done, tds_bcp_start and tds_bcp_start_copy_in
+
+diff --git a/ChangeLog b/ChangeLog
+index 5e66c86..f5f4b5b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Dec 15 16:48:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
++	- add and reuse tds_bcp_done, tds_bcp_start and tds_bcp_start_copy_in
++
+ Mon Dec 15 14:18:38 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
+ 	- add and reuse tds_bcp_send_colmetadata
+@@ -1069,4 +1073,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2681 2008/12/15 13:21:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2682 2008/12/15 15:52:10 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index a25c018..025d154 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.306 2008/12/15 13:21:45 freddy77 Exp $ */
++/* $Id: tds.h,v 1.307 2008/12/15 15:52:10 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1614,9 +1614,10 @@ typedef struct tds_bcpinfo
+ 
+ typedef int  (*tds_bcp_get_col_data) (TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+ typedef void (*tds_bcp_null_error)   (TDSBCPINFO *bulk, int index, int offset);
+-int tds_bcp_start_insert_stmt(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ int tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset);
+-int tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++int tds_bcp_done(TDSSOCKET *tds, int *rows_copied);
++int tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++int tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ 
+ 
+ #define IS_TDS42(x) (x->major_version==4 && x->minor_version==2)
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 52939f0..6849b68 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,11 +38,10 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.46 2008/12/15 13:21:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.47 2008/12/15 15:52:10 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+-static CS_RETCODE _rowxfer_in_init(CS_BLKDESC * blkdesc);
+ static CS_RETCODE _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+ static CS_RETCODE _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred);
+ 
+@@ -219,49 +218,35 @@ CS_RETCODE
+ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow)
+ {
+ 	TDSSOCKET *tds;
++	int rows_copied;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "blk_done()\n");
+ 	tds = blkdesc->con->tds_socket;
+ 
+ 	switch (type) {
+ 	case CS_BLK_BATCH:
+-
+-		tds_flush_packet(tds);
+-		/* TODO correct ?? */
+-		tds_set_state(tds, TDS_PENDING);
+-		if (tds_process_simple_query(tds) != TDS_SUCCEED) {
++		if (tds_bcp_done(tds, &rows_copied) != TDS_SUCCEED) {
+ 			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");
+ 			return CS_FAIL;
+ 		}
+ 		
+ 		if (outrow) 
+-			*outrow = tds->rows_affected;
++			*outrow = rows_copied;
+ 		
+-		tds_submit_query(tds, blkdesc->bcpinfo.insert_stmt);
+-		if (tds_process_simple_query(tds) != TDS_SUCCEED) {
++		if (tds_bcp_start(tds, &blkdesc->bcpinfo) != TDS_SUCCEED) {
+ 			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");
+ 			return CS_FAIL;
+ 		}
+-
+-		tds->out_flag = TDS_BULK;
+-
+-		if (IS_TDS7_PLUS(tds))
+-			tds_bcp_send_colmetadata(tds, &blkdesc->bcpinfo);
+-
+ 		break;
+ 		
+ 	case CS_BLK_ALL:
+-
+-		tds_flush_packet(tds);
+-		/* TODO correct ?? */
+-		tds_set_state(tds, TDS_PENDING);
+-		if (tds_process_simple_query(tds) != TDS_SUCCEED) {
++		if (tds_bcp_done(tds, &rows_copied) != TDS_SUCCEED) {
+ 			_ctclient_msg(blkdesc->con, "blk_done", 2, 5, 1, 140, "");
+ 			return CS_FAIL;
+ 		}
+ 		
+ 		if (outrow) 
+-			*outrow = tds->rows_affected;
++			*outrow = rows_copied;
+ 		
+ 		/* free allocated storage in blkdesc & initialise flags, etc. */
+ 	
+@@ -697,15 +682,10 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 		 * retrieve details of the database table columns
+ 		 */
+ 
+-		if (_rowxfer_in_init(blkdesc) == CS_FAIL)
+-			return (CS_FAIL);
+-
+-
+-		/* set packet type to send bulk data */
+-		tds->out_flag = TDS_BULK;
+-
+-		if (IS_TDS7_PLUS(tds))
+-			tds_bcp_send_colmetadata(tds, &blkdesc->bcpinfo);
++		if (tds_bcp_start_copy_in(tds, &blkdesc->bcpinfo) == TDS_FAIL) {
++			_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 5, 1, 140, "");
++			return CS_FAIL;
++		}
+ 
+ 		blkdesc->bcpinfo.xfer_init = 1;
+ 	} 
+@@ -721,100 +701,6 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 	return CS_SUCCEED;
+ }
+ 
+-static CS_RETCODE
+-_rowxfer_in_init(CS_BLKDESC * blkdesc)
+-{
+-
+-	TDSSOCKET *tds = blkdesc->con->tds_socket;
+-	TDSCOLUMN *bcpcol;
+-
+-	int i;
+-
+-	int fixed_col_len_tot     = 0;
+-	int variable_col_len_tot  = 0;
+-	int column_bcp_data_size  = 0;
+-	int bcp_record_size       = 0;
+-	
+-	TDSBCPINFO *bcpinfo = &blkdesc->bcpinfo;
+-
+-	if (tds_bcp_start_insert_stmt(tds, bcpinfo) == TDS_FAIL)
+-		return CS_FAIL;
+-
+-	/*
+-	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
+-	 * We're going to ignore it.  
+-	 */
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED) {
+-		_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 5, 1, 140, "");
+-		return CS_FAIL;
+-	}
+-
+-	/* FIXME find a better way, some other thread could change state here */
+-	tds_set_state(tds, TDS_QUERYING);
+-
+-	/* 
+-	 * Work out the number of "variable" columns.  These are either nullable or of 
+-	 * varying length type e.g. varchar.   
+-	 */
+-	bcpinfo->var_cols = 0;
+-
+-	if (IS_TDS50(tds)) {
+-		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+-	
+-			bcpcol = bcpinfo->bindinfo->columns[i];
+-
+-			/*
+-			 * work out storage required for this datatype
+-			 * blobs always require 16, numerics vary, the
+-			 * rest can be taken from the server
+-			 */
+-
+-			if (is_blob_type(bcpcol->on_server.column_type))
+-				column_bcp_data_size  = 16;
+-			else if (is_numeric_type(bcpcol->on_server.column_type))
+-				column_bcp_data_size  = tds_numeric_bytes_per_prec[bcpcol->column_prec];
+-			else
+-				column_bcp_data_size  = bcpcol->column_size;
+-
+-			/*
+-			 * now add that size into either fixed or variable
+-			 * column totals...
+-			 */
+-
+-			if (is_nullable_type(bcpcol->on_server.column_type) || bcpcol->column_nullable) {
+-				bcpinfo->var_cols++;
+-				variable_col_len_tot += column_bcp_data_size;
+-			}
+-			else {
+-				fixed_col_len_tot += column_bcp_data_size;
+-			}
+-		}
+-
+-		/* this formula taken from sybase manual... */
+-
+-		bcp_record_size =  	4 +
+-							fixed_col_len_tot +
+-							variable_col_len_tot +
+-							( (int)(variable_col_len_tot / 256 ) + 1 ) +
+-							(bcpinfo->var_cols + 1) +
+-							2;
+-
+-		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
+-		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
+-
+-		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
+-			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
+-			if (bcpinfo->bindinfo->current_row == NULL) {
+-				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
+-				return CS_FAIL;
+-			}
+-			bcpinfo->bindinfo->row_size = bcp_record_size;
+-		}
+-	}
+-
+-	return CS_SUCCEED;
+-}
+-
+ static void
+ _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset)
+ {
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 85b5e31..a099b04 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.176 2008/12/15 13:21:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.177 2008/12/15 15:52:10 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -82,8 +82,6 @@ static void _bcp_free_columns(DBPROCESS * dbproc);
+ static void _bcp_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset);
+ static int _bcp_no_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset);
+-static RETCODE _bcp_start_copy_in(DBPROCESS *);
+-static RETCODE _bcp_start_new_batch(DBPROCESS *);
+ 
+ static int rtrim(char *, int);
+ static offset_type _bcp_measure_terminated_field(FILE * hostfile, BYTE * terminator, int term_len);
+@@ -1621,18 +1619,11 @@ bcp_sendrow(DBPROCESS * dbproc)
+ 	if (dbproc->bcpinfo->xfer_init == 0) {
+ 
+ 		/* The start_copy function retrieves details of the table's columns */
+-		if (_bcp_start_copy_in(dbproc) == FAIL) {
++		if (tds_bcp_start_copy_in(tds, dbproc->bcpinfo) == TDS_FAIL) {
+ 			dbperror(dbproc, SYBEBULKINSERT, 0);
+-			return (FAIL);
++			return FAIL;
+ 		}
+ 
+-		/* set packet type to send bulk data */
+-		tds->out_flag = TDS_BULK;
+-		tds_set_state(tds, TDS_QUERYING);
+-
+-		if (IS_TDS7_PLUS(tds))
+-			tds_bcp_send_colmetadata(tds, dbproc->bcpinfo);
+-
+ 		dbproc->bcpinfo->xfer_init = 1;
+ 
+ 	}
+@@ -1677,17 +1668,11 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 		return FAIL;
+ 	}
+ 
+-	if (_bcp_start_copy_in(dbproc) == FAIL) {
++	if (tds_bcp_start_copy_in(tds, dbproc->bcpinfo) == TDS_FAIL) {
+ 		fclose(hostfile);
+ 		return FAIL;
+ 	}
+ 
+-	tds->out_flag = TDS_BULK;
+-	tds_set_state(tds, TDS_QUERYING);
+-
+-	if (IS_TDS7_PLUS(tds))
+-		tds_bcp_send_colmetadata(tds, dbproc->bcpinfo);
+-
+ 	row_of_hostfile = 0;
+ 	rows_written_so_far = 0;
+ 
+@@ -1778,25 +1763,19 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 					rows_written_so_far++;
+ 	
+ 					if (dbproc->hostfileinfo->batch > 0 && rows_written_so_far == dbproc->hostfileinfo->batch) {
+-						rows_written_so_far = 0;
+-	
+-						tds_flush_packet(tds);
+-	
+-						tds_set_state(tds, TDS_PENDING);
+-	
+-						if (tds_process_simple_query(tds) != TDS_SUCCEED) {
++						if (tds_bcp_done(tds, &rows_written_so_far) != TDS_SUCCEED) {
+ 							if (errfile)
+ 								fclose(errfile);
+ 							fclose(hostfile);
+ 							return FAIL;
+ 						}
+ 							
+-						*rows_copied += tds->rows_affected;
++						*rows_copied += rows_written_so_far;
++						rows_written_so_far = 0;
+ 	
+ 						dbperror(dbproc, SYBEBBCI, 0); /* batch copied to server */
+ 	
+-						_bcp_start_new_batch(dbproc);
+-	
++						tds_bcp_start(tds, dbproc->bcpinfo);
+ 					}
+ 				}
+ 			} else {
+@@ -1822,15 +1801,8 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 		ret = FAIL;
+ 	}
+ 
+-	tds_flush_packet(tds);
+-
+-	tds_set_state(tds, TDS_PENDING);
+-
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED) {
+-		return FAIL;
+-	}
+-	
+-	*rows_copied += tds->rows_affected;
++	tds_bcp_done(tds, &rows_written_so_far);
++	*rows_copied += rows_written_so_far;
+ 
+ 	return ret == NO_MORE_ROWS? SUCCEED : FAIL;	/* (ret is returned from _bcp_read_hostfile) */
+ }
+@@ -1884,189 +1856,6 @@ bcp_row_free(TDSRESULTINFO* result, unsigned char *row)
+  * \ingroup dblib_bcp_internal
+  * \brief 
+  *
+- * \param dbproc contains all information needed by db-lib to manage communications with the server.
+- * 
+- * \return SUCCEED or FAIL.
+- * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+- */
+-static RETCODE
+-_bcp_start_copy_in(DBPROCESS * dbproc)
+-{
+-	TDSSOCKET *tds = dbproc->tds_socket;
+-	TDSCOLUMN *bcpcol;
+-	int i;
+-	int fixed_col_len_tot     = 0;
+-	int variable_col_len_tot  = 0;
+-	int column_bcp_data_size  = 0;
+-	int bcp_record_size       = 0;
+-	TDSBCPINFO *bcpinfo;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_start_copy_in(%p)\n", dbproc);
+-	assert(dbproc);
+-	bcpinfo = dbproc->bcpinfo;
+-
+-	if (tds_bcp_start_insert_stmt(tds, bcpinfo) == TDS_FAIL)
+-		return FAIL;
+-
+-	/*
+-	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
+-	 * We're going to ignore it.  
+-	 */
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED)
+-		return FAIL;
+-
+-	/* 
+-	 * Work out the number of "variable" columns.  These are either nullable or of 
+-	 * varying length type e.g. varchar.   
+-	 */
+-	bcpinfo->var_cols = 0;
+-
+-	if (IS_TDS50(tds)) {
+-		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+-	
+-			bcpcol = bcpinfo->bindinfo->columns[i];
+-
+-			/*
+-			 * work out storage required for this datatype
+-			 * blobs always require 16, numerics vary, the
+-			 * rest can be taken from the server
+-			 */
+-
+-			if (is_blob_type(bcpcol->on_server.column_type))
+-				column_bcp_data_size  = 16;
+-			else if (is_numeric_type(bcpcol->on_server.column_type))
+-				column_bcp_data_size  = tds_numeric_bytes_per_prec[bcpcol->column_prec];
+-			else
+-				column_bcp_data_size  = bcpcol->column_size;
+-
+-			/*
+-			 * now add that size into either fixed or variable
+-			 * column totals...
+-			 */
+-
+-			if (is_nullable_type(bcpcol->on_server.column_type) || bcpcol->column_nullable) {
+-				bcpinfo->var_cols++;
+-				variable_col_len_tot += column_bcp_data_size;
+-			}
+-			else {
+-				fixed_col_len_tot += column_bcp_data_size;
+-			}
+-		}
+-
+-		/* this formula taken from sybase manual... */
+-
+-		bcp_record_size =  	4 +
+-							fixed_col_len_tot +
+-							variable_col_len_tot +
+-							( (int)(variable_col_len_tot / 256 ) + 1 ) +
+-							(bcpinfo->var_cols + 1) +
+-							2;
+-
+-		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
+-		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
+-
+-		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
+-			/* FIXME remove memory leak */
+-			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
+-			bcpinfo->bindinfo->row_free = bcp_row_free;
+-			if (bcpinfo->bindinfo->current_row == NULL) {
+-				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
+-				return FAIL;
+-			}
+-			bcpinfo->bindinfo->row_size = bcp_record_size;
+-		}
+-	}
+-	if (IS_TDS7_PLUS(tds)) {
+-		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+-	
+-			bcpcol = bcpinfo->bindinfo->columns[i];
+-
+-			/*
+-			 * dont send the (meta)data for timestamp columns, or
+-			 * identity columns (unless indentity_insert is enabled
+-			 */
+-
+-			if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || 
+-				bcpcol->column_timestamp) {
+-				continue;
+-			}
+-
+-			switch (bcpcol->column_varint_size) {
+-				case 4:
+-					if (is_blob_type(bcpcol->column_type)) {
+-						bcp_record_size += 25;
+-					}
+-					bcp_record_size += 4;
+-					break;
+-				case 2:
+-					bcp_record_size +=2;
+-					break;
+-				case 1:
+-					bcp_record_size++;
+-					break;
+-				case 0:
+-					break;
+-			}
+-
+-			if (is_numeric_type(bcpcol->column_type)) {
+-				bcp_record_size += tds_numeric_bytes_per_prec[bcpcol->column_prec];
+-			} else {
+-				bcp_record_size += bcpcol->column_size;
+-			}
+-		}
+-		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
+-		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
+-
+-		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
+-			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
+-			bcpinfo->bindinfo->row_free = bcp_row_free;
+-			if (bcpinfo->bindinfo->current_row == NULL) {
+-				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
+-				return FAIL;
+-			}
+-			bcpinfo->bindinfo->row_size = bcp_record_size;
+-		}
+-	}
+-
+-	return SUCCEED;
+-}
+-
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+- * \param dbproc contains all information needed by db-lib to manage communications with the server.
+- * 
+- * \return SUCCEED or FAIL.
+- * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+- */
+-static RETCODE
+-_bcp_start_new_batch(DBPROCESS * dbproc)
+-{
+-	TDSSOCKET *tds = dbproc->tds_socket;
+-
+-	tdsdump_log(TDS_DBG_FUNC, "_bcp_start_new_batch(%p)\n", dbproc);
+-	assert(dbproc);
+-
+-	tds_submit_query(tds, dbproc->bcpinfo->insert_stmt);
+-
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED)
+-		return FAIL;
+-
+-	/* TODO problem with thread safety */
+-	tds->out_flag = TDS_BULK;
+-	tds_set_state(tds, TDS_QUERYING);
+-
+-	if (IS_TDS7_PLUS(tds))
+-		tds_bcp_send_colmetadata(tds, dbproc->bcpinfo);
+-	
+-	return SUCCEED;
+-}
+-
+-/** 
+- * \ingroup dblib_bcp_internal
+- * \brief 
+- *
+  * \param buffer 
+  * \param size 
+  * \param f 
+@@ -2442,7 +2231,6 @@ bcp_moretext(DBPROCESS * dbproc, DBINT size, BYTE * text)
+ DBINT
+ bcp_batch(DBPROCESS * dbproc)
+ {
+-	TDSSOCKET *tds;
+ 	int rows_copied = 0;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "bcp_batch(%p)\n", dbproc);
+@@ -2450,19 +2238,12 @@ bcp_batch(DBPROCESS * dbproc)
+ 	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+ 	CHECK_PARAMETER(dbproc->bcpinfo, SYBEBCPI, FAIL);
+ 
+-	tds = dbproc->tds_socket;
+-	tds_flush_packet(tds);
+-
+-	tds_set_state(tds, TDS_PENDING);
+-
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED)
++	if (tds_bcp_done(dbproc->tds_socket, &rows_copied) != TDS_SUCCEED)
+ 		return FAIL;
+ 
+-	rows_copied = tds->rows_affected;
+-
+-	_bcp_start_new_batch(dbproc);
++	tds_bcp_start(dbproc->tds_socket, dbproc->bcpinfo);
+ 
+-	return (rows_copied);
++	return rows_copied;
+ }
+ 
+ /** 
+@@ -2478,29 +2259,19 @@ bcp_batch(DBPROCESS * dbproc)
+ DBINT
+ bcp_done(DBPROCESS * dbproc)
+ {
+-	TDSSOCKET *tds;
+-	int rows_copied = -1;
++	int rows_copied;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "bcp_done(%p)\n", dbproc);
+ 	CHECK_DBPROC();
+ 	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+ 	CHECK_PARAMETER(dbproc->bcpinfo, SYBEBCPI, FAIL);
+ 
+-	/* TODO check proper tds state */
+-
+-	tds = dbproc->tds_socket;
+-	tds_flush_packet(tds);
+-
+-	tds_set_state(tds, TDS_PENDING);
+-
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED)
+-		return FAIL;
+-		
+-	rows_copied = tds->rows_affected;
++	if (tds_bcp_done(dbproc->tds_socket, &rows_copied) != TDS_SUCCEED)
++		return -1;
+ 
+ 	_bcp_free_storage(dbproc);
+ 
+-	return (rows_copied);
++	return rows_copied;
+ }
+ 
+ /** 
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 89f0b9a..397d7af 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.3 2008/12/15 13:21:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.4 2008/12/15 15:52:10 freddy77 Exp $");
+ 
+ typedef struct tds_pbcb
+ {
+@@ -51,6 +51,8 @@ typedef struct tds_pbcb
+ 	unsigned int from_malloc;
+ } TDSPBCB;
+ 
++static int tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++static int tds_bcp_start_insert_stmt(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ static int tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, unsigned char * rowbuffer, int start);
+ static int tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, TDS_UCHAR *rowbuffer, int start, int *pncols);
+ 
+@@ -223,7 +225,7 @@ tds_build_bulk_insert_stmt(TDSSOCKET * tds, TDSPBCB * clause, TDSCOLUMN * bcpcol
+ 	return TDS_SUCCEED;
+ }
+ 
+-int
++static int
+ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo)
+ {
+ 	char *query;
+@@ -699,7 +701,7 @@ tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_d
+ /** 
+  * \return TDS_SUCCEED or TDS_FAIL.
+  */
+-int
++static int
+ tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ {
+ 	const static unsigned char colmetadata_token = 0x81;
+@@ -783,3 +785,197 @@ tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 
+ 	return TDS_SUCCEED;
+ }
++
++int
++tds_bcp_done(TDSSOCKET *tds, int *rows_copied)
++{
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_done(%p, %p)\n", tds, rows_copied);
++
++	/* TODO check proper tds state */
++	tds_flush_packet(tds);
++
++	tds_set_state(tds, TDS_PENDING);
++
++	if (tds_process_simple_query(tds) != TDS_SUCCEED)
++		return TDS_FAIL;
++
++	if (rows_copied)
++		*rows_copied = tds->rows_affected;
++
++	return TDS_SUCCEED;
++}
++
++int
++tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
++{
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_start(%p, %p)\n", tds, bcpinfo);
++
++	tds_submit_query(tds, bcpinfo->insert_stmt);
++
++	if (tds_process_simple_query(tds) != TDS_SUCCEED)
++		return TDS_FAIL;
++
++	/* TODO problem with thread safety */
++	tds->out_flag = TDS_BULK;
++	tds_set_state(tds, TDS_QUERYING);
++
++	if (IS_TDS7_PLUS(tds))
++		tds_bcp_send_colmetadata(tds, bcpinfo);
++	
++	return TDS_SUCCEED;
++}
++
++static void 
++tds_bcp_row_free(TDSRESULTINFO* result, unsigned char *row)
++{
++	result->row_size = 0;
++	TDS_ZERO_FREE(result->current_row);
++}
++
++int
++tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
++{
++	TDSCOLUMN *bcpcol;
++	int i;
++	int fixed_col_len_tot     = 0;
++	int variable_col_len_tot  = 0;
++	int column_bcp_data_size  = 0;
++	int bcp_record_size       = 0;
++	
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_start_copy_in(%p, %p)\n", tds, bcpinfo);
++
++	if (tds_bcp_start_insert_stmt(tds, bcpinfo) == TDS_FAIL)
++		return TDS_FAIL;
++
++	/*
++	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
++	 * We're going to ignore it.  
++	 */
++	if (tds_process_simple_query(tds) != TDS_SUCCEED) {
++		/* TODO, in CTLib was _ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 5, 1, 140, ""); */
++		return TDS_FAIL;
++	}
++
++	/* 
++	 * Work out the number of "variable" columns.  These are either nullable or of 
++	 * varying length type e.g. varchar.   
++	 */
++	bcpinfo->var_cols = 0;
++
++	if (IS_TDS50(tds)) {
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++	
++			bcpcol = bcpinfo->bindinfo->columns[i];
++
++			/*
++			 * work out storage required for this datatype
++			 * blobs always require 16, numerics vary, the
++			 * rest can be taken from the server
++			 */
++
++			if (is_blob_type(bcpcol->on_server.column_type))
++				column_bcp_data_size  = 16;
++			else if (is_numeric_type(bcpcol->on_server.column_type))
++				column_bcp_data_size  = tds_numeric_bytes_per_prec[bcpcol->column_prec];
++			else
++				column_bcp_data_size  = bcpcol->column_size;
++
++			/*
++			 * now add that size into either fixed or variable
++			 * column totals...
++			 */
++
++			if (is_nullable_type(bcpcol->on_server.column_type) || bcpcol->column_nullable) {
++				bcpinfo->var_cols++;
++				variable_col_len_tot += column_bcp_data_size;
++			}
++			else {
++				fixed_col_len_tot += column_bcp_data_size;
++			}
++		}
++
++		/* this formula taken from sybase manual... */
++
++		bcp_record_size =  	4 +
++							fixed_col_len_tot +
++							variable_col_len_tot +
++							( (int)(variable_col_len_tot / 256 ) + 1 ) +
++							(bcpinfo->var_cols + 1) +
++							2;
++
++		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
++		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
++
++		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
++			/* FIXME remove memory leak */
++			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
++			bcpinfo->bindinfo->row_free = tds_bcp_row_free;
++			if (bcpinfo->bindinfo->current_row == NULL) {
++				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
++				return TDS_FAIL;
++			}
++			bcpinfo->bindinfo->row_size = bcp_record_size;
++		}
++	}
++	if (IS_TDS7_PLUS(tds)) {
++		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
++	
++			bcpcol = bcpinfo->bindinfo->columns[i];
++
++			/*
++			 * dont send the (meta)data for timestamp columns, or
++			 * identity columns (unless indentity_insert is enabled
++			 */
++
++			if ((!bcpinfo->identity_insert_on && bcpcol->column_identity) || 
++				bcpcol->column_timestamp) {
++				continue;
++			}
++
++			switch (bcpcol->column_varint_size) {
++				case 4:
++					if (is_blob_type(bcpcol->column_type)) {
++						bcp_record_size += 25;
++					}
++					bcp_record_size += 4;
++					break;
++				case 2:
++					bcp_record_size +=2;
++					break;
++				case 1:
++					bcp_record_size++;
++					break;
++				case 0:
++					break;
++			}
++
++			if (is_numeric_type(bcpcol->column_type)) {
++				bcp_record_size += tds_numeric_bytes_per_prec[bcpcol->column_prec];
++			} else {
++				bcp_record_size += bcpcol->column_size;
++			}
++		}
++		tdsdump_log(TDS_DBG_FUNC, "current_record_size = %d\n", bcpinfo->bindinfo->row_size);
++		tdsdump_log(TDS_DBG_FUNC, "bcp_record_size     = %d\n", bcp_record_size);
++
++		if (bcp_record_size > bcpinfo->bindinfo->row_size) {
++			bcpinfo->bindinfo->current_row = realloc(bcpinfo->bindinfo->current_row, bcp_record_size);
++			bcpinfo->bindinfo->row_free = tds_bcp_row_free;
++			if (bcpinfo->bindinfo->current_row == NULL) {
++				tdsdump_log(TDS_DBG_FUNC, "could not realloc current_row\n");
++				return TDS_FAIL;
++			}
++			bcpinfo->bindinfo->row_size = bcp_record_size;
++		}
++	}
++
++	/* set packet type to send bulk data */
++	tds->out_flag = TDS_BULK;
++	/* FIXME find a better way, some other thread could change state here */
++	tds_set_state(tds, TDS_QUERYING);
++
++	if (IS_TDS7_PLUS(tds))
++		tds_bcp_send_colmetadata(tds, bcpinfo);
++
++	return TDS_SUCCEED;
++}
+
+commit 29ace07d5d94f69440da4ad79edbde440276956a
+Author: jklowden <jklowden>
+Date:   Tue Dec 16 03:39:00 2008 +0000
+
+    update and obscure Brian's address
+
+diff --git a/doc/htdoc/support.html b/doc/htdoc/support.html
+index 0f67f31..1cd80c4 100644
+--- a/doc/htdoc/support.html
++++ b/doc/htdoc/support.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: support.html,v 1.3 2007/08/09 07:52:08 freddy77 Exp $ -->
++<!-- $Id: support.html,v 1.4 2008/12/16 03:39:00 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -31,7 +31,7 @@ Support&nbsp;&nbsp;|&nbsp;
+ <table summary="layout" width="80%" align="center">
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>
+-The first place you should look to resolve your problem is the <a href="docs.html">documentation</a>
++The first place to look to resolve your problem is the <a href="docs.html">documentation</a>
+ </td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>
+@@ -39,12 +39,12 @@ The next step is to subscribe and post a question to the <a href="http://lists.i
+ </td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>
+-<i>Note:</i> I often see people post what are really FreeTDS questions in a variety of forums such as the PHP list, LUG lists, and Usenet groups.  Many times these queries go unanswered because no one in those forums knows FreeTDS. Your best bet for getting answers will generally be the FreeTDS mailing list. (I know this seems obvious, but you'd be surprised).
++<i>Note:</i> we often see people post what are really FreeTDS questions in a variety of forums such as the PHP list, LUG lists, and Usenet groups.  Many times these queries go unanswered because no one in those forums knows FreeTDS. Your best bet for getting answers will generally be the FreeTDS mailing list. (If this seems obvious, you'd be surprised.)
+ </td></tr>
+ <tr><td>&nbsp;</td></tr>
+ <tr><td>
+-<font color="red">Blatant commercial plug!</font>
+-If you are interested in having someone install and configure FreeTDS for you, you can contact <a href="mailto:camber@ais.org">Brian Bruns (camber@ais.org)</a>, the original author of FreeTDS, who offers consulting, custom programming, and support contracts for FreeTDS.
++<h4 style="color:red">Blatant commercial plug!</h4>
++<P>If you are interested in having someone install and configure FreeTDS for you, you can contact <a href="mailto:brian@&zwnj;bruns.com">Brian Bruns (brian@&zwnj;bruns.com)</a>, the original author of FreeTDS, who offers consulting, custom programming, and support contracts for FreeTDS.
+ </td></tr>
+ <tr><td>&nbsp;</td></tr>
+ </table>
+
+commit 388f5f968e0eb14fbfc43ae46f4c84ce2afa1137
+Author: jklowden <jklowden>
+Date:   Tue Dec 16 03:42:32 2008 +0000
+
+    move Id tag to Support title
+
+diff --git a/doc/htdoc/support.html b/doc/htdoc/support.html
+index 1cd80c4..d131739 100644
+--- a/doc/htdoc/support.html
++++ b/doc/htdoc/support.html
+@@ -1,7 +1,6 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: support.html,v 1.4 2008/12/16 03:39:00 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -25,7 +24,8 @@ Support&nbsp;&nbsp;|&nbsp;
+ 
+ 
+ <!-- page specific content -->
+-<p align="center">
++<p align="center" 
++	title="$Id: support.html,v 1.5 2008/12/16 03:42:32 jklowden Exp $">
+ <font size="+3"><b>S</b></font>upport
+ </p>
+ <table summary="layout" width="80%" align="center">
+
+commit f36ae538a36d289a937c134187abd3e0d35d5696
+Author: freddy77 <freddy77>
+Date:   Tue Dec 16 09:21:08 2008 +0000
+
+    remove formatting errors
+
+diff --git a/ChangeLog b/ChangeLog
+index f5f4b5b..61a9f90 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Dec 16 10:19:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/util.c src/apps/tsql.c:
++	- remove formatting problems
++
+ Mon Dec 15 16:48:44 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
+ 	- add and reuse tds_bcp_done, tds_bcp_start and tds_bcp_start_copy_in
+@@ -1073,4 +1077,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2682 2008/12/15 15:52:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2683 2008/12/16 09:21:08 freddy77 Exp $
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 632955b..59fa741 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.124 2008/12/15 05:31:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.125 2008/12/16 09:21:09 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -530,7 +530,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		 *	in that order. 
+ 		 */
+ 		if (!QUIET) {
+-			printf("Missing argument -p, looking for default instance ... ", port);
++			printf("Missing argument -p, looking for default instance ... ");
+ 		}
+ 		if (0 == (port = get_default_instance_port(hostname))) {
+ 			printf("no reply from server\n");
+diff --git a/src/tds/util.c b/src/tds/util.c
+index a4a2fc8..679c404 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.84 2008/12/15 05:31:15 jklowden Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.85 2008/12/16 09:21:08 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -366,7 +366,7 @@ tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum)
+ 		TDS_ZERO_FREE(msg.sql_state);
+ 	} else {
+ 		const static char msg[] = "tdserror: client library not called because either "
+-					  "tds_ctx (%x) or tds_ctx->err_handler is NULL\n";
++					  "tds_ctx (%p) or tds_ctx->err_handler is NULL\n";
+ 	 	tdsdump_log(TDS_DBG_FUNC, msg, tds_ctx);
+ 	}
+ 
+
+commit 634384276d68f7e906c61fc0ed30eaef17c6e1f8
+Author: freddy77 <freddy77>
+Date:   Tue Dec 16 09:26:02 2008 +0000
+
+    add and reuse tds_bcp_init
+
+diff --git a/ChangeLog b/ChangeLog
+index 61a9f90..8565a4a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Dec 16 10:25:33 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
++	- add and reuse tds_bcp_init
++	- small bulk.c improves
++
+ Tue Dec 16 10:19:26 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/util.c src/apps/tsql.c:
+ 	- remove formatting problems
+@@ -1077,4 +1082,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2683 2008/12/16 09:21:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2684 2008/12/16 09:26:02 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 025d154..8f49901 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.307 2008/12/15 15:52:10 freddy77 Exp $ */
++/* $Id: tds.h,v 1.308 2008/12/16 09:26:02 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1612,6 +1612,7 @@ typedef struct tds_bcpinfo
+ 	TDSRESULTINFO *bindinfo;
+ } TDSBCPINFO;
+ 
++int tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ typedef int  (*tds_bcp_get_col_data) (TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+ typedef void (*tds_bcp_null_error)   (TDSBCPINFO *bulk, int index, int offset);
+ int tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset);
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 6849b68..f37732a 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,7 +38,7 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.47 2008/12/15 15:52:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.48 2008/12/16 09:26:02 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+@@ -306,14 +306,6 @@ blk_gettext(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp, CS_INT
+ CS_RETCODE
+ blk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tnamelen)
+ {
+-	TDSCOLUMN *curcol;
+-
+-	TDSSOCKET *tds;
+-	TDSRESULTINFO *resinfo;
+-	TDSRESULTINFO *bindinfo;
+-	TDS_INT result_type;
+-	int i, rc;
+-
+ 	tdsdump_log(TDS_DBG_FUNC, "blk_init()\n");
+ 
+ 	if (!blkdesc) {
+@@ -361,96 +353,12 @@ blk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tna
+ 	blkdesc->bcpinfo.xfer_init = 0;
+ 	blkdesc->bcpinfo.var_cols = 0;
+ 
+-	tds = blkdesc->con->tds_socket;
+-
+-	/* TODO quote tablename if needed */
+-	if (tds_submit_queryf(tds, "select * from %s where 0 = 1", blkdesc->bcpinfo.tablename) == TDS_FAIL) {
++	if (tds_bcp_init(blkdesc->con->tds_socket, &blkdesc->bcpinfo) == TDS_FAIL) {
+ 		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+ 		return CS_FAIL;
+ 	}
+-
+-	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
+-		   == TDS_SUCCEED) {
+-	}
+-	if (rc != TDS_NO_MORE_RESULTS) {
+-		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+-		return CS_FAIL;
+-	}
+-
+-	/* copy the results info from the TDS socket into CS_BLKDESC structure */
+-
+-	if (!tds->res_info) {
+-		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+-		return CS_FAIL;
+-	}
+-
+-	resinfo = tds->res_info;
+-
+-	if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL) {
+-		_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+-		return CS_FAIL;
+-	}
+-
+-
+-	bindinfo->row_size = resinfo->row_size;
+-
+-	for (i = 0; i < bindinfo->num_cols; i++) {
+-
+-		curcol = bindinfo->columns[i];
+-
+-		curcol->column_type = resinfo->columns[i]->column_type;
+-		curcol->column_usertype = resinfo->columns[i]->column_usertype;
+-		curcol->column_flags = resinfo->columns[i]->column_flags;
+-		curcol->column_size = resinfo->columns[i]->column_size;
+-		curcol->column_varint_size = resinfo->columns[i]->column_varint_size;
+-		curcol->column_prec = resinfo->columns[i]->column_prec;
+-		curcol->column_scale = resinfo->columns[i]->column_scale;
+-		curcol->column_namelen = resinfo->columns[i]->column_namelen;
+-		curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type;
+-		curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size;
+-		curcol->char_conv = resinfo->columns[i]->char_conv;
+-		memcpy(curcol->column_name, resinfo->columns[i]->column_name, resinfo->columns[i]->column_namelen);
+-		if (curcol->table_column_name)
+-			TDS_ZERO_FREE(curcol->table_column_name);
+-		if (resinfo->columns[i]->table_column_name)
+-			curcol->table_column_name = strdup(resinfo->columns[i]->table_column_name);
+-		curcol->column_nullable = resinfo->columns[i]->column_nullable;
+-		curcol->column_identity = resinfo->columns[i]->column_identity;
+-		curcol->column_timestamp = resinfo->columns[i]->column_timestamp;
+-
+-		memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5);
+-
+-		if (is_numeric_type(curcol->column_type)) {
+-			curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC));
+-			((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec;
+-			((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale;
+-		} else {
+-			curcol->bcp_column_data = tds_alloc_bcp_column_data(curcol->on_server.column_size);
+-		}
+-	}
+-
+-	/* TODO check */
+-	tds_alloc_row(bindinfo);
+-
+-	blkdesc->bcpinfo.bindinfo = bindinfo;
+ 	blkdesc->bcpinfo.bind_count = CS_UNUSED;
+ 
+-	if (blkdesc->bcpinfo.identity_insert_on) {
+-
+-		if (tds_submit_queryf(tds, "set identity_insert %s on", blkdesc->bcpinfo.tablename) == TDS_FAIL) {
+-			_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+-			return CS_FAIL;
+-		}
+-	
+-		while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
+-			   == TDS_SUCCEED) {
+-		}
+-		if (rc != TDS_NO_MORE_RESULTS) {
+-			_ctclient_msg(blkdesc->con, "blk_init", 2, 5, 1, 140, "");
+-			return CS_FAIL;
+-		}
+-	}
+-
+ 	return CS_SUCCEED;
+ }
+ 
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index a099b04..0a84483 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.177 2008/12/15 15:52:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.178 2008/12/16 09:26:02 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -89,8 +89,6 @@ static RETCODE _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_
+ static int _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci);
+ static RETCODE _bcp_get_term_var(BYTE * pdata, BYTE * term, int term_len);
+ 
+-static void bcp_row_free(TDSRESULTINFO* result, unsigned char *row);
+-
+ /** 
+  * \ingroup dblib_bcp
+  * \brief Prepare for bulk copy operation on a table
+@@ -116,12 +114,6 @@ static void bcp_row_free(TDSRESULTINFO* result, unsigned char *row);
+ RETCODE
+ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char *errfile, int direction)
+ {
+-	TDSRESULTINFO *resinfo;
+-	TDSRESULTINFO *bindinfo;
+-	TDSCOLUMN *curcol;
+-	TDS_INT result_type;
+-	int i, rc;
+-
+ 	tdsdump_log(TDS_DBG_FUNC, "bcp_init(%p, %s, %s, %s, %d)\n", 
+ 			dbproc, tblname? tblname:"NULL", hfile? hfile:"NULL", errfile? errfile:"NULL", direction);
+ 	CHECK_DBPROC();
+@@ -189,83 +181,12 @@ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char
+ 	if (direction == DB_IN) {
+ 		TDSSOCKET *tds = dbproc->tds_socket;
+ 
+-		if (tds_submit_queryf(tds, "SET FMTONLY ON select * from %s SET FMTONLY OFF", 
+-								dbproc->bcpinfo->tablename) == TDS_FAIL) {
++		if (tds_bcp_init(tds, dbproc->bcpinfo) == TDS_FAIL) {
++			/* TODO return proper error */
+ 			/* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */
+ 			dbperror(dbproc, SYBEBCNT, 0);
+ 			return FAIL;
+ 		}
+-	
+-		/* TODO check what happen if table is not present, cleanup on error */
+-		while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
+-		       == TDS_SUCCEED) {
+-		}
+-		if (rc != TDS_NO_MORE_RESULTS) {
+-			return FAIL;
+-		}
+-	
+-		if (!tds->res_info) {
+-			return FAIL;
+-		}
+-	
+-		/* TODO check what happen if table is not present, cleanup on error */
+-		resinfo = tds->res_info;
+-		if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL)
+-			goto memory_error;
+-	
+-		bindinfo->row_size = resinfo->row_size;
+-	
+-		dbproc->bcpinfo->bindinfo = bindinfo;
+-		dbproc->bcpinfo->bind_count = 0;
+-	
+-		/* Copy the column metadata */
+-		for (i = 0; i < bindinfo->num_cols; i++) {
+-	
+-			curcol = bindinfo->columns[i];
+-			
+-			/*
+-			 * TODO use memcpy ??
+-			 * curcol and resinfo->columns[i] are both TDSCOLUMN.  
+-			 * Why not "curcol = resinfo->columns[i];"?  Because the rest of TDSCOLUMN (below column_timestamp)
+-			 * isn't being used.  Perhaps this "upper" part of TDSCOLUMN should be a substructure.
+-			 * Or, see if the "lower" part is unused (and zeroed out) at this point, and just do one assignment.
+-			 */
+-			curcol->column_type = resinfo->columns[i]->column_type;
+-			curcol->column_usertype = resinfo->columns[i]->column_usertype;
+-			curcol->column_flags = resinfo->columns[i]->column_flags;
+-			curcol->column_size = resinfo->columns[i]->column_size;
+-			curcol->column_varint_size = resinfo->columns[i]->column_varint_size;
+-			curcol->column_prec = resinfo->columns[i]->column_prec;
+-			curcol->column_scale = resinfo->columns[i]->column_scale;
+-			curcol->column_namelen = resinfo->columns[i]->column_namelen;
+-			curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type;
+-			curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size;
+-			curcol->char_conv = resinfo->columns[i]->char_conv;
+-			memcpy(curcol->column_name, resinfo->columns[i]->column_name, resinfo->columns[i]->column_namelen);
+-			TDS_ZERO_FREE(curcol->table_column_name);
+-			if (resinfo->columns[i]->table_column_name)
+-				curcol->table_column_name = strdup(resinfo->columns[i]->table_column_name);
+-			curcol->column_nullable = resinfo->columns[i]->column_nullable;
+-			curcol->column_identity = resinfo->columns[i]->column_identity;
+-			curcol->column_timestamp = resinfo->columns[i]->column_timestamp;
+-			
+-			memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5);
+-			
+-			if (is_numeric_type(curcol->column_type)) {
+-				curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC));
+-				((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec;
+-				((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale;
+-			} else {
+-				curcol->bcp_column_data = 
+-					tds_alloc_bcp_column_data(MAX(curcol->column_size,curcol->on_server.column_size));
+-			}
+-		}
+-
+-		bindinfo->current_row = malloc(bindinfo->row_size);
+-		if (!bindinfo->current_row)
+-			goto memory_error;
+-		bindinfo->row_free = bcp_row_free;
+-		return SUCCEED;
+ 	}
+ 
+ 	return SUCCEED;
+@@ -1845,13 +1766,6 @@ bcp_exec(DBPROCESS * dbproc, DBINT *rows_copied)
+ 	return ret;
+ }
+ 
+-static void 
+-bcp_row_free(TDSRESULTINFO* result, unsigned char *row)
+-{
+-	result->row_size = 0;
+-	TDS_ZERO_FREE(result->current_row);
+-}
+-
+ /** 
+  * \ingroup dblib_bcp_internal
+  * \brief 
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 397d7af..467f736 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -37,12 +37,17 @@
+ 
+ #include "tds.h"
+ #include "tds_checks.h"
++#include "tdsbytes.h"
+ #include "replacements.h"
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.4 2008/12/15 15:52:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.5 2008/12/16 09:26:02 freddy77 Exp $");
++
++#ifndef MAX
++#define MAX(a,b) ( (a) > (b) ? (a) : (b) )
++#endif
+ 
+ typedef struct tds_pbcb
+ {
+@@ -51,21 +56,124 @@ typedef struct tds_pbcb
+ 	unsigned int from_malloc;
+ } TDSPBCB;
+ 
+-static int tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
++static int tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ static int tds_bcp_start_insert_stmt(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ static int tds_bcp_add_fixed_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, unsigned char * rowbuffer, int start);
+ static int tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset, TDS_UCHAR *rowbuffer, int start, int *pncols);
++static void tds_bcp_row_free(TDSRESULTINFO* result, unsigned char *row);
++
++int
++tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
++{
++	TDSRESULTINFO *resinfo;
++	TDSRESULTINFO *bindinfo = NULL;
++	TDSCOLUMN *curcol;
++	TDS_INT result_type;
++	int i, rc;
++
++	/* FIXME don't leave state in processing state */
++
++	/* TODO quote tablename if needed */
++	if (tds_submit_queryf(tds, "select * from %s where 0 = 1", bcpinfo->tablename) == TDS_FAIL)
++		/* TODO return an error ?? */
++		/* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */
++		return TDS_FAIL;
++
++	/* TODO check what happen if table is not present, cleanup on error */
++	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
++		   == TDS_SUCCEED) {
++	}
++	if (rc != TDS_NO_MORE_RESULTS)
++		return TDS_FAIL;
++
++	/* copy the results info from the TDS socket */
++	if (!tds->res_info)
++		return TDS_FAIL;
++
++	resinfo = tds->res_info;
++	if ((bindinfo = tds_alloc_results(resinfo->num_cols)) == NULL)
++		goto cleanup;
++
++	bindinfo->row_size = resinfo->row_size;
++
++	/* Copy the column metadata */
++	for (i = 0; i < bindinfo->num_cols; i++) {
++
++		curcol = bindinfo->columns[i];
++		
++		/*
++		 * TODO use memcpy ??
++		 * curcol and resinfo->columns[i] are both TDSCOLUMN.  
++		 * Why not "curcol = resinfo->columns[i];"?  Because the rest of TDSCOLUMN (below column_timestamp)
++		 * isn't being used.  Perhaps this "upper" part of TDSCOLUMN should be a substructure.
++		 * Or, see if the "lower" part is unused (and zeroed out) at this point, and just do one assignment.
++		 */
++		curcol->column_type = resinfo->columns[i]->column_type;
++		curcol->column_usertype = resinfo->columns[i]->column_usertype;
++		curcol->column_flags = resinfo->columns[i]->column_flags;
++		curcol->column_size = resinfo->columns[i]->column_size;
++		curcol->column_varint_size = resinfo->columns[i]->column_varint_size;
++		curcol->column_prec = resinfo->columns[i]->column_prec;
++		curcol->column_scale = resinfo->columns[i]->column_scale;
++		curcol->column_namelen = resinfo->columns[i]->column_namelen;
++		curcol->on_server.column_type = resinfo->columns[i]->on_server.column_type;
++		curcol->on_server.column_size = resinfo->columns[i]->on_server.column_size;
++		curcol->char_conv = resinfo->columns[i]->char_conv;
++		memcpy(curcol->column_name, resinfo->columns[i]->column_name, resinfo->columns[i]->column_namelen);
++		TDS_ZERO_FREE(curcol->table_column_name);
++		if (resinfo->columns[i]->table_column_name)
++			curcol->table_column_name = strdup(resinfo->columns[i]->table_column_name);
++		curcol->column_nullable = resinfo->columns[i]->column_nullable;
++		curcol->column_identity = resinfo->columns[i]->column_identity;
++		curcol->column_timestamp = resinfo->columns[i]->column_timestamp;
++		
++		memcpy(curcol->column_collation, resinfo->columns[i]->column_collation, 5);
++		
++		if (is_numeric_type(curcol->column_type)) {
++			curcol->bcp_column_data = tds_alloc_bcp_column_data(sizeof(TDS_NUMERIC));
++			((TDS_NUMERIC *) curcol->bcp_column_data->data)->precision = curcol->column_prec;
++			((TDS_NUMERIC *) curcol->bcp_column_data->data)->scale = curcol->column_scale;
++		} else {
++			curcol->bcp_column_data = 
++				tds_alloc_bcp_column_data(MAX(curcol->column_size,curcol->on_server.column_size));
++		}
++	}
++
++	bindinfo->current_row = malloc(bindinfo->row_size);
++	if (!bindinfo->current_row)
++		goto cleanup;
++	bindinfo->row_free = tds_bcp_row_free;
++
++	if (bcpinfo->identity_insert_on) {
++
++		if (tds_submit_queryf(tds, "set identity_insert %s on", bcpinfo->tablename) == TDS_FAIL)
++			goto cleanup;
++	
++		while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
++			   == TDS_SUCCEED) {
++		}
++		if (rc != TDS_NO_MORE_RESULTS)
++			goto cleanup;
++	}
++
++	bcpinfo->bindinfo = bindinfo;
++	bcpinfo->bind_count = 0;
++	return TDS_SUCCEED;
+ 
++cleanup:
++	tds_free_results(bindinfo);
++	return TDS_FAIL;
++}
+ /** 
+  * \return TDS_SUCCEED or TDS_FAIL.
+  */
+ static int
+-tds_build_bulk_insert_stmt(TDSSOCKET * tds, TDSPBCB * clause, TDSCOLUMN * bcpcol, int first)
++tds7_build_bulk_insert_stmt(TDSSOCKET * tds, TDSPBCB * clause, TDSCOLUMN * bcpcol, int first)
+ {
+ 	char buffer[32];
+ 	char *column_type = buffer;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_build_bulk_insert_stmt(%p, %p, %p, %d)\n", tds, clause, bcpcol, first);
++	tdsdump_log(TDS_DBG_FUNC, "tds7_build_bulk_insert_stmt(%p, %p, %p, %d)\n", tds, clause, bcpcol, first);
+ 
+ 	/* TODO reuse function in tds/query.c */
+ 	switch (bcpcol->on_server.column_type) {
+@@ -246,17 +354,12 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo)
+ 		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+ 			bcpcol = bcpinfo->bindinfo->columns[i];
+ 
+-			if (bcpinfo->identity_insert_on) {
+-				if (!bcpcol->column_timestamp) {
+-					tds_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
+-					firstcol = 0;
+-				}
+-			} else {
+-				if (!bcpcol->column_identity && !bcpcol->column_timestamp) {
+-					tds_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
+-					firstcol = 0;
+-				}
+-			}
++			if (bcpcol->column_timestamp)
++				continue;
++			if (!bcpinfo->identity_insert_on && bcpcol->column_identity)
++				continue;
++			tds7_build_bulk_insert_stmt(tds, &colclause, bcpcol, firstcol);
++			firstcol = 0;
+ 		}
+ 
+ 		if (bcpinfo->hint) {
+@@ -285,9 +388,7 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo)
+ 			return TDS_FAIL;
+ 	}
+ 
+-	tds_submit_query(tds, query);
+ 	/* save the statement for later... */
+-
+ 	bcpinfo->insert_stmt = query;
+ 
+ 	return TDS_SUCCEED;
+@@ -312,8 +413,6 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 	unsigned char *record;
+ 	TDS_INT	 old_record_size;
+ 	TDS_INT	 new_record_size;
+-	TDS_INT	     varint_4;
+-	TDS_SMALLINT varint_2;
+ 	TDS_TINYINT  varint_1;
+ 
+ 	int row_pos;
+@@ -386,18 +485,12 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 						memcpy(record, timestamp, 8); record += 8;
+ 						new_record_size += 25;
+ 					}
+-					varint_4 = bindcol->bcp_column_data->datalen;
+-#if WORDS_BIGENDIAN
+-					tds_swap_datatype(SYBINT4, (unsigned char *)&varint_4);
+-#endif
+-					memcpy(record, &varint_4, 4); record += 4; new_record_size +=4;
++					TDS_PUT_UA4LE(record, bindcol->bcp_column_data->datalen);
++					record += 4; new_record_size +=4;
+ 					break;
+ 				case 2:
+-					varint_2 = bindcol->bcp_column_data->datalen;
+-#if WORDS_BIGENDIAN
+-					tds_swap_datatype(SYBINT2, (unsigned char *)&varint_2);
+-#endif
+-					memcpy(record, &varint_2, 2); record += 2; new_record_size +=2;
++					TDS_PUT_UA2LE(record, bindcol->bcp_column_data->datalen);
++					record += 2; new_record_size +=2;
+ 					break;
+ 				case 1:
+ 					varint_1 = bindcol->bcp_column_data->datalen;
+@@ -702,19 +795,18 @@ tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_d
+  * \return TDS_SUCCEED or TDS_FAIL.
+  */
+ static int
+-tds_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
++tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ {
+-	const static unsigned char colmetadata_token = 0x81;
+ 	TDSCOLUMN *bcpcol;
+ 	int i, num_cols;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_colmetadata(%p, %p)\n", tds, bcpinfo);
++	tdsdump_log(TDS_DBG_FUNC, "tds7_bcp_send_colmetadata(%p, %p)\n", tds, bcpinfo);
+ 	assert(tds && bcpinfo);
+ 
+ 	/* 
+ 	 * Deep joy! For TDS 8 we have to send a colmetadata message followed by row data 
+ 	 */
+-	tds_put_byte(tds, colmetadata_token);	/* 0x81 */
++	tds_put_byte(tds, TDS7_RESULT_TOKEN);	/* 0x81 */
+ 
+ 	num_cols = 0;
+ 	for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+@@ -812,6 +904,10 @@ tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 
+ 	tds_submit_query(tds, bcpinfo->insert_stmt);
+ 
++	/*
++	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
++	 * We're going to ignore it.  
++	 */
+ 	if (tds_process_simple_query(tds) != TDS_SUCCEED)
+ 		return TDS_FAIL;
+ 
+@@ -820,7 +916,7 @@ tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 	tds_set_state(tds, TDS_QUERYING);
+ 
+ 	if (IS_TDS7_PLUS(tds))
+-		tds_bcp_send_colmetadata(tds, bcpinfo);
++		tds7_bcp_send_colmetadata(tds, bcpinfo);
+ 	
+ 	return TDS_SUCCEED;
+ }
+@@ -847,11 +943,7 @@ tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 	if (tds_bcp_start_insert_stmt(tds, bcpinfo) == TDS_FAIL)
+ 		return TDS_FAIL;
+ 
+-	/*
+-	 * In TDS 5 we get the column information as a result set from the "insert bulk" command.
+-	 * We're going to ignore it.  
+-	 */
+-	if (tds_process_simple_query(tds) != TDS_SUCCEED) {
++	if (tds_bcp_start(tds, bcpinfo) != TDS_SUCCEED) {
+ 		/* TODO, in CTLib was _ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 5, 1, 140, ""); */
+ 		return TDS_FAIL;
+ 	}
+@@ -969,13 +1061,5 @@ tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 		}
+ 	}
+ 
+-	/* set packet type to send bulk data */
+-	tds->out_flag = TDS_BULK;
+-	/* FIXME find a better way, some other thread could change state here */
+-	tds_set_state(tds, TDS_QUERYING);
+-
+-	if (IS_TDS7_PLUS(tds))
+-		tds_bcp_send_colmetadata(tds, bcpinfo);
+-
+ 	return TDS_SUCCEED;
+ }
+
+commit 83c75d582b38cf79c04de4436ae299de0966cc45
+Author: freddy77 <freddy77>
+Date:   Tue Dec 16 15:35:21 2008 +0000
+
+    check function library
+
+diff --git a/misc/check_symbols b/misc/check_symbols
+new file mode 100755
+index 0000000..7ab76aa
+--- /dev/null
++++ b/misc/check_symbols
+@@ -0,0 +1,82 @@
++#!/usr/bin/perl
++
++# $Id: check_symbols,v 1.1 2008/12/16 15:35:21 freddy77 Exp $
++# Check use of functions in client libraries
++
++use strict;
++
++sub getExpSymbols($)
++{
++	my $objs = shift;
++	my %out;
++	open(SYMS, "nm -B $objs |") or die('getting symbols');
++	while(<SYMS>) {
++		next if !/^.*\s+([ABCDGIRSTW])\s+(.+?)\s+.*$/;
++		my ($type, $sym) = ($1, $2);
++#		print "adding $sym type $type\n";
++		$out{$sym} = $type;
++	}
++	close(SYMS);
++	return \%out;
++}
++
++sub getImpSymbols($)
++{
++	my $objs = shift;
++	my %out;
++	open(SYMS, "nm -B $objs |") or die('getting symbols');
++	while(<SYMS>) {
++		next if !/^.*\s+([U])\s+(.+?)\s+.*$/;
++		my ($type, $sym) = ($1, $2);
++		$out{$sym} = $type;
++	}
++	close(SYMS);
++	return \%out;
++}
++
++my %tdsSymbols = %{&getExpSymbols('src/tds/*.o')};
++
++my %syms;
++open(F, '<', './misc/check_symbols.txt') or die('getting list');
++while (<F>) {
++	chomp;
++	s/#.*//;
++	s/\s.*//;
++#	print "marking $_\n";
++	if (/^!(.*)/) {
++#		print "symbol $1 is private\n";
++		$syms{$1} = 0;
++	} else {
++		$syms{$_} = 1;
++	}
++}
++close(F);
++
++# check all tds symbols are known
++foreach my $sym (sort keys %tdsSymbols) {
++	if (!defined($syms{$sym})) {
++		print STDERR "UNKNOWN $sym\n";
++		$tdsSymbols{$sym} = 1;
++	} else {
++		$tdsSymbols{$sym} = $syms{$sym};
++	}
++#	print "$sym state ".$tdsSymbols{$sym}."\n";
++}
++
++
++sub checkLib($$)
++{
++	my ($lib, $objs) = @_;
++	print "Checking $lib library\n";
++	foreach my $sym (sort keys %{&getImpSymbols($objs)}) {
++#		print "proc $sym\n";
++		next if !defined($tdsSymbols{$sym});
++		print "Symbols $sym referenced by $lib but marked as private\n" if (!$tdsSymbols{$sym});
++	}
++	print "\n";
++}
++
++&checkLib('dblib', 'src/dblib/*.o');
++&checkLib('CTLib', 'src/ctlib/*.o');
++&checkLib('ODBC', 'src/odbc/*.o');
++
+diff --git a/misc/check_symbols.txt b/misc/check_symbols.txt
+new file mode 100644
+index 0000000..90419ee
+--- /dev/null
++++ b/misc/check_symbols.txt
+@@ -0,0 +1,220 @@
++MD4Final
++MD4Init
++MD4Transform
++MD4Update
++MD5Final
++MD5Init
++MD5Transform
++MD5Update
++STD_DATETIME_FMT
++hmac_md5
++tds7_crypt_pass
++tds7_get_instance_port
++tds7_get_instance_ports
++tds7_srv_charset_changed
++tds_alloc_bcp_column_data
++tds_alloc_client_sqlstate
++tds_alloc_compute_results
++tds_alloc_compute_row
++tds_alloc_connection
++tds_alloc_context
++tds_alloc_cursor
++tds_alloc_dynamic
++tds_alloc_locale
++tds_alloc_login
++tds_alloc_lookup_sqlstate
++tds_alloc_param_data
++tds_alloc_param_result
++tds_alloc_results
++tds_alloc_row
++tds_alloc_socket
++tds_bcp_done
++tds_bcp_init
++tds_bcp_send_record
++tds_bcp_start
++tds_bcp_start_copy_in
++tds_canonical_charset_name
++tds_check_column_extra
++tds_check_context_extra
++tds_check_cursor_extra
++tds_check_dynamic_extra
++tds_check_env_extra
++tds_check_resultinfo_extra
++tds_check_tds_extra
++tds_close_socket
++tds_config_verstr
++tds_connect
++tds_connect_and_login
++tds_convert
++tds_count_placeholders
++tds_cursor_close
++tds_cursor_dealloc
++tds_cursor_deallocated
++tds_cursor_declare
++tds_cursor_fetch
++tds_cursor_get_cursor_info
++tds_cursor_open
++tds_cursor_setname
++tds_cursor_setrows
++tds_cursor_update
++tds_datecrack
++tds_debug_flags
++tds_default_port
++tds_des_ecb_encrypt
++tds_des_encrypt
++tds_des_set_key
++tds_des_set_odd_parity
++tds_dstr_alloc
++tds_dstr_buf
++tds_dstr_copy
++tds_dstr_copyn
++tds_dstr_dup
++tds_dstr_free
++tds_dstr_init
++tds_dstr_isempty
++tds_dstr_len
++tds_dstr_set
++tds_dstr_setlen
++tds_dstr_zero
++tds_fix_connection
++!tds_flush_packet
++tds_free_all_results
++tds_free_bcp_column_data
++tds_free_connection
++tds_free_context
++tds_free_dynamic
++tds_free_input_params
++tds_free_locale
++tds_free_login
++tds_free_msg
++tds_free_param_result
++tds_free_param_results
++tds_free_results
++tds_free_row
++tds_free_socket
++tds_g_append_mode
++!tds_get_byte
++tds_get_cardinal_type
++tds_get_char_data
++tds_get_compiletime_settings
++tds_get_conversion_type
++tds_get_homedir
++!tds_get_int
++!tds_get_int8
++tds_get_locale
++!tds_get_n
++tds_get_null_type
++tds_get_parent
++tds_get_size_by_type
++!tds_get_smallint
++!tds_get_string
++tds_get_token_size
++tds_get_varint_size
++tds_gethostbyname_r
++tds_getmac
++tds_getservbyname_r
++tds_gettime_ms
++tds_gss_get_auth
++tds_hex_digits
++tds_iconv
++tds_iconv_alloc
++tds_iconv_close
++tds_iconv_fread
++tds_iconv_free
++tds_iconv_from_collate
++tds_iconv_get
++tds_iconv_open
++tds_inet_ntoa_r
++!tds_init_write_buf
++!tds_lastpacket
++tds_lookup_dynamic
++tds_lookup_host
++tds_money_to_string
++tds_multiple_done
++tds_multiple_execute
++tds_multiple_init
++tds_multiple_query
++tds_next_placeholder
++!tds_ntlm_get_auth
++tds_numeric_bytes_per_prec
++tds_numeric_change_prec_scale
++tds_numeric_to_string
++tds_parse_conf_section
++!tds_peek
++tds_process_cancel
++tds_process_login_tokens
++tds_process_simple_query
++tds_process_tokens
++tds_prtype
++!tds_put_buf
++!tds_put_byte
++!tds_put_int
++!tds_put_int8
++!tds_put_n
++!tds_put_smallint
++!tds_put_string
++tds_quote_id
++tds_quote_string
++tds_read_conf_file
++tds_read_conf_section
++tds_read_config_info
++tds_read_packet
++tds_realloc_socket
++tds_release_cursor
++tds_send_cancel
++tds_set_app
++tds_set_bulk
++tds_set_capabilities
++tds_set_client_charset
++tds_set_column_type
++tds_set_host
++tds_set_interfaces_file_loc
++tds_set_language
++tds_set_library
++tds_set_packet
++tds_set_param_type
++tds_set_parent
++tds_set_passwd
++tds_set_port
++tds_set_server
++tds_set_server_addr
++!tds_set_state
++tds_set_user
++tds_set_version
++tds_skip_quoted
++tds_srv_charset_changed
++!tds_ssl_deinit
++!tds_ssl_init
++!tds_str_empty
++tds_strftime
++tds_submit_execdirect
++tds_submit_execute
++tds_submit_optioncmd
++tds_submit_prepare
++tds_submit_query
++tds_submit_query_params
++tds_submit_queryf
++tds_submit_rpc
++tds_submit_unprepare
++tds_swap_bytes
++!tds_swap_datatype
++!tds_swap_numeric
++tds_sybase_charset_name
++tds_timestamp_str
++!tds_unget_byte
++tds_version
++tds_vstrbuild
++tds_willconvert
++!tds_write_packet
++tds_writetext_continue
++tds_writetext_end
++tds_writetext_start
++tdsdump_close
++tdsdump_col
++tdsdump_dump_buf
++tdsdump_isopen
++tdsdump_log
++tdsdump_off
++tdsdump_on
++tdsdump_open
++!tdserror
+
+commit 97eeedc553a51085d3d433b9ff3094f360fb2e92
+Author: freddy77 <freddy77>
+Date:   Tue Dec 16 15:41:18 2008 +0000
+
+    add and reuse tds_writetext_(start|continue|end)
+
+diff --git a/ChangeLog b/ChangeLog
+index 8565a4a..d3a3627 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Dec 16 16:39:35 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/ct.c src/dblib/dblib.c src/tds/bulk.c:
++	- add and reuse tds_writetext_(start|continue|end)
++
+ Tue Dec 16 10:25:33 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/ctlib/blk.c src/dblib/bcp.c src/tds/bulk.c:
+ 	- add and reuse tds_bcp_init
+@@ -1082,4 +1086,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2684 2008/12/16 09:26:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2685 2008/12/16 15:41:18 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 8f49901..bf96853 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.308 2008/12/16 09:26:02 freddy77 Exp $ */
++/* $Id: tds.h,v 1.309 2008/12/16 15:41:18 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1620,6 +1620,10 @@ int tds_bcp_done(TDSSOCKET *tds, int *rows_copied);
+ int tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ int tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
+ 
++int tds_writetext_start(TDSSOCKET *tds, const char *objname, const char *textptr, const char *timestamp, int with_log, TDS_UINT size);
++int tds_writetext_continue(TDSSOCKET *tds, const TDS_UCHAR *text, TDS_UINT size);
++int tds_writetext_end(TDSSOCKET *tds);
++
+ 
+ #define IS_TDS42(x) (x->major_version==4 && x->minor_version==2)
+ #define IS_TDS46(x) (x->major_version==4 && x->minor_version==6)
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 24b3bbc..43a808b 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.182 2008/12/15 05:31:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.183 2008/12/16 15:41:18 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -1079,8 +1079,7 @@ ct_send(CS_COMMAND * cmd)
+ 	}
+ 
+ 	if (cmd->command_type == CS_SEND_DATA_CMD) {
+-		tds_flush_packet(tds);
+-		tds_set_state(tds, TDS_PENDING);
++		tds_writetext_end(tds);
+ 		ct_set_command_state(cmd, _CS_COMMAND_SENT);
+ 	}
+ 
+@@ -2735,7 +2734,6 @@ CS_RETCODE
+ ct_send_data(CS_COMMAND * cmd, CS_VOID * buffer, CS_INT buflen)
+ {
+ 	TDSSOCKET *tds;
+-	char writetext_cmd[512];
+ 
+ 	char textptr_string[35];	/* 16 * 2 + 2 (0x) + 1 */
+ 	char timestamp_string[19];	/* 8 * 2 + 2 (0x) + 1 */
+@@ -2782,32 +2780,16 @@ ct_send_data(CS_COMMAND * cmd, CS_VOID * buffer, CS_INT buflen)
+ 		}
+ 		*c = '\0';
+ 
+-		/* submit the "writetext bulk" command */
+-
+-		sprintf(writetext_cmd, "writetext bulk %s 0x%s timestamp = 0x%s%s",
+-			cmd->iodesc->name,
+-			textptr_string, timestamp_string, ((cmd->iodesc->log_on_update == CS_TRUE) ? " with log" : "")
+-			);
+-
+-		if (tds_submit_query(tds, writetext_cmd) != TDS_SUCCEED) {
+-			return CS_FAIL;
+-		}
+-
+-		/* FIXME in this case processing all results can bring state to IDLE... not threading safe */
+-		/* read the end token */
+-		if (tds_process_simple_query(tds) != TDS_SUCCEED)
+-			return CS_FAIL;
+-
+-		if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
++		/* submit the writetext command */
++		if (tds_writetext_start(tds, cmd->iodesc->name,
++			textptr_string, timestamp_string, (cmd->iodesc->log_on_update == CS_TRUE), cmd->iodesc->total_txtlen) != TDS_SUCCEED)
+ 			return CS_FAIL;
+ 
+ 		cmd->send_data_started = 1;
+-		tds->out_flag = TDS_BULK;
+-		tds_put_int(tds, cmd->iodesc->total_txtlen);
+ 	}
+ 
+-	tds->out_flag = TDS_BULK;
+-	tds_put_n(tds, buffer, buflen);
++	if (tds_writetext_continue(tds, buffer, buflen) != TDS_SUCCEED)
++		return CS_FAIL;
+ 
+ 	return CS_SUCCEED;
+ }
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index a1eb2ca..1ea3983 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.335 2008/12/15 05:31:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.336 2008/12/16 15:41:18 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -6298,31 +6298,19 @@ dbwritetext(DBPROCESS * dbproc, char *objname, DBBINARY * textptr, DBTINYINT tex
+ 			return FAIL;
+ 		}
+ 	}
+-
+-	if (tds_submit_queryf(dbproc->tds_socket,
+-			      "writetext bulk %s 0x%s timestamp = 0x%s %s",
+-			      objname, textptr_string, timestamp_string, ((log == TRUE) ? "with log" : ""))
+-	    != TDS_SUCCEED) {
+-		return FAIL;
+-	}
+-
+-	/* read the end token */
+-	if (tds_process_simple_query(dbproc->tds_socket) != TDS_SUCCEED)
++	
++	if (tds_writetext_start(dbproc->tds_socket, objname, 
++		textptr_string, timestamp_string, (log == TRUE), size) != TDS_SUCCEED)
+ 		return FAIL;
+ 
+-	dbproc->tds_socket->out_flag = TDS_BULK;
+-	tds_set_state(dbproc->tds_socket, TDS_QUERYING);
+-	tds_put_int(dbproc->tds_socket, size);
+-
+ 	if (!text) {
+ 		dbproc->text_size = size;
+ 		dbproc->text_sent = 0;
+ 		return SUCCEED;
+ 	}
+ 
+-	tds_put_n(dbproc->tds_socket, text, size);
+-	tds_flush_packet(dbproc->tds_socket);
+-	tds_set_state(dbproc->tds_socket, TDS_PENDING);
++	tds_writetext_continue(dbproc->tds_socket, text, size);
++	tds_writetext_end(dbproc->tds_socket);
+ 
+ 	if (dbsqlok(dbproc) == SUCCEED && dbresults(dbproc) == SUCCEED)
+ 		return SUCCEED;
+@@ -6422,21 +6410,17 @@ dbmoretext(DBPROCESS * dbproc, DBINT size, BYTE * text)
+ 
+ 	assert(dbproc->text_size >= dbproc->text_sent);
+ 
+-	/* test dbproc value and state */
+-	if (!dbproc || !dbproc->tds_socket || dbproc->tds_socket->out_flag != TDS_BULK)
+-		return FAIL;
+-
++	/* TODO this test should be inside tds_writetext_continue, currently not */
+ 	if (size < 0 || size > dbproc->text_size - dbproc->text_sent)
+ 		return FAIL;
+ 
+ 	if (size) {
+-		tds_put_n(dbproc->tds_socket, text, size);
++		if (tds_writetext_continue(dbproc->tds_socket, text, size) != TDS_SUCCEED)
++			return FAIL;
+ 		dbproc->text_sent += size;
+ 
+-		if (dbproc->text_sent == dbproc->text_size) {
+-			tds_flush_packet(dbproc->tds_socket);
+-			tds_set_state(dbproc->tds_socket, TDS_PENDING);
+-		}
++		if (dbproc->text_sent == dbproc->text_size)
++			tds_writetext_end(dbproc->tds_socket);
+ 	}
+ 
+ 	return SUCCEED;
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 467f736..5d06482 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.5 2008/12/16 09:26:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.6 2008/12/16 15:41:19 freddy77 Exp $");
+ 
+ #ifndef MAX
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+@@ -1063,3 +1063,50 @@ tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 
+ 	return TDS_SUCCEED;
+ }
++
++int
++tds_writetext_start(TDSSOCKET *tds, const char *objname, const char *textptr, const char *timestamp, int with_log, TDS_UINT size)
++{
++	if (tds_submit_queryf(tds,
++			      "writetext bulk %s 0x%s timestamp = 0x%s%s",
++			      objname, textptr, timestamp, with_log ? " with log" : "")
++	    != TDS_SUCCEED) {
++		return TDS_FAIL;
++	}
++
++	/* FIXME in this case processing all results can bring state to IDLE... not threading safe */
++	/* read the end token */
++	if (tds_process_simple_query(tds) != TDS_SUCCEED)
++		return TDS_FAIL;
++
++	/* FIXME better transiction state */
++	tds->out_flag = TDS_BULK;
++	if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
++		return TDS_FAIL;
++	tds_put_int(tds, size);
++	return TDS_SUCCEED;
++}
++
++int
++tds_writetext_continue(TDSSOCKET *tds, const TDS_UCHAR *text, TDS_UINT size)
++{
++	/* TODO check state */
++	if (tds->out_flag != TDS_BULK)
++		return TDS_FAIL;
++
++	/* TODO check size letft */
++	tds_put_n(tds, text, size);
++	return TDS_SUCCEED;
++}
++
++int
++tds_writetext_end(TDSSOCKET *tds)
++{
++	/* TODO check state */
++	if (tds->out_flag != TDS_BULK)
++		return TDS_FAIL;
++
++	tds_flush_packet(tds);
++	tds_set_state(tds, TDS_PENDING);
++	return TDS_SUCCEED;
++}
+
+commit 868bbfa6ceb652df5e854730ab2e60358ac18361
+Author: freddy77 <freddy77>
+Date:   Wed Dec 17 11:04:34 2008 +0000
+
+    check tds_connect_and_login result correctly
+
+diff --git a/ChangeLog b/ChangeLog
+index d3a3627..7ade710 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Dec 17 12:01:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c src/dblib/dblib.c src/odbc/odbc.c src/pool/member.c:
++	* src/tds/login.c src/tds/unittests/common.c:
++	- check tds_connect_and_login result correctly
++
+ Tue Dec 16 16:39:35 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/ctlib/ct.c src/dblib/dblib.c src/tds/bulk.c:
+ 	- add and reuse tds_writetext_(start|continue|end)
+@@ -1086,4 +1091,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2685 2008/12/16 15:41:18 freddy77 Exp $
++$Id: ChangeLog,v 1.2686 2008/12/17 11:04:34 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 43a808b..ec95596 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.183 2008/12/16 15:41:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.184 2008/12/17 11:04:34 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -616,7 +616,7 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 		*/
+ 	}
+ 
+-	if (tds_connect_and_login(con->tds_socket, connection) == TDS_FAIL)
++	if (tds_connect_and_login(con->tds_socket, connection) != TDS_SUCCEED)
+ 		goto Cleanup;
+ 
+ 	tds_free_connection(connection);
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 1ea3983..ec1d31f 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.336 2008/12/16 15:41:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.337 2008/12/17 11:04:34 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1146,7 +1146,7 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 
+ 	TDS_MUTEX_UNLOCK(&dblib_mutex);
+ 
+-	if (tds_connect_and_login(dbproc->tds_socket, connection) == TDS_FAIL) {
++	if (tds_connect_and_login(dbproc->tds_socket, connection) != TDS_SUCCEED) {
+ 		tds_free_connection(connection);
+ 		dbclose(dbproc);
+ 		return NULL;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 3786b54..ff298b0 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.507 2008/12/15 05:31:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.508 2008/12/17 11:04:34 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -381,7 +381,7 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 
+ 	connection->connect_timeout = dbc->attr.connection_timeout;
+ 
+-	if (tds_connect_and_login(dbc->tds_socket, connection) == TDS_FAIL) {
++	if (tds_connect_and_login(dbc->tds_socket, connection) != TDS_SUCCEED) {
+ 		tds_free_socket(dbc->tds_socket);
+ 		dbc->tds_socket = NULL;
+ 		odbc_errs_add(&dbc->errs, "08001", NULL);
+diff --git a/src/pool/member.c b/src/pool/member.c
+index 418213c..b31fb5f 100644
+--- a/src/pool/member.c
++++ b/src/pool/member.c
+@@ -59,7 +59,7 @@
+ #define MAXHOSTNAMELEN 256
+ #endif /* MAXHOSTNAMELEN */
+ 
+-TDS_RCSID(var, "$Id: member.c,v 1.43 2008/12/15 05:31:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: member.c,v 1.44 2008/12/17 11:04:34 freddy77 Exp $");
+ 
+ static int pool_packet_read(TDS_POOL_MEMBER * pmbr);
+ static TDSSOCKET *pool_mbr_login(TDS_POOL * pool);
+@@ -96,7 +96,7 @@ pool_mbr_login(TDS_POOL * pool)
+ 	context = tds_alloc_context(NULL);
+ 	tds = tds_alloc_socket(context, 512);
+ 	connection = tds_read_config_info(NULL, login, context->locale);
+-	if (!connection || tds_connect_and_login(tds, connection) == TDS_FAIL) {
++	if (!connection || tds_connect_and_login(tds, connection) != TDS_SUCCEED) {
+ 		tds_free_socket(tds);
+ 		tds_free_connection(connection);
+ 		/* what to do? */
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 984ed12..b610e7c 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.177 2008/12/15 05:31:15 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.178 2008/12/17 11:04:34 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -355,7 +355,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 			connection->minor_version = versions[i].minor_version;
+ 			reset_save_context(&save_ctx);
+ 
+-			if ((erc = tds_connect_and_login(tds, connection)) == TDS_FAIL) {
++			if ((erc = tds_connect_and_login(tds, connection)) != TDS_SUCCEED) {
+ 				tds_close_socket(tds);
+ 			}
+ 			
+diff --git a/src/tds/unittests/common.c b/src/tds/unittests/common.c
+index 48896fb..f037b2a 100644
+--- a/src/tds/unittests/common.c
++++ b/src/tds/unittests/common.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.28 2008/12/15 05:31:15 jklowden Exp $";
++static char software_version[] = "$Id: common.c,v 1.29 2008/12/17 11:04:34 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -97,7 +97,7 @@ try_tds_login(TDSLOGIN ** login, TDSSOCKET ** tds, const char *appname, int verb
+ 	*tds = tds_alloc_socket(test_context, 512);
+ 	tds_set_parent(*tds, NULL);
+ 	connection = tds_read_config_info(NULL, *login, test_context->locale);
+-	if (!connection || tds_connect_and_login(*tds, connection) == TDS_FAIL) {
++	if (!connection || tds_connect_and_login(*tds, connection) != TDS_SUCCEED) {
+ 		if (connection) {
+ 			tds_free_socket(*tds);
+ 			*tds = NULL;
+
+commit 8ce5f1b8462176cc71bc0859aec7316b8bfc7332
+Author: freddy77 <freddy77>
+Date:   Wed Dec 17 11:12:02 2008 +0000
+
+    optimize tds_config_verstr
+
+diff --git a/ChangeLog b/ChangeLog
+index 7ade710..485d1a3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Dec 17 12:10:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: optimize
++
+ Wed Dec 17 12:01:55 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c src/dblib/dblib.c src/odbc/odbc.c src/pool/member.c:
+ 	* src/tds/login.c src/tds/unittests/common.c:
+@@ -1091,4 +1094,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2686 2008/12/17 11:04:34 freddy77 Exp $
++$Id: ChangeLog,v 1.2687 2008/12/17 11:12:02 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 5863e9f..2cb061c 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.139 2008/12/15 05:31:15 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.140 2008/12/17 11:12:02 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -688,43 +688,38 @@ tds_config_env_tdshost(TDSCONNECTION * connection)
+  * Set TDS version from given string
+  * @param tdsver tds string version
+  * @param connection where to store information
+- * @return as encoded hex value: high nybble major, low nybble minor.  
++ * @return as encoded hex value: high nybble major, low nybble minor.
+  */
+ unsigned char
+ tds_config_verstr(const char *tdsver, TDSCONNECTION * connection)
+ {
+-	TDSCONNECTION dummy, *c = &dummy;
+-	
+-	if (connection) 
+-		c = connection;
+-	
+-	if (!strcmp(tdsver, "42") || !strcmp(tdsver, "4.2")) {
+-		c->major_version = 4;
+-		c->minor_version = 2;
+-	} else if (!strcmp(tdsver, "46") || !strcmp(tdsver, "4.6")) {
+-		c->major_version = 4;
+-		c->minor_version = 6;
+-	} else if (!strcmp(tdsver, "50") || !strcmp(tdsver, "5.0")) {
+-		c->major_version = 5;
+-		c->minor_version = 0;
+-	} else if (!strcmp(tdsver, "70") || !strcmp(tdsver, "7.0")) {
+-		c->major_version = 7;
+-		c->minor_version = 0;
+-	} else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0")) {
+-		c->major_version = 8;
+-		c->minor_version = 0;
++	unsigned char version;
++
++	if (!strcmp(tdsver, "42") || !strcmp(tdsver, "4.2"))
++		version = 0x42;
++	else if (!strcmp(tdsver, "46") || !strcmp(tdsver, "4.6"))
++		version = 0x46;
++	else if (!strcmp(tdsver, "50") || !strcmp(tdsver, "5.0"))
++		version = 0x50;
++	else if (!strcmp(tdsver, "70") || !strcmp(tdsver, "7.0"))
++		version = 0x70;
++	else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0"))
++		version = 0x80;
+ #ifdef ENABLE_DEVELOPING
+-	} else if (!strcmp(tdsver, "90") || !strcmp(tdsver, "9.0")) {
+-		c->major_version = 9;
+-		c->minor_version = 0;
++	else if (!strcmp(tdsver, "90") || !strcmp(tdsver, "9.0"))
++		version = 0x90;
+ #endif
+-	} else if (!strcmp(tdsver, "0.0")) {
+-		c->major_version = 0;
+-		c->minor_version = 0;
+-	} else 
++	else if (!strcmp(tdsver, "0.0"))
++		version = 0;
++	else 
+ 		return 0;
+-	
+-	return (c->major_version << 4) | c->minor_version;
++
++	if (connection) {
++		connection->major_version = version >> 4;
++		connection->minor_version = version & 0xf;
++	}
++
++	return version;
+ }
+ 
+ /**
+
+commit ba98f393811f30a15171b5e69b121be81fb2a844
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 10:37:51 2008 +0000
+
+    fix pointer error
+
+diff --git a/ChangeLog b/ChangeLog
+index 485d1a3..79ebdbd 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Dec 19 11:36:53 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c: fix memory problem
++	* src/ctlib/ct.c: small optimization
++
+ Wed Dec 17 12:10:29 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c: optimize
+ 
+@@ -1094,4 +1098,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2687 2008/12/17 11:12:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2688 2008/12/19 10:37:51 freddy77 Exp $
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index f37732a..7d0a25b 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,7 +38,7 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.48 2008/12/16 09:26:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.49 2008/12/19 10:37:51 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+@@ -598,7 +598,7 @@ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred
+ 		blkdesc->bcpinfo.xfer_init = 1;
+ 	} 
+ 
+-	blkdesc->bcpinfo.parent = &blkdesc;
++	blkdesc->bcpinfo.parent = blkdesc;
+ 	for (each_row = 0; each_row < rows_to_xfer; each_row++ ) {
+ 
+ 		if (tds_bcp_send_record(tds, &blkdesc->bcpinfo, _blk_get_col_data, _blk_null_error, each_row) == TDS_SUCCEED) {
+@@ -639,6 +639,8 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset)
+ 	 * and increment it if offset specified
+ 	 */
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_blk_get_col_data(%p, %p, %d)\n", bulk, bindcol, offset);
++
+ 	src = (unsigned char *) bindcol->column_varaddr;
+ 	src += offset * bindcol->column_bindlen;
+ 	
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index ec95596..46c3dea 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.184 2008/12/17 11:04:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.185 2008/12/19 10:37:51 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -264,12 +264,11 @@ ct_con_alloc(CS_CONTEXT * ctx, CS_CONNECTION ** con)
+ 	login = tds_alloc_login();
+ 	if (!login)
+ 		return CS_FAIL;
+-	*con = (CS_CONNECTION *) malloc(sizeof(CS_CONNECTION));
++	*con = (CS_CONNECTION *) calloc(1, sizeof(CS_CONNECTION));
+ 	if (!*con) {
+ 		tds_free_login(login);
+ 		return CS_FAIL;
+ 	}
+-	memset(*con, '\0', sizeof(CS_CONNECTION));
+ 	(*con)->tds_login = login;
+ 
+ 	/* so we know who we belong to */
+
+commit ac99a367453ed546c74a069ff2d34577e3713784
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 10:38:56 2008 +0000
+
+    make some variable static
+
+diff --git a/ChangeLog b/ChangeLog
+index 79ebdbd..54ba070 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Dec 19 11:38:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/bcp.c src/dblib/unittests/bcp.h:
++	- make some variable static
++
+ Fri Dec 19 11:36:53 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/blk.c: fix memory problem
+ 	* src/ctlib/ct.c: small optimization
+@@ -1098,4 +1102,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2688 2008/12/19 10:37:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2689 2008/12/19 10:38:56 freddy77 Exp $
+diff --git a/src/dblib/unittests/bcp.c b/src/dblib/unittests/bcp.c
+index 5954615..511d42d 100644
+--- a/src/dblib/unittests/bcp.c
++++ b/src/dblib/unittests/bcp.c
+@@ -13,7 +13,7 @@
+ 
+ #include "bcp.h"
+ 
+-static char software_version[] = "$Id: bcp.c,v 1.15 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: bcp.c,v 1.16 2008/12/19 10:38:56 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[512];
+@@ -23,20 +23,20 @@ static void test_bind(DBPROCESS * dbproc);
+ /*
+  * Static data for insertion
+  */
+-int not_null_bit = 1;
+-char not_null_char[] = "a char";
+-char not_null_varchar[] = "a varchar";
+-char not_null_datetime[] 		= "Dec 17 2003  3:44PM";
+-char not_null_smalldatetime[] 	= "Dec 17 2003  3:44PM";
+-char not_null_money[] = "12.34";
+-char not_null_smallmoney[] = "12.34";
+-char not_null_float[] = "12.34";
+-char not_null_real[] = "12.34";
+-char not_null_decimal[] = "12.34";
+-char not_null_numeric[] = "12.34";
+-int not_null_int        = 1234;
+-int not_null_smallint   = 1234;
+-int not_null_tinyint    = 123;
++static int not_null_bit = 1;
++static char not_null_char[] = "a char";
++static char not_null_varchar[] = "a varchar";
++static char not_null_datetime[] 		= "Dec 17 2003  3:44PM";
++static char not_null_smalldatetime[] 	= "Dec 17 2003  3:44PM";
++static char not_null_money[] = "12.34";
++static char not_null_smallmoney[] = "12.34";
++static char not_null_float[] = "12.34";
++static char not_null_real[] = "12.34";
++static char not_null_decimal[] = "12.34";
++static char not_null_numeric[] = "12.34";
++static int not_null_int        = 1234;
++static int not_null_smallint   = 1234;
++static int not_null_tinyint    = 123;
+ 
+ 
+ static int
+diff --git a/src/dblib/unittests/bcp.h b/src/dblib/unittests/bcp.h
+index 1412e9c..5448727 100644
+--- a/src/dblib/unittests/bcp.h
++++ b/src/dblib/unittests/bcp.h
+@@ -1,4 +1,4 @@
+-char create_table_sql[] = 
++static const char create_table_sql[] = 
+ "CREATE TABLE all_types_bcp_unittest (\n"
+ "	  not_null_bit			bit NOT NULL\n"
+ "\n"
+
+commit a3d680efa488369326efe4bc2a13d96a6677407d
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 15:41:29 2008 +0000
+
+    notes, reduce variable scope, remove new_record_size
+
+diff --git a/ChangeLog b/ChangeLog
+index 54ba070..20c06d7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Dec 19 16:40:53 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/bulk.c:
++	- notes, reduce variable scope, remove new_record_size
++
+ Fri Dec 19 11:38:30 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/bcp.c src/dblib/unittests/bcp.h:
+ 	- make some variable static
+@@ -1102,4 +1106,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2689 2008/12/19 10:38:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2690 2008/12/19 15:41:29 freddy77 Exp $
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 5d06482..542ff79 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.6 2008/12/16 15:41:19 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.7 2008/12/19 15:41:29 freddy77 Exp $");
+ 
+ #ifndef MAX
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+@@ -79,6 +79,7 @@ tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 		/* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */
+ 		return TDS_FAIL;
+ 
++	/* TODO possibly stop at ROWFMT and copy before going to idle */
+ 	/* TODO check what happen if table is not present, cleanup on error */
+ 	while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
+ 		   == TDS_SUCCEED) {
+@@ -148,7 +149,8 @@ tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 
+ 		if (tds_submit_queryf(tds, "set identity_insert %s on", bcpinfo->tablename) == TDS_FAIL)
+ 			goto cleanup;
+-	
++
++		/* TODO use tds_process_simple_query */
+ 		while ((rc = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS))
+ 			   == TDS_SUCCEED) {
+ 		}
+@@ -349,6 +351,7 @@ tds_bcp_start_insert_stmt(TDSSOCKET * tds, TDSBCPINFO * bcpinfo)
+ 		colclause.cb = sizeof(clause_buffer);
+ 		colclause.from_malloc = 0;
+ 
++		/* TODO avoid asprintf, use always malloc-ed buffer */
+ 		firstcol = 1;
+ 
+ 		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+@@ -412,23 +415,15 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 
+ 	unsigned char *record;
+ 	TDS_INT	 old_record_size;
+-	TDS_INT	 new_record_size;
+-	TDS_TINYINT  varint_1;
+-
+-	int row_pos;
+-	int row_sz_pos;
+-	TDS_SMALLINT row_size;
+-	int blob_cols = 0;
+-	int var_cols_written = 0;
+ 	int i;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_bcp_record(offset %d)\n", offset);
++	tdsdump_log(TDS_DBG_FUNC, "tds_bcp_send_bcp_record(%p, %p, %p, %p, %d)\n", tds, bcpinfo, get_col_data, null_error, offset);
+ 
+ 	record = bcpinfo->bindinfo->current_row;
+ 	old_record_size = bcpinfo->bindinfo->row_size;
+-	new_record_size = 0;
+ 
+ 	if (IS_TDS7_PLUS(tds)) {
++		TDS_TINYINT  varint_1;
+ 
+ 		for (i = 0; i < bcpinfo->bindinfo->num_cols; i++) {
+ 	
+@@ -462,12 +457,10 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 					case XSYBNVARCHAR:
+ 						memcpy(record, CHARBIN_NULL, 2);
+ 						record +=2;
+-						new_record_size +=2;
+ 						break;
+ 					default:
+ 						*record = GEN_NULL;
+ 						record++;
+-						new_record_size ++;
+ 						break;
+ 					}
+ 				} else {
+@@ -483,14 +476,13 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 						*record = textptr_size; record++;
+ 						memcpy(record, textptr, 16); record += 16;
+ 						memcpy(record, timestamp, 8); record += 8;
+-						new_record_size += 25;
+ 					}
+ 					TDS_PUT_UA4LE(record, bindcol->bcp_column_data->datalen);
+-					record += 4; new_record_size +=4;
++					record += 4;
+ 					break;
+ 				case 2:
+ 					TDS_PUT_UA2LE(record, bindcol->bcp_column_data->datalen);
+-					record += 2; new_record_size +=2;
++					record += 2;
+ 					break;
+ 				case 1:
+ 					varint_1 = bindcol->bcp_column_data->datalen;
+@@ -502,14 +494,14 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 						varint_1 = bindcol->bcp_column_data->datalen;
+ 						tdsdump_log(TDS_DBG_INFO1, "varint_1 = %d\n", varint_1);
+ 					}
+-					*record = varint_1; record++; new_record_size++;
++					*record = varint_1; record++;
+ 					break;
+ 				case 0:
+ 					break;
+ 				}
+ 
+ 				tdsdump_log(TDS_DBG_INFO1, "new_record_size = %d datalen = %d \n", 
+-							new_record_size, bindcol->bcp_column_data->datalen);
++							record - bcpinfo->bindinfo->current_row, bindcol->bcp_column_data->datalen);
+ 
+ #if WORDS_BIGENDIAN
+ 				tds_swap_datatype(tds_get_conversion_type(bindcol->column_type, bindcol->bcp_column_data->datalen),
+@@ -524,22 +516,26 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 					size = tds_numeric_bytes_per_prec[num->precision];
+ 					memcpy(record, num->array, size);
+ 					record += size; 
+-					new_record_size += size;
+ 				} else {
+ 					memcpy(record, bindcol->bcp_column_data->data, bindcol->bcp_column_data->datalen);
+ 					record += bindcol->bcp_column_data->datalen;
+-					new_record_size += bindcol->bcp_column_data->datalen;
+ 				}
+ 
+ 			}
+ 			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n",
+-					old_record_size, new_record_size);
++					old_record_size, record - bcpinfo->bindinfo->current_row);
+ 		}
+ 
+ 		tds_put_byte(tds, TDS_ROW_TOKEN);   /* 0xd1 */
+-		tds_put_n(tds, bcpinfo->bindinfo->current_row, new_record_size);
++		tds_put_n(tds, bcpinfo->bindinfo->current_row, record - bcpinfo->bindinfo->current_row);
+ 	}  /* IS_TDS7_PLUS */
+ 	else {
++		int row_pos;
++		int row_sz_pos;
++		TDS_SMALLINT row_size;
++		int blob_cols = 0;
++		int var_cols_written = 0;
++
+ 		memset(record, '\0', old_record_size);	/* zero the rowbuffer */
+ 
+ 		/*
+
+commit 43496a761b1e986af6a00ecb0f0ebc5637ce7667
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 15:48:53 2008 +0000
+
+    script for help committing
+
+diff --git a/misc/commit b/misc/commit
+new file mode 100755
+index 0000000..6303f40
+--- /dev/null
++++ b/misc/commit
+@@ -0,0 +1,210 @@
++#!/usr/bin/perl
++
++# $Id: commit,v 1.1 2008/12/19 15:48:53 freddy77 Exp $
++
++use strict;
++
++my $debug = 0;
++my $lineLimit = 75; # maximun row length
++
++# parse arguments
++my $cvsMessage = '';
++foreach my $arg (@ARGV) {
++	$debug = 1, next if $arg eq '--debug';
++	die("wrong argument $cvsMessage\n") if $cvsMessage ne '';
++	$cvsMessage = $arg;
++}
++die("cvs commit message required\n") if $cvsMessage eq '';
++
++`freetds_local`;
++die('setting local') if $?;
++
++# extract file changed
++open(CHANGES, 'cvs diff 2> /dev/null | lsdiff |') or die('gettting file changed');
++my %changes;
++while(<CHANGES>) {
++	chomp;
++	print "detected file changed $_\n" if $debug;
++	$changes{$_} = 0;
++}
++close(CHANGES);
++
++my @lastFiles; # all files collected
++my $lastComment = ''; # all comments collected
++my @changeLog; # list of files with proper comments
++
++sub addChangeLog()
++{
++	die('comment with no files') if $#lastFiles < 0;
++	my @files = @lastFiles;
++	$lastComment =~ s/ $//;
++	push @changeLog, { files => \@files, comment => $lastComment };
++	$lastComment = '';
++	@lastFiles = ();
++}
++
++sub dumpChangeLog()
++{
++	print "dumping changeLog\n";
++	foreach my $ch (@changeLog) {
++		print "\tfiles: ".join(' ',@{$ch->{files}})."
++\tcomment: $ch->{comment}
++";
++	}
++}
++sub parseLine($)
++{
++	my ($line) = @_;
++	my $comment = '';
++	chomp $line;
++	print "lastFiles @lastFiles\n" if $debug;
++	print "parsing line $line\n" if $debug;
++
++	# anything after : or - is a comment
++	if ($line =~ /(.*?)[-:](.*)/) {
++		($line, $comment) = ($1, $2);
++		print "line $line comment $comment\n" if $debug;
++	}
++
++	# if start with * a file follows
++	my $needFile = 0;
++	if ($line =~ /^\s*\*\s*(.*)/) {
++		$needFile = 1;
++		$line = $1;
++	}
++
++	print "parsing line $line\n" if $debug;
++
++	my $fileFound = 0;
++	foreach my $tok (split(/\s+/, $line)) {
++		print "token $tok\n" if $debug;
++		if (defined($changes{$tok})) {
++			# add comment to files
++			addChangeLog if ($lastComment);
++			$fileFound = 1;
++			die ("found two $tok references") if ++$changes{$tok} > 1;
++			push @lastFiles, $tok;
++			print "file $tok detected\n" if $debug;
++			$line =~ s/.*?$tok\s*//;
++			print "line left $line\n" if $debug;
++		} else {
++			last
++		}
++	}
++	die('wrong format line, file expected') if $needFile && !$fileFound;
++
++	$line =~ s/^\s+//s;
++	$comment =~ s/^\s+//s;
++	die ('two comments') if $line ne '' && $comment ne '';
++	$lastComment .= " $line $comment";
++	$lastComment =~ s/\s+/ /sg;
++	$lastComment =~ s/^ //;
++}
++
++# extract first ChangeLog rows
++open(CL, '<', 'ChangeLog') or die ('opening ChangeLog');
++my $nRow = 1;
++my $begin = '';
++while (<CL>) {
++	my $hdr = 0;
++	if ($nRow == 1) {
++		my $norm = $_;
++		$norm =~ s/\s+/ /g;
++		$hdr = ($norm =~ /Frediano Ziglio/i);
++	}
++	if (!$hdr) {
++		last if $nRow != 1 && $_ ne "\n" && !/^[ \t]/;
++		&parseLine($_);
++		$begin .= $_;
++	}
++	++$nRow;
++	die('too many start rows') if $nRow >= 20;
++}
++addChangeLog if ($lastComment);
++die('files with no comments') if $#lastFiles >= 0;
++dumpChangeLog if $debug;
++close(CL);
++--$nRow;
++print "readed $nRow lines\n" if $debug;
++print "begin with: \n--- START ---\n$begin--- END ---\n" if $debug;
++
++sub splitLines($$$$$)
++{
++	my ($line, $start1, $start2, $end, $limit) = @_;
++	my $res = '';
++	my $start = $start1;
++	while (length($line) > $limit) {
++		die("unable to split line:\n'$line'") if ($line !~ /^(.{1,$limit}) (.*)$/);
++		$res .= "$start$1$end\n";
++		$start = $start2;
++		$line = $2;
++	}
++	$res .= "$start$line$end\n";
++	return $res;
++}
++
++# compute ChangeLog lines and list of all files
++my $date = `date`;
++chomp $date;
++my $norm = "$date    Frediano Ziglio <freddy77_A_gmail_D_com>\n";
++my @allFiles = ('ChangeLog');
++foreach my $ch (@changeLog) {
++	push @allFiles, @{$ch->{files}};
++	my $files = join(' ', @{$ch->{files}});
++	my $oneLine = "* $files: $ch->{comment}";
++	if (length($oneLine) + 8 <= $lineLimit) {
++		$norm .= "\t$oneLine\n"
++	} else {
++		$norm .= splitLines($files, "\t* ", "\t* ", ':', $lineLimit - 11);
++		$norm .= splitLines($ch->{comment}, "\t- ", "\t  ", '', $lineLimit - 10);
++	}
++}
++print "Normalized ChangeLog:\n$norm";
++print "Changed file list:\n".splitLines(join(' ',@allFiles), "\t", "\t", '', $lineLimit - 8);
++print "Message:\n\t$cvsMessage\n";
++
++# request confirm
++for (;;) {
++	print "Agree (yes|no)\n";
++	$! = '';
++	my $answer = <STDIN>;
++	die("error reading reply: $!") if !defined($answer);
++	chomp $answer;
++	last if $answer eq 'yes';
++	exit(0) if $answer eq 'no';
++}
++
++# change ChangeLog if needed
++open(CL, '<', 'ChangeLog') or die ('opening ChangeLog');
++open(CL2, '>', '.ChangeLog.tmp') or die ('opening ChangeLog');
++print CL2 "$norm\n";
++for my $i (1..$nRow) {
++	<CL>;
++}
++while (<CL>) {
++	print CL2 $_;
++}
++close(CL2);
++close(CL);
++rename('.ChangeLog.tmp', 'ChangeLog') or die('error renaming temp ChangeLog file');
++
++# commit 
++`freetds_remote`;
++die('setting local') if $?;
++$| = 1;
++if (!fork()) {
++	my @args = ('cvs', 'commit', '-m', $cvsMessage, @allFiles);
++	print "Command:\n\t".join(' ', @args)."\n" if $debug;
++	exec @args if !$debug;
++	exit(1);
++}
++wait();
++my $cvsOut = $?;
++
++`freetds_local`;
++die('setting local') if $?;
++
++die('cvs command failed') if $cvsOut;
++
++print "Everything went all right\n";
++
+
+commit c837c559123089c83a7290fc05852009700032a2
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 16:23:20 2008 +0000
+
+    process last empty field from sql browser
+
+diff --git a/ChangeLog b/ChangeLog
+index 20c06d7..f66e10e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Dec 19 17:22:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- fix typo, process last empty field from sql browser
++
+ Fri Dec 19 16:40:53 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/bulk.c:
+ 	- notes, reduce variable scope, remove new_record_size
+@@ -1106,4 +1110,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2690 2008/12/19 15:41:29 freddy77 Exp $
++$Id: ChangeLog,v 1.2691 2008/12/19 16:23:20 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 8552192..6435f06 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.80 2008/12/15 05:31:15 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.81 2008/12/19 16:23:20 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -800,7 +800,7 @@ tds_write_packet(TDSSOCKET * tds, unsigned char final)
+ /**
+  * Get port of all instances
+  * @return default port number or 0 if error
+- * @remark experimental, cf. MS-SQLR.pdf.
++ * @remark experimental, cf. MC-SQLR.pdf.
+  */
+ int
+ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+@@ -1098,11 +1098,14 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 					break;
+ 				*p++ = 0;
+ 
+-				value = p;
+-				p = strchr(p, ';');
+-				if (!p)
+-					break;
+-				*p++ = 0;
++				value = name;
++				if (*name) {
++					value = p;
++					p = strchr(p, ';');
++					if (!p)
++						break;
++					*p++ = 0;
++				}
+ 
+ 				if (strcasecmp(name, "InstanceName") == 0) {
+ 					if (strcasecmp(value, instance) != 0)
+
+commit 13354246185995793641fe59970ffd33d5fc80d2
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 18:43:21 2008 +0000
+
+    fix possible issue with 64 bit machines
+
+diff --git a/ChangeLog b/ChangeLog
+index f66e10e..8cf9b86 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Dec 19 19:43:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/bulk.c: fix possible issue with 64 bit machines
++
+ Fri Dec 19 17:22:14 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c:
+ 	- fix typo, process last empty field from sql browser
+@@ -1110,4 +1113,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2691 2008/12/19 16:23:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2692 2008/12/19 18:43:21 freddy77 Exp $
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 542ff79..856f831 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.7 2008/12/19 15:41:29 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.8 2008/12/19 18:43:21 freddy77 Exp $");
+ 
+ #ifndef MAX
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+@@ -500,8 +500,8 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 					break;
+ 				}
+ 
+-				tdsdump_log(TDS_DBG_INFO1, "new_record_size = %d datalen = %d \n", 
+-							record - bcpinfo->bindinfo->current_row, bindcol->bcp_column_data->datalen);
++				tdsdump_log(TDS_DBG_INFO1, "new_record_size = %ld datalen = %d\n", 
++							(long int) (record - bcpinfo->bindinfo->current_row), bindcol->bcp_column_data->datalen);
+ 
+ #if WORDS_BIGENDIAN
+ 				tds_swap_datatype(tds_get_conversion_type(bindcol->column_type, bindcol->bcp_column_data->datalen),
+@@ -522,8 +522,8 @@ tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data ge
+ 				}
+ 
+ 			}
+-			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %d \n",
+-					old_record_size, record - bcpinfo->bindinfo->current_row);
++			tdsdump_log(TDS_DBG_INFO1, "old_record_size = %d new size = %ld\n",
++					old_record_size, (long int) (record - bcpinfo->bindinfo->current_row));
+ 		}
+ 
+ 		tds_put_byte(tds, TDS_ROW_TOKEN);   /* 0xd1 */
+
+commit db08c4237d2505ed7bfd5183c8827297f4d7b7c6
+Author: freddy77 <freddy77>
+Date:   Fri Dec 19 19:22:17 2008 +0000
+
+    improve commit script
+
+diff --git a/ChangeLog b/ChangeLog
+index 8cf9b86..e58b99f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Dec 19 20:22:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/commit:
++	- fix date language problem
++	- multiple comments support
++
+ Fri Dec 19 19:43:07 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/bulk.c: fix possible issue with 64 bit machines
+ 
+@@ -1113,4 +1118,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2692 2008/12/19 18:43:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2693 2008/12/19 19:22:17 freddy77 Exp $
+diff --git a/misc/commit b/misc/commit
+index 6303f40..5b0ea28 100755
+--- a/misc/commit
++++ b/misc/commit
+@@ -1,6 +1,6 @@
+ #!/usr/bin/perl
+ 
+-# $Id: commit,v 1.1 2008/12/19 15:48:53 freddy77 Exp $
++# $Id: commit,v 1.2 2008/12/19 19:22:17 freddy77 Exp $
+ 
+ use strict;
+ 
+@@ -30,16 +30,16 @@ while(<CHANGES>) {
+ close(CHANGES);
+ 
+ my @lastFiles; # all files collected
+-my $lastComment = ''; # all comments collected
++my @lastComments = (); # all comments collected
+ my @changeLog; # list of files with proper comments
+ 
+ sub addChangeLog()
+ {
++	@lastComments = grep { $_ ne '' } map { s/\s+/ /sg; s/^ //; s/ $//; $_ } @lastComments;
++	return if $#lastComments < 0;
+ 	die('comment with no files') if $#lastFiles < 0;
+-	my @files = @lastFiles;
+-	$lastComment =~ s/ $//;
+-	push @changeLog, { files => \@files, comment => $lastComment };
+-	$lastComment = '';
++	push @changeLog, { files => [@lastFiles], comments => [@lastComments] };
++	@lastComments = ();
+ 	@lastFiles = ();
+ }
+ 
+@@ -48,7 +48,7 @@ sub dumpChangeLog()
+ 	print "dumping changeLog\n";
+ 	foreach my $ch (@changeLog) {
+ 		print "\tfiles: ".join(' ',@{$ch->{files}})."
+-\tcomment: $ch->{comment}
++\tcomments: - ".join("\n\t\t- ", @{$ch->{comments}})."
+ ";
+ 	}
+ }
+@@ -61,8 +61,9 @@ sub parseLine($)
+ 	print "parsing line $line\n" if $debug;
+ 
+ 	# anything after : or - is a comment
+-	if ($line =~ /(.*?)[-:](.*)/) {
+-		($line, $comment) = ($1, $2);
++	if ($line =~ /(.*?)([-:])(.*)/) {
++		($line, $comment) = ($1, $3);
++		push(@lastComments, '') if $2 eq '-';
+ 		print "line $line comment $comment\n" if $debug;
+ 	}
+ 
+@@ -77,10 +78,11 @@ sub parseLine($)
+ 
+ 	my $fileFound = 0;
+ 	foreach my $tok (split(/\s+/, $line)) {
++		next if $tok eq '';
+ 		print "token $tok\n" if $debug;
+ 		if (defined($changes{$tok})) {
+ 			# add comment to files
+-			addChangeLog if ($lastComment);
++			addChangeLog();
+ 			$fileFound = 1;
+ 			die ("found two $tok references") if ++$changes{$tok} > 1;
+ 			push @lastFiles, $tok;
+@@ -95,10 +97,9 @@ sub parseLine($)
+ 
+ 	$line =~ s/^\s+//s;
+ 	$comment =~ s/^\s+//s;
+-	die ('two comments') if $line ne '' && $comment ne '';
+-	$lastComment .= " $line $comment";
+-	$lastComment =~ s/\s+/ /sg;
+-	$lastComment =~ s/^ //;
++	die ('two comments in a line') if $line ne '' && $comment ne '';
++	push(@lastComments, '') if $#lastComments < 0;
++	$lastComments[-1] .= " $line $comment";
+ }
+ 
+ # extract first ChangeLog rows
+@@ -120,7 +121,7 @@ while (<CL>) {
+ 	++$nRow;
+ 	die('too many start rows') if $nRow >= 20;
+ }
+-addChangeLog if ($lastComment);
++addChangeLog();
+ die('files with no comments') if $#lastFiles >= 0;
+ dumpChangeLog if $debug;
+ close(CL);
+@@ -144,19 +145,19 @@ sub splitLines($$$$$)
+ }
+ 
+ # compute ChangeLog lines and list of all files
+-my $date = `date`;
++my $date = `LANG=C date`;
+ chomp $date;
+ my $norm = "$date    Frediano Ziglio <freddy77_A_gmail_D_com>\n";
+ my @allFiles = ('ChangeLog');
+ foreach my $ch (@changeLog) {
+ 	push @allFiles, @{$ch->{files}};
+ 	my $files = join(' ', @{$ch->{files}});
+-	my $oneLine = "* $files: $ch->{comment}";
+-	if (length($oneLine) + 8 <= $lineLimit) {
++	my $oneLine = "* $files: $ch->{comments}";
++	if (scalar @{$ch->{comments}} == 1 && length($oneLine) + 8 <= $lineLimit) {
+ 		$norm .= "\t$oneLine\n"
+ 	} else {
+ 		$norm .= splitLines($files, "\t* ", "\t* ", ':', $lineLimit - 11);
+-		$norm .= splitLines($ch->{comment}, "\t- ", "\t  ", '', $lineLimit - 10);
++		$norm .= join('', map { splitLines($_, "\t- ", "\t  ", '', $lineLimit - 10) } @{$ch->{comments}});
+ 	}
+ }
+ print "Normalized ChangeLog:\n$norm";
+
+commit d8b5fb1635c44ed407c0550e195245dc16bb1b34
+Author: jklowden <jklowden>
+Date:   Sat Dec 20 06:01:21 2008 +0000
+
+    initialize tds_login at allocation, not connection
+
+diff --git a/ChangeLog b/ChangeLog
+index e58b99f..403bef7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,14 @@
++Sat Dec 20 00:52:51 EST 2008	JK Lowden <jklowden@freetds.org>
++	* src/tds/login.c src/tds/mem.c src/tds/net.c
++	- initialize tds_login at allocation, not connection
++	* configure.ac include/Makefile.am 
++	- sort header files for readability
++	* doc/userguide.dsl.in HTML 4.0 strict output
++	* doc/userguide.sgml minor updates
++	* src/replacements/Makefile.am 
++	* src/replacements/fakepoll.h src/replacements/fakepoll.c
++	- added fakepoll
++
+ Fri Dec 19 20:22:03 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/commit:
+ 	- fix date language problem
+@@ -1118,4 +1129,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2693 2008/12/19 19:22:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2694 2008/12/20 06:01:21 jklowden Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index b610e7c..81be9db 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.178 2008/12/17 11:04:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.179 2008/12/20 06:01:21 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -122,18 +122,26 @@ tds_set_app(TDSLOGIN * tds_login, const char *application)
+ void
+ tds_set_server(TDSLOGIN * tds_login, const char *server)
+ {
+-	if (!server || strlen(server) == 0) {
+-		server = getenv("TDSQUERY");
+-		tdsdump_log(TDS_DBG_INFO1, "Setting 'server_name' to '%s' from $TDSQUERY.\n", server);
+-	}
+-	if (!server || strlen(server) == 0) {
+-		server = getenv("DSQUERY");
+-		tdsdump_log(TDS_DBG_INFO1, "Setting 'server_name' to '%s' from $DSQUERY.\n", server);
+-	}
+-	if (!server || strlen(server) == 0) {
+-		server = "SYBASE";
+-		tdsdump_log(TDS_DBG_INFO1, "Setting 'server_name' to '%s' (compiled-in default).\n", server);
++#if 0
++	// Doing this in tds_alloc_login instead
++	static const char *names[] = { "TDSQUERY", "DSQUERY", "SYBASE" };
++	int i;
++	
++	for (i=0; i < TDS_VECTOR_SIZE(names) && (!server || strlen(server) == 0); i++) {
++		const char *source;
++		if (i + 1 == TDS_VECTOR_SIZE(names)) {
++			server = names[i];
++			source = "compiled-in default";
++		} else {
++			server = getenv(names[i]);
++			source = names[i];
++		}
++		if (server) {
++			tdsdump_log(TDS_DBG_INFO1, "Setting TDSLOGIN::server_name to '%s' from %s.\n", server, source);
++		}
+ 	}
++#endif
++	assert(server);
+ 	tds_dstr_copy(&tds_login->server_name, server);
+ }
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 6238db3..b0edbf7 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -22,13 +22,7 @@
+ #include <config.h>
+ #endif /* HAVE_CONFIG_H */
+ 
+-#if HAVE_STDLIB_H
+ #include <stdlib.h>
+-#endif /* HAVE_STDLIB_H */
+-
+-#if HAVE_STRING_H
+-#include <string.h>
+-#endif /* HAVE_STRING_H */
+ 
+ #if HAVE_UNISTD_H
+ #include <unistd.h>
+@@ -47,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.182 2008/11/05 14:54:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.183 2008/12/20 06:01:21 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -955,7 +949,9 @@ TDSLOGIN *
+ tds_alloc_login(void)
+ {
+ 	TDSLOGIN *tds_login;
+-
++	const char *server_name = "SYBASE";
++	char *s;
++	
+ 	TEST_MALLOC(tds_login, TDSLOGIN);
+ 	tds_dstr_init(&tds_login->server_name);
+ 	tds_dstr_init(&tds_login->server_addr);
+@@ -967,7 +963,16 @@ tds_alloc_login(void)
+ 	tds_dstr_init(&tds_login->password);
+ 	tds_dstr_init(&tds_login->library);
+ 	tds_dstr_init(&tds_login->client_charset);
++
++	if ((s=getenv("DSQUERY")) != NULL)
++		server_name = s;
++
++	if ((s=getenv("TDSQUERY")) != NULL)
++		server_name = s;
++
++	tds_dstr_copy(&tds_login->server_name, server_name);
+ 	memcpy(tds_login->capabilities, defaultcaps, TDS_MAX_CAPABILITY);
++
+ 	return tds_login;
+ 
+       Cleanup:
+@@ -993,6 +998,7 @@ tds_free_login(TDSLOGIN * login)
+ 		free(login);
+ 	}
+ }
++
+ TDSSOCKET *
+ tds_alloc_socket(TDSCONTEXT * context, int bufsize)
+ {
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 6435f06..2536db0 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.81 2008/12/19 16:23:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.82 2008/12/20 06:01:22 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -347,9 +347,11 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ {
+ 	int rc, seconds;
+ 	unsigned int poll_seconds;
++	const char *method = "poll(2)";
+ #if !USE_POLL
+ 	fd_set fds[3];
+ 	fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
++	method = "select(2)";
+ #endif
+ 
+ 	assert(tds != NULL);
+@@ -426,8 +428,8 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 			case TDSSOCK_EINTR:
+ 				break;	/* let interrupt handler be called */
+ 			default: /* documented: EFAULT, EBADF, EINVAL */
+-				tdsdump_log(TDS_DBG_ERROR, "error: select(2) returned 0x%x, \"%s\"\n", 
+-						sock_errno, strerror(sock_errno));
++				tdsdump_log(TDS_DBG_ERROR, "error: %s returned %d, \"%s\"\n", 
++						method, sock_errno, strerror(sock_errno));
+ 				return rc;
+ 			}
+ 		}
+
+commit 4fae3c22407e283bdd486fb5d97bf6174b805e6e
+Author: jklowden <jklowden>
+Date:   Sat Dec 20 06:01:26 2008 +0000
+
+    sort header files for readability
+
+diff --git a/configure.ac b/configure.ac
+index 1e37fdf..f49be71 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.37 2008/05/28 13:44:19 jklowden Exp $
++dnl $Id: configure.ac,v 1.38 2008/12/20 06:01:26 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.37 $)
++AC_REVISION($Revision: 1.38 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -238,12 +238,32 @@ AC_STRUCT_TIMEZONE
+ AC_CHECK_MEMBERS([struct tm.__tm_zone],,,[#include <sys/types.h>
+ #include <$ac_cv_struct_tm>
+ ])
+-AC_CHECK_HEADERS([unistd.h errno.h wchar.h sys/time.h sys/types.h \
+-sys/param.h sys/stat.h sys/wait.h limits.h locale.h odbcss.h readpassphrase.h \
+-signal.h libgen.h poll.h getopt.h])
++AC_CHECK_HEADERS([	errno.h \
++			getopt.h \
++			libgen.h \
++			limits.h \
++			locale.h \
++			odbcss.h \
++			poll.h \
++			readpassphrase.h \
++			signal.h \
++			sys/param.h \
++			sys/select.h \
++			sys/stat.h \
++			sys/time.h \
++			sys/types.h \
++			sys/wait.h \
++			unistd.h \
++			wchar.h ])
+ if test $tds_mingw = no; then
+-	AC_CHECK_HEADERS([sys/socket.h arpa/inet.h netdb.h netinet/in.h \
+-netinet/tcp.h paths.h sys/ioctl.h langinfo.h])
++    AC_CHECK_HEADERS([	arpa/inet.h \
++			langinfo.h \
++			netdb.h \
++			netinet/in.h \
++			netinet/tcp.h \
++			paths.h \
++			sys/ioctl.h \
++			sys/socket.h ])
+ fi
+ AC_HAVE_INADDR_NONE
+ 
+diff --git a/include/Makefile.am b/include/Makefile.am
+index e28fa70..2924983 100644
+--- a/include/Makefile.am
++++ b/include/Makefile.am
+@@ -1,26 +1,28 @@
+-AUTOMAKE_OPTIONS	=	1.5.3
++AUTOMAKE_OPTIONS =	1.5.3
+ 
+-include_HEADERS	=	bkpublic.h cspublic.h cstypes.h ctpublic.h \
++include_HEADERS	=	bkpublic.h \
++			cspublic.h cstypes.h ctpublic.h \
+ 			sqldb.h sqlfront.h \
+ 			sybdb.h sybfront.h \
+ 			syberror.h odbcss.h
+ 
+-nodist_include_HEADERS	=	tds_sysdep_public.h
++nodist_include_HEADERS	= tds_sysdep_public.h
+ 
+-noinst_HEADERS	=	tds_configs.h \
+-			tds_sysdep_private.h \
++noinst_HEADERS	=	ctlib.h \
++			dblib.h \
+ 			md4.h md5.h des.h hmac_md5.h \
+ 			replacements.h \
+-			tdsstring.h \
+-			tdsodbc.h \
+-			tdsiconv.h \
+-			dblib.h \
+-			ctlib.h \
+-			tdsthread.h \
+-			tdsbytes.h \
+ 			replacements/readpassphrase.h \
+ 			tds.h tdsver.h tdsconvert.h \
+-			tdssrv.h
++			tds_sysdep_private.h \
++			tdsbytes.h \
++			tdsiconv.h \
++			tdsodbc.h \
++			tdssrv.h \
++			tdsstring.h \
++			tdsthread.h \
++			tds_configs.h
++
+ 
+ DISTCLEANFILES	=	tds_sysdep_public.h freetds_sysconfdir.h
+ 
+
+commit d458192e8fd7ac4a2c825e9c14c00bcfd55d3706
+Author: jklowden <jklowden>
+Date:   Sat Dec 20 06:01:31 2008 +0000
+
+    HTML 4.0 strict output
+
+diff --git a/doc/userguide.dsl.in b/doc/userguide.dsl.in
+index 18c4894..0b73e6f 100644
+--- a/doc/userguide.dsl.in
++++ b/doc/userguide.dsl.in
+@@ -12,7 +12,7 @@
+ ;; See Chapter 3, "Customizing the Stylesheets"
+ ;; http://docbook.sourceforge.net/release/dsssl/current/doc/custom.html
+ 
+-;; $Id: userguide.dsl.in,v 1.3 2008/08/15 04:47:05 jklowden Exp $
++;; $Id: userguide.dsl.in,v 1.4 2008/12/20 06:01:31 jklowden Exp $
+ 
+ ;; For note, tip, and warning: include little
+ ;; gifs of a hand pointing a finger, or a yield sign, and so on.  
+@@ -51,6 +51,37 @@
+   ;; Generate HTML 4.0
+   #t)
+ 
++(define %html-pubid%
++  ;; REFENTRY html-pubid
++  ;; PURP What public ID are you declaring your HTML compliant with?
++  ;; DESC
++  ;; The public ID used in output HTML files.  If '#f', then no public ID
++  ;; is produced.  If both this and %html-sysid% are '#f', then no
++  ;; doctype declaration is produced.
++  ;; /DESC
++  ;; AUTHOR N/A
++  ;; /REFENTRY
++  (if %html40%
++	;; "-//W3C//DTD HTML 4.01 Transitional//EN"
++	   "-//W3C//DTD HTML 4.01//EN"
++      #f))
++
++(define %html-sysid%
++  ;; REFENTRY html-sysid
++  ;; PURP What system ID are you declaring your HTML compliant with?
++  ;; DESC
++  ;; The system ID used in output HTML files.  If '#f', then no system ID
++  ;; is produced.  If both this and %html-pubid% are '#f', then no
++  ;; doctype declaration is produced.
++  ;; /DESC
++  ;; AUTHOR N/A
++  ;; /REFENTRY
++  (if %html40%
++      	;; "http://www.w3.org/TR/html4/loose.dtd"
++	   "http://www.w3.org/TR/html4/strict.dtd"
++      #f))
++
++
+ ;; Insert meta tag with encoding information into each generated HTML file.
+ ;; cf. http://www.dpawson.co.uk/docbook/dsssl/dssslgeneral.html 
+ 
+
+commit e9ca746085f9b34805ad759be5baeeb2f2658057
+Author: jklowden <jklowden>
+Date:   Sat Dec 20 06:01:41 2008 +0000
+
+    minor updates
+
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 30ab1e5..c759cd2 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/12/10 23:27:09 $</date>
+-		<releaseinfo>$Revision: 1.119 $</releaseinfo>
++		<date>$Date: 2008/12/20 06:01:41 $</date>
++		<releaseinfo>$Revision: 1.120 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.119 $</>
+-<member>$Date: 2008/12/10 23:27:09 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.119 2008/12/10 23:27:09 jklowden Exp $.</>
++<member>$Revision: 1.120 $</>
++<member>$Date: 2008/12/20 06:01:41 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.120 2008/12/20 06:01:41 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/12/10 23:27:09 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2008/12/20 06:01:41 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -2774,7 +2774,7 @@ If this fails, FreeTDS is either not finding your <filename>freetds.conf</filena
+ <prompt>$ </prompt><userinput>export TDSDUMP=/tmp/freetds.log</userinput>
+ </screen>
+ Will generate a log file named <filename>freetds.log</filename> in the <filename>/tmp</filename> directory.  
+-			<tip><para> The filenames <filename>stdout</> and <filename>stderr</> are also supported.  They can be handy if you want o interpserse the log output with your application's output, or if your application opens more than one connection.  (The logfile is otherwise normally truncatated each time the library connects to the server.) </para></tip>
++			<tip><para> The filenames <filename>stdout</> and <filename>stderr</> are also supported.  They can be handy if you want to intersperse the log output with your application's output, or if your application opens more than one connection.  (The logfile is otherwise normally truncatated each time the library connects to the server.) </para></tip>
+ 			</para>
+ 		</listitem>
+ 	</varlistentry>	
+@@ -2791,7 +2791,7 @@ obtained, e.g. from environment variables, a <filename>freetds.conf</filename> f
+ 
+ 			<tip><para>
+ What if you were running <productname>Apache</productname>/PHP?  <productname>Apache</productname> has many children.
+-Setting the <envar>TDSDUMP</envar> variable to a null string will cause <productname>FreeTDS</productname> to open a log under every PID.
++Setting the <envar>TDSDUMP</envar> (and/or <envar>TDSDUMPCONFIG</envar>) variable to a null string will cause <productname>FreeTDS</productname> to open a log under every PID.
+ <screen>
+ <prompt>$ </prompt><userinput>export TDSDUMP=""</userinput>
+ </screen>
+
+commit f7785eb3acabc35f470ae49eb2dc7af184c99c46
+Author: jklowden <jklowden>
+Date:   Sat Dec 20 06:01:47 2008 +0000
+
+    added fakepoll
+
+diff --git a/src/replacements/Makefile.am b/src/replacements/Makefile.am
+index 7ff6a92..ab13b33 100644
+--- a/src/replacements/Makefile.am
++++ b/src/replacements/Makefile.am
+@@ -1,8 +1,15 @@
+-# $Id: Makefile.am,v 1.13 2006/06/14 15:30:13 freddy77 Exp $
+-AM_CPPFLAGS=			-I$(top_srcdir)/include
++# $Id: Makefile.am,v 1.14 2008/12/20 06:01:47 jklowden Exp $
++AM_CPPFLAGS=			-I$(top_srcdir)/include -I$(top_srcdir)/src/replacements
+ noinst_LTLIBRARIES=		libreplacements.la
+-libreplacements_la_SOURCES=	iconv.c gettimeofday.c
++libreplacements_la_SOURCES=	iconv.c gettimeofday.c fakepoll.c fakepoll.h
+ libreplacements_la_LDFLAGS=
+ libreplacements_la_LIBADD=	@LTLIBOBJS@
+-EXTRA_DIST=			asprintf.c vasprintf.c atoll.c strtok_r.c \
+-	readpassphrase.c basename.c strlcpy.c strlcat.c
++EXTRA_DIST=	asprintf.c \
++		atoll.c \
++		basename.c \
++		readpassphrase.c \
++		strlcat.c \
++		strlcpy.c \
++		strtok_r.c \
++		vasprintf.c 
++
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+new file mode 100644
+index 0000000..b49abbd
+--- /dev/null
++++ b/src/replacements/fakepoll.c
+@@ -0,0 +1,167 @@
++#ifndef HAVE_POLL
++/*
++ * poll(2) implemented with select(2), for systems without poll(2). 
++ * Warning: a call to this poll() takes about 4K of stack space.
++ *
++ * This file and the accompanying fakepoll.h  
++ * are based on fakepoll.h in C++ by 
++ * 
++ * Greg Parker	 gparker-web@sealiesoftware.com     December 2000
++ * This code is in the public domain. 
++ *
++ * Updated May 2002: 
++ * * fix crash when an fd is less than 0
++ * * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
++ * * don't set POLLIN or POLLOUT in revents if it wasn't requested 
++ *   in events (only happens when an fd is in the poll set twice)
++ *
++ * Converted to C and spruced up by James K. Lowden December 2008. 
++ */
++
++static char software_version[] = "$Id: fakepoll.c,v 1.1 2008/12/20 06:01:47 jklowden Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++#include "fakepoll.h"
++
++#if HAVE_SYS_TYPES_H
++#include <sys/types.h>
++#endif /* HAVE_SYS_TYPES_H */
++
++#if HAVE_ERRNO_H
++#include <errno.h>
++#endif /* HAVE_ERRNO_H */
++
++#if HAVE_UNISTD_H
++#include <unistd.h>
++#endif /* HAVE_UNISTD_H */
++
++#if TIME_WITH_SYS_TIME
++# if HAVE_SYS_TIME_H
++#  include <sys/time.h>
++# endif
++# include <time.h>
++#else
++# if HAVE_SYS_TIME_H
++#  include <sys/time.h>
++# else
++#  include <time.h>
++# endif
++#endif
++
++#include <string.h>
++#include <assert.h>
++
++int
++fakepoll(struct pollfd fds[], int nfds, int timeout)
++{
++	struct timeval tv, *tvp;
++	fd_set fdsr, fdsw, fdsp;
++	struct pollfd *p;
++	const struct pollfd *endp = fds? fds + nfds : NULL;
++	int selected, polled = 0, maxfd = 0;
++
++	if (fds == NULL) {
++		errno = EFAULT;
++		return -1;
++	}
++
++	FD_ZERO(&fdsr);
++	FD_ZERO(&fdsw);
++	FD_ZERO(&fdsp);
++
++	/* 
++	 * Transcribe flags from the poll set to the fd sets. 
++	 * Also ensure we don't exceed select's capabilities. 
++	 */
++	for (p = fds; p < endp; p++) {
++		/* Negative fd checks nothing and always reports zero */
++		if (p->fd < 0) {
++			continue;
++		} 
++
++		if (p->fd > maxfd)
++			maxfd = p->fd;
++
++		/* POLLERR is never set coming in; poll(2) always reports errors */
++		/* But don't report if we're not listening to anything at all. */
++		if (p->events & POLLIN)
++			FD_SET(p->fd, &fdsr);
++		if (p->events & POLLOUT)
++			FD_SET(p->fd, &fdsw);
++		if (p->events != 0)
++			FD_SET(p->fd, &fdsp);
++	}
++
++	/* 
++	 * If any FD is too big for select(2), we need to return an error. 
++	 * Which one, though, is debatable.  There's no defined errno for 
++	 * this for poll(2) because it's an "impossible" condition; 
++	 * there's no such thing as "too many" FD's to check.  
++	 * select(2) returns EINVAL, and so do we.  
++	 * EFAULT might be better.
++	 */ 
++	if (maxfd > FD_SETSIZE) {
++		assert(FD_SETSIZE > 0);
++		errno = EINVAL;
++		return -1;
++	}
++
++	/*
++	 * poll timeout is in milliseconds. Convert to struct timeval.
++	 *      timeout == -1: wait forever : select timeout of NULL
++	 *      timeout ==  0: return immediately : select timeout of zero
++	 */
++	if (timeout >= 0) {
++		tv.tv_sec = timeout / 1000;
++		tv.tv_usec = (timeout % 1000) * 1000;
++		tvp = &tv;
++	} else {
++		tvp = NULL;
++	}
++
++	/* 
++	 * call select(2) 
++	 */
++	if ((selected = select(maxfd+1, &fdsr, &fdsw, &fdsp, tvp)) < 0) {
++		return -1; /* error */
++	}
++	
++	/* timeout, clear all result bits and return zero. */
++	if (selected == 0) {	
++		for (p = fds; p < endp; p++) {
++			p->revents = 0;
++		}
++		return 0;
++	}
++
++	/*
++	 * Select found something
++	 * Transcribe result from fd sets to poll set.
++	 * Return the number of ready fds.
++	 */
++	for (polled=0, p=fds; p < endp; p++) {
++		p->revents = 0;
++		/* Negative fd always reports zero */
++		if (p->fd < 0) {
++			continue;
++		}
++		
++		if ((p->events & POLLIN) && FD_ISSET(p->fd, &fdsr)) {
++			p->revents |= POLLIN;
++		}
++		if ((p->events & POLLOUT) && FD_ISSET(p->fd, &fdsw)) {
++			p->revents |= POLLOUT;
++		}
++		if ((p->events != 0) && FD_ISSET(p->fd, &fdsp)) {
++			p->revents |= POLLERR;
++		}
++
++		if (p->revents)
++			polled++;
++	}
++	
++	assert(polled == selected);
++
++	return polled;
++}
++#endif /* HAVE_POLL */
+diff --git a/src/replacements/fakepoll.h b/src/replacements/fakepoll.h
+new file mode 100644
+index 0000000..d40518d
+--- /dev/null
++++ b/src/replacements/fakepoll.h
+@@ -0,0 +1,51 @@
++/* $Id: fakepoll.h,v 1.1 2008/12/20 06:01:47 jklowden Exp $ */
++#if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
++#define _FAKE_POLL_H
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif 
++
++
++#if HAVE_LIMITS_H
++#include <limits.h>
++#endif 
++
++#if HAVE_SYS_SELECT_H
++#include <sys/select.h>
++#endif 
++
++#if !defined(FD_SETSIZE)
++# if !defined(OPEN_MAX)
++# error cannot establish FD_SETSIZE
++# endif
++#define FD_SETSIZE OPEN_MAX
++#endif
++
++// poll flags
++#define POLLIN  0x0001
++#define POLLOUT 0x0004
++#define POLLERR 0x0008
++
++// synonyms
++#define POLLNORM POLLIN
++#define POLLPRI POLLIN
++#define POLLRDNORM POLLIN
++#define POLLRDBAND POLLIN
++#define POLLWRNORM POLLOUT
++#define POLLWRBAND POLLOUT
++
++// ignored
++#define POLLHUP 0x0010
++#define POLLNVAL 0x0020
++
++typedef struct pollfd {
++    int fd;		/* file descriptor to poll */
++    short events;	/* events of interest on fd */
++    short revents;	/* events that occurred on fd */
++} pollfd_t;
++
++
++int fakepoll(struct pollfd fds[], int nfds, int timeout);
++
++#endif
+
+commit 29a67ae7bca4f2b00f61065ad9424e7e811e95ed
+Author: freddy77 <freddy77>
+Date:   Sat Dec 20 19:11:54 2008 +0000
+
+    fix win32 portability issue
+
+diff --git a/ChangeLog b/ChangeLog
+index 403bef7..5333c55 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Dec 20 20:11:46 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/fakepoll.c: fix win32 portability issue
++
+ Sat Dec 20 00:52:51 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/login.c src/tds/mem.c src/tds/net.c
+ 	- initialize tds_login at allocation, not connection
+@@ -1129,4 +1132,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2694 2008/12/20 06:01:21 jklowden Exp $
++$Id: ChangeLog,v 1.2695 2008/12/20 19:11:54 freddy77 Exp $
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index b49abbd..e48cd58 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -18,7 +18,7 @@
+  * Converted to C and spruced up by James K. Lowden December 2008. 
+  */
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.1 2008/12/20 06:01:47 jklowden Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.2 2008/12/20 19:11:54 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include "fakepoll.h"
+@@ -79,8 +79,10 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			continue;
+ 		} 
+ 
++#if !defined(WIN32)
+ 		if (p->fd > maxfd)
+ 			maxfd = p->fd;
++#endif
+ 
+ 		/* POLLERR is never set coming in; poll(2) always reports errors */
+ 		/* But don't report if we're not listening to anything at all. */
+@@ -92,6 +94,7 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			FD_SET(p->fd, &fdsp);
+ 	}
+ 
++#if !defined(WIN32)
+ 	/* 
+ 	 * If any FD is too big for select(2), we need to return an error. 
+ 	 * Which one, though, is debatable.  There's no defined errno for 
+@@ -105,6 +108,7 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
++#endif
+ 
+ 	/*
+ 	 * poll timeout is in milliseconds. Convert to struct timeval.
+
+commit 2bde05b4f7dd9b0845bd3efc3befda11eb0ddfa3
+Author: freddy77 <freddy77>
+Date:   Sat Dec 20 19:13:41 2008 +0000
+
+    fix small problem with small comments
+
+diff --git a/ChangeLog b/ChangeLog
+index 5333c55..66f10b3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Dec 20 20:13:33 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/commit: fix small problem with small comments
++
+ Sat Dec 20 20:11:46 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/fakepoll.c: fix win32 portability issue
+ 
+@@ -1132,4 +1135,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2695 2008/12/20 19:11:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2696 2008/12/20 19:13:41 freddy77 Exp $
+diff --git a/misc/commit b/misc/commit
+index 5b0ea28..77afdf8 100755
+--- a/misc/commit
++++ b/misc/commit
+@@ -1,6 +1,6 @@
+ #!/usr/bin/perl
+ 
+-# $Id: commit,v 1.2 2008/12/19 19:22:17 freddy77 Exp $
++# $Id: commit,v 1.3 2008/12/20 19:13:41 freddy77 Exp $
+ 
+ use strict;
+ 
+@@ -20,7 +20,7 @@ die("cvs commit message required\n") if $cvsMessage eq '';
+ die('setting local') if $?;
+ 
+ # extract file changed
+-open(CHANGES, 'cvs diff 2> /dev/null | lsdiff |') or die('gettting file changed');
++open(CHANGES, 'cvs diff 2> /dev/null | lsdiff |') or die('getting files changed');
+ my %changes;
+ while(<CHANGES>) {
+ 	chomp;
+@@ -152,7 +152,7 @@ my @allFiles = ('ChangeLog');
+ foreach my $ch (@changeLog) {
+ 	push @allFiles, @{$ch->{files}};
+ 	my $files = join(' ', @{$ch->{files}});
+-	my $oneLine = "* $files: $ch->{comments}";
++	my $oneLine = "* $files: @{$ch->{comments}}";
+ 	if (scalar @{$ch->{comments}} == 1 && length($oneLine) + 8 <= $lineLimit) {
+ 		$norm .= "\t$oneLine\n"
+ 	} else {
+
+commit 748ae964f6fe39d07b88830201de268a16b9694b
+Author: freddy77 <freddy77>
+Date:   Sat Dec 20 19:16:31 2008 +0000
+
+    fix quite impossible memory leak
+
+diff --git a/ChangeLog b/ChangeLog
+index 66f10b3..8955590 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Dec 20 20:16:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: fix quite impossible memory leak
++
+ Sat Dec 20 20:13:33 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/commit: fix small problem with small comments
+ 
+@@ -1135,4 +1138,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2696 2008/12/20 19:13:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2697 2008/12/20 19:16:31 freddy77 Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index b0edbf7..730f70d 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.183 2008/12/20 06:01:21 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.184 2008/12/20 19:16:31 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -948,7 +948,7 @@ tds_release_cursor(TDSSOCKET *tds, TDSCURSOR *cursor)
+ TDSLOGIN *
+ tds_alloc_login(void)
+ {
+-	TDSLOGIN *tds_login;
++	TDSLOGIN *tds_login = NULL;
+ 	const char *server_name = "SYBASE";
+ 	char *s;
+ 	
+@@ -970,12 +970,14 @@ tds_alloc_login(void)
+ 	if ((s=getenv("TDSQUERY")) != NULL)
+ 		server_name = s;
+ 
+-	tds_dstr_copy(&tds_login->server_name, server_name);
++	if (!tds_dstr_copy(&tds_login->server_name, server_name))
++		goto Cleanup;
+ 	memcpy(tds_login->capabilities, defaultcaps, TDS_MAX_CAPABILITY);
+ 
+ 	return tds_login;
+ 
+       Cleanup:
++	free(tds_login);
+ 	return NULL;
+ }
+ 
+
+commit 5ee5fd86ae5bbe6b6fb101c9d34fc7e7578d007d
+Author: freddy77 <freddy77>
+Date:   Sat Dec 20 19:30:55 2008 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index 8955590..a43d709 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Dec 20 20:30:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: remove warning
++
+ Sat Dec 20 20:16:20 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/mem.c: fix quite impossible memory leak
+ 
+@@ -1138,4 +1141,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2697 2008/12/20 19:16:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2698 2008/12/20 19:30:55 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 2536db0..f654480 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.82 2008/12/20 06:01:22 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.83 2008/12/20 19:30:55 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -926,7 +926,7 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 					if( *p == ';' )
+ 						*p = *sep;
+ 				}
+-				fprintf(output, msg + 3);
++				fputs(msg + 3, output);
+ 			}
+ 
+ 			/*
+
+commit b85c6268313e05ee9544841413cba83aa4068f42
+Author: freddy77 <freddy77>
+Date:   Mon Dec 22 15:33:55 2008 +0000
+
+    use strtok_r instead of strtok
+
+diff --git a/ChangeLog b/ChangeLog
+index a43d709..4360348 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Dec 22 16:32:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: use strtok_r instead of strtok
++
+ Sat Dec 20 20:30:47 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: remove warning
+ 
+@@ -1141,4 +1144,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2698 2008/12/20 19:30:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2699 2008/12/22 15:33:55 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index f654480..1a35c6e 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.83 2008/12/20 19:30:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.84 2008/12/22 15:33:55 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -913,7 +913,7 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 
+ 		/* got data, read and parse */
+ 		if ((msg_len = recv(s, msg, sizeof(msg) - 1, 0)) > 3 && msg[0] == 5) {
+-			char *name, sep[2] = ";";
++			char *name, sep[2] = ";", *save;
+ 
+ 			/* assure null terminated */
+ 			msg[msg_len] = 0;
+@@ -932,14 +932,14 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 			/*
+ 			 * Parse and print message.
+ 			 */
+-			name = strtok(msg+3, sep);
++			name = strtok_r(msg+3, sep, &save);
+ 			while (name && output) {
+ 				int i;
+ 				static const char *names[] = { "ServerName", "InstanceName", "IsClustered", "Version", 
+ 							       "tcp", "np", "via" };
+-				
++
+ 				for (i=0; name && i < TDS_VECTOR_SIZE(names); i++) {
+-					const char *value = strtok(NULL, sep);
++					const char *value = strtok_r(NULL, sep, &save);
+ 					
+ 					if (strcmp(name, names[i]) != 0)
+ 						fprintf(output, "error: expecting '%s', found '%s'\n", names[i], name);
+@@ -948,8 +948,8 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 					else 
+ 						break;
+ 
+-					name = strtok(NULL, sep);
+-					
++					name = strtok_r(NULL, sep, &save);
++
+ 					if (name && strcmp(name, names[0]) == 0)
+ 						break;
+ 				}
+
+commit 85eab7e15b836feda1df78f73c92659275c19ce4
+Author: freddy77 <freddy77>
+Date:   Fri Dec 26 12:20:50 2008 +0000
+
+    cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index 4360348..fe597fe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Dec 26 13:20:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: cleanup
++
+ Mon Dec 22 16:32:17 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: use strtok_r instead of strtok
+ 
+@@ -1144,4 +1147,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2699 2008/12/22 15:33:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2700 2008/12/26 12:20:50 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 1633264..4c38ffe 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -3,41 +3,14 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.14 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.15 2008/12/26 12:20:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define CHECK_RCODE(t,h,m) \
+-   if ( RetCode != SQL_SUCCESS && RetCode != SQL_SUCCESS_WITH_INFO && RetCode != SQL_NO_DATA && RetCode != SQL_NEED_DATA ) { \
+-      fprintf(stderr,"Error %d at: %s\n",RetCode,m); \
+-      getErrorInfo(t,h); \
+-      exit(1); \
+-   }
+-
+ #define NBYTES 10000
+ 
+ static int failed = 0;
+ 
+ static void
+-getErrorInfo(SQLSMALLINT sqlhdltype, SQLHANDLE sqlhandle)
+-{
+-	SQLCHAR sqlstate[SQL_SQLSTATE_SIZE + 1];
+-	SQLINTEGER naterror = 0;
+-	SQLCHAR msgtext[SQL_MAX_MESSAGE_LENGTH + 1];
+-	SQLSMALLINT msgtextl = 0;
+-
+-	SQLGetDiagRec((SQLSMALLINT) sqlhdltype,
+-			      (SQLHANDLE) sqlhandle,
+-			      (SQLSMALLINT) 1,
+-			      (SQLCHAR *) sqlstate,
+-			      (SQLINTEGER *) & naterror,
+-			      (SQLCHAR *) msgtext, (SQLSMALLINT) sizeof(msgtext), (SQLSMALLINT *) & msgtextl);
+-	fprintf(stderr, "Diagnostic info:\n");
+-	fprintf(stderr, "  SQL State: %s\n", (char *) sqlstate);
+-	fprintf(stderr, "  SQL code : %d\n", (int) naterror);
+-	fprintf(stderr, "  Message  : %s\n", (char *) msgtext);
+-}
+-
+-static void
+ fill_chars(char *buf, size_t len, unsigned int start, unsigned int step)
+ {
+ 	size_t n;
+@@ -83,7 +56,7 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ 	return 1;
+ }
+ 
+-static int
++static void
+ readBlob(SQLUSMALLINT pos)
+ {
+ 	SQLRETURN rc;
+@@ -114,10 +87,9 @@ readBlob(SQLUSMALLINT pos)
+ 	printf(">>   total bytes read = %d \n", (int) total);
+ 	if (total != 10000)
+ 		failed = 1;
+-	return rc;
+ }
+ 
+-static int
++static void
+ readBlobAsChar(SQLUSMALLINT pos, int step)
+ {
+ 	SQLRETURN rc = SQL_SUCCESS_WITH_INFO;
+@@ -151,7 +123,6 @@ readBlobAsChar(SQLUSMALLINT pos, int step)
+ 	printf(">>   total bytes read = %d \n", (int) total);
+ 	if (total != 20000)
+ 		failed = 1;
+-	return rc;
+ }
+ 
+ 
+@@ -266,12 +237,9 @@ main(int argc, char **argv)
+ 		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
+ 		printf(">> fetch... %d\n", i);
+ 
+-		RetCode = readBlob(1);
+-		CHECK_RCODE(SQL_HANDLE_STMT, Statement, "readBlob 1");
+-		RetCode = readBlob(2);
+-		CHECK_RCODE(SQL_HANDLE_STMT, Statement, "readBlob 2");
+-		RetCode = readBlobAsChar(3, i);
+-		CHECK_RCODE(SQL_HANDLE_STMT, Statement, "readBlob 3 as SQL_C_CHAR");
++		readBlob(1);
++		readBlob(2);
++		readBlobAsChar(3, i);
+ 
+ 		CHKCloseCursor("S");
+ 		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+
+commit e5e4e60376e679474ebb5e4ef2ff13b7d60bc4ce
+Author: jklowden <jklowden>
+Date:   Sat Dec 27 21:48:36 2008 +0000
+
+    different approach to Win32 compatibility
+
+diff --git a/ChangeLog b/ChangeLog
+index fe597fe..7029d9b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Dec 27 16:47:40 EST 2008	JK Lowden <jklowden@freetds.org>
++	* src/replacements/fakepoll.c src/replacements/fakepoll.h
++	- different approach to Win32 compatibility
++
+ Fri Dec 26 13:20:39 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: cleanup
+ 
+@@ -1147,4 +1151,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2700 2008/12/26 12:20:50 freddy77 Exp $
++$Id: ChangeLog,v 1.2701 2008/12/27 21:48:36 jklowden Exp $
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index e48cd58..14a1df6 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -18,7 +18,7 @@
+  * Converted to C and spruced up by James K. Lowden December 2008. 
+  */
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.2 2008/12/20 19:11:54 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.3 2008/12/27 21:48:36 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include "fakepoll.h"
+@@ -79,10 +79,8 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			continue;
+ 		} 
+ 
+-#if !defined(WIN32)
+ 		if (p->fd > maxfd)
+ 			maxfd = p->fd;
+-#endif
+ 
+ 		/* POLLERR is never set coming in; poll(2) always reports errors */
+ 		/* But don't report if we're not listening to anything at all. */
+@@ -94,7 +92,10 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			FD_SET(p->fd, &fdsp);
+ 	}
+ 
+-#if !defined(WIN32)
++#if defined(WIN32)
++	/* Win32 cares about the number of desciptors, not the highest one. */
++	maxfd = nfds;
++#endif
+ 	/* 
+ 	 * If any FD is too big for select(2), we need to return an error. 
+ 	 * Which one, though, is debatable.  There's no defined errno for 
+@@ -108,7 +109,6 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
+-#endif
+ 
+ 	/*
+ 	 * poll timeout is in milliseconds. Convert to struct timeval.
+diff --git a/src/replacements/fakepoll.h b/src/replacements/fakepoll.h
+index d40518d..569b485 100644
+--- a/src/replacements/fakepoll.h
++++ b/src/replacements/fakepoll.h
+@@ -1,4 +1,4 @@
+-/* $Id: fakepoll.h,v 1.1 2008/12/20 06:01:47 jklowden Exp $ */
++/* $Id: fakepoll.h,v 1.2 2008/12/27 21:48:36 jklowden Exp $ */
+ #if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
+ #define _FAKE_POLL_H
+ 
+@@ -15,6 +15,10 @@
+ #include <sys/select.h>
+ #endif 
+ 
++#if defined(WIN32)
++#include <winsock2.h>
++#endif
++
+ #if !defined(FD_SETSIZE)
+ # if !defined(OPEN_MAX)
+ # error cannot establish FD_SETSIZE
+
+commit 03d510ca1f189bff9b198e7ea5392db8ff008851
+Author: freddy77 <freddy77>
+Date:   Mon Dec 29 17:08:12 2008 +0000
+
+    fix typo in comment
+
+diff --git a/ChangeLog b/ChangeLog
+index 7029d9b..f9b3a96 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Dec 29 18:08:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/fakepoll.c: fix typo in comment
++
+ Sat Dec 27 16:47:40 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* src/replacements/fakepoll.c src/replacements/fakepoll.h
+ 	- different approach to Win32 compatibility
+@@ -1151,4 +1154,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2701 2008/12/27 21:48:36 jklowden Exp $
++$Id: ChangeLog,v 1.2702 2008/12/29 17:08:12 freddy77 Exp $
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index 14a1df6..0b023b5 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -18,7 +18,7 @@
+  * Converted to C and spruced up by James K. Lowden December 2008. 
+  */
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.3 2008/12/27 21:48:36 jklowden Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.4 2008/12/29 17:08:12 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include "fakepoll.h"
+@@ -93,7 +93,7 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 	}
+ 
+ #if defined(WIN32)
+-	/* Win32 cares about the number of desciptors, not the highest one. */
++	/* Win32 cares about the number of descriptors, not the highest one. */
+ 	maxfd = nfds;
+ #endif
+ 	/* 
+
+commit 7e9f8b8fd2c3ad96c9ab82af6500a19978fd8650
+Author: freddy77 <freddy77>
+Date:   Sat Jan 3 14:56:53 2009 +0000
+
+    check win32 maxfd in a different way
+
+diff --git a/ChangeLog b/ChangeLog
+index f9b3a96..2156a6d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan  3 15:56:46 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/fakepoll.c: check win32 maxfd in a different way
++
+ Mon Dec 29 18:08:00 CET 2008    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/fakepoll.c: fix typo in comment
+ 
+@@ -1154,4 +1157,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2702 2008/12/29 17:08:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2703 2009/01/03 14:56:53 freddy77 Exp $
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index 0b023b5..3685092 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -18,7 +18,7 @@
+  * Converted to C and spruced up by James K. Lowden December 2008. 
+  */
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.4 2008/12/29 17:08:12 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.5 2009/01/03 14:56:53 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include "fakepoll.h"
+@@ -79,8 +79,13 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			continue;
+ 		} 
+ 
++#if defined(WIN32)
++		/* Win32 cares about the number of descriptors, not the highest one. */
++		++maxfd;
++#else
+ 		if (p->fd > maxfd)
+ 			maxfd = p->fd;
++#endif
+ 
+ 		/* POLLERR is never set coming in; poll(2) always reports errors */
+ 		/* But don't report if we're not listening to anything at all. */
+@@ -92,10 +97,6 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			FD_SET(p->fd, &fdsp);
+ 	}
+ 
+-#if defined(WIN32)
+-	/* Win32 cares about the number of descriptors, not the highest one. */
+-	maxfd = nfds;
+-#endif
+ 	/* 
+ 	 * If any FD is too big for select(2), we need to return an error. 
+ 	 * Which one, though, is debatable.  There's no defined errno for 
+
+commit 9dbec0624fec850b54b7901ba1e9c91f02feb061
+Author: jklowden <jklowden>
+Date:   Sat Jan 3 15:26:09 2009 +0000
+
+    support SYBUNIQUE and SYBIMAGE
+
+diff --git a/ChangeLog b/ChangeLog
+index 2156a6d..b3b87fb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jan  3 10:25:24 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/tds/convert.c src/tds/tds_willconvert.pl
++	- support SYBUNIQUE and SYBIMAGE
++
+ Sat Jan  3 15:56:46 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/fakepoll.c: check win32 maxfd in a different way
+ 
+@@ -1157,4 +1161,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2703 2009/01/03 14:56:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2704 2009/01/03 15:26:09 jklowden Exp $
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index c589476..a9694c5 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.185 2008/10/29 08:42:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.186 2009/01/03 15:26:09 jklowden Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -2844,6 +2844,7 @@ tds_willconvert(int srctype, int desttype)
+ 	/* non-fixed types have variable data sizes, just return 0xff */
+ 	case SYBCHAR:
+ 	case SYBBINARY:
++	case SYBIMAGE:
+ 	case SYBLONGBINARY:
+ 	case SYBLONGCHAR:
+ 	case SYBTEXT:
+diff --git a/src/tds/tds_willconvert.pl b/src/tds/tds_willconvert.pl
+index a695b51..a153685 100755
+--- a/src/tds/tds_willconvert.pl
++++ b/src/tds/tds_willconvert.pl
+@@ -1,35 +1,33 @@
+ #!perl
+ 
+-$indent = "\t ";
++printf qq(/* %s */\n), '($Id: tds_willconvert.pl,v 1.3 2009/01/03 15:26:09 jklowden Exp $)';
+ printf qq(/*** %-67s ***/\n), "Please do not edit this file!";
+ printf qq(/*** %-67s ***/\n), "It was generated with 'perl tds_willconvert.pl > tds_willconvert.h'";
+ printf qq(/*** %-67s ***/\n), "It is much easier to edit the __DATA__ table than this file.  ";
+ printf qq(/*** %-67s ***/\n), " ";
+ printf qq(/*** %67s ***/\n\n), "Thank you.";
+ 
++%yn = 	( T => 1
++	, t => 0	# should be true, but not yet implemented.
++	, F => 0
++	);
++
++$indent = "\t ";
++
+ while(<DATA>) {
+-	next if /^\s+To\s+$/;
++	next if /^\s+To\s*$/;
+ 	next if /^From/;
+ 	if( /^\s+VARCHAR CHAR/ ) {
+ 		@to = split;
+ 		next;
+ 	}
+-	last if /^BOUNDARY/;
++	last if /^\s*$/;
+ 
+ 	@yn = split;
+ 	$from = shift @yn;
+ 	$i = 0;
+ 	foreach $to (@to) {
+-		last if $to =~ /^BOUNDARY/;
+-
+-		$yn = $yn[$i];	# default
+-		$yn = 1 if $yn[$i] eq 'T';
+-		$yn = 0 if $yn[$i] eq 'F';
+-		$yn = 0 if $yn[$i] eq 't';	# means it should be true, but isn't so far.
+-
+-		printf "$indent %-30.30s, %s", "{ SYB${from}, SYB${to}", "$yn }\n"; 
+-
+-		$i++;
++		printf "$indent %-35s, %s }\n", "{ SYB${from}, SYB${to}", $yn{$yn[$i++]}; 
+ 		$indent = "\t,";
+ 	}
+ }
+@@ -37,44 +35,26 @@ while(<DATA>) {
+ __DATA__
+           To
+ From
+-          VARCHAR CHAR TEXT BINARY VARBINARY IMAGE INT1 INT2 INT4 INT8 FLT8 REAL NUMERIC DECIMAL BIT MONEY MONEY4 DATETIME DATETIME4 BOUNDARY SENSITIVITY
+-VARCHAR     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T
+-CHAR        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T
+-TEXT        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T
+-BINARY      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-VARBINARY   T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-IMAGE       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-INT1        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-INT2        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-INT4        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-INT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-FLT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-REAL        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-NUMERIC     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-DECIMAL     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-BIT         T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-MONEY       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-MONEY4      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F
+-DATETIME    T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F
+-DATETIME4   T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F
+-BOUNDARY    T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     T        F
+-SENSITIVITY T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     F        T
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
+-
++          VARCHAR CHAR TEXT BINARY VARBINARY IMAGE INT1 INT2 INT4 INT8 FLT8 REAL NUMERIC DECIMAL BIT MONEY MONEY4 DATETIME DATETIME4 BOUNDARY UNIQUE SENSITIVITY
++VARCHAR     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
++CHAR        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
++TEXT        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  T	   T	     T        T        t
++BINARY      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++VARBINARY   T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++IMAGE       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++INT1        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++INT2        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++INT4        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++INT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++FLT8        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++REAL        T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++NUMERIC     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++DECIMAL     T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++BIT         T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++MONEY       T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++MONEY4      T      T   T    T	   T         T     T	T    T    T    T    T	 T	 T	 T   T     T	  F	   F	     F        F        F
++DATETIME    T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F        F
++DATETIME4   T      T   T    T	   T         T     F	F    F    F    F    F	 F	 F	 F   F     F	  T	   T	     F        F        F
++BOUNDARY    T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     T        F        F
++UNIQUE      T      T   T    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     F        T        F
++SENSITIVITY t      t   t    F	   F         F     F	F    F    F    F    F	 F	 F	 F   F     F	  F	   F	     F        F        t
+
+commit 4afe9204870d1aa18a9f5fada09ebb06941cba3e
+Author: jklowden <jklowden>
+Date:   Wed Jan 7 02:58:32 2009 +0000
+
+    src/replacements/fakepoll.h
+
+diff --git a/ChangeLog b/ChangeLog
+index b3b87fb..ca11e0b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Tue Jan  6 21:53:56 EST 2009	JK Lowden <jklowden@freetds.org>
++	* include/Makefile.am
++	* include/fakepoll.h  src/replacements/fakepoll.h
++	* include/replacements.h src/replacements/Makefile.am
++	- organized fakepoll like the other replacements
++	* src/apps/defncopy.c print numeric sized correctly
++	* src/tds/token.c minor logging 
++
+ Sat Jan  3 10:25:24 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/convert.c src/tds/tds_willconvert.pl
+ 	- support SYBUNIQUE and SYBIMAGE
+@@ -1161,4 +1169,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2704 2009/01/03 15:26:09 jklowden Exp $
++$Id: ChangeLog,v 1.2705 2009/01/07 02:58:32 jklowden Exp $
+diff --git a/include/Makefile.am b/include/Makefile.am
+index 2924983..a9de20b 100644
+--- a/include/Makefile.am
++++ b/include/Makefile.am
+@@ -10,6 +10,7 @@ nodist_include_HEADERS	= tds_sysdep_public.h
+ 
+ noinst_HEADERS	=	ctlib.h \
+ 			dblib.h \
++			fakepoll.h \
+ 			md4.h md5.h des.h hmac_md5.h \
+ 			replacements.h \
+ 			replacements/readpassphrase.h \
+diff --git a/include/fakepoll.h b/include/fakepoll.h
+new file mode 100644
+index 0000000..e81f9ad
+--- /dev/null
++++ b/include/fakepoll.h
+@@ -0,0 +1,55 @@
++/* $Id: fakepoll.h,v 1.1 2009/01/07 02:58:32 jklowden Exp $ */
++#if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
++#define _FAKE_POLL_H
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif 
++
++
++#if HAVE_LIMITS_H
++#include <limits.h>
++#endif 
++
++#if HAVE_SYS_SELECT_H
++#include <sys/select.h>
++#endif 
++
++#if defined(WIN32)
++#include <winsock2.h>
++#endif
++
++#if !defined(FD_SETSIZE)
++# if !defined(OPEN_MAX)
++# error cannot establish FD_SETSIZE
++# endif
++#define FD_SETSIZE OPEN_MAX
++#endif
++
++// poll flags
++#define POLLIN  0x0001
++#define POLLOUT 0x0004
++#define POLLERR 0x0008
++
++// synonyms
++#define POLLNORM POLLIN
++#define POLLPRI POLLIN
++#define POLLRDNORM POLLIN
++#define POLLRDBAND POLLIN
++#define POLLWRNORM POLLOUT
++#define POLLWRBAND POLLOUT
++
++// ignored
++#define POLLHUP 0x0010
++#define POLLNVAL 0x0020
++
++typedef struct pollfd {
++    int fd;		/* file descriptor to poll */
++    short events;	/* events of interest on fd */
++    short revents;	/* events that occurred on fd */
++} pollfd_t;
++
++
++int fakepoll(struct pollfd fds[], int nfds, int timeout);
++
++#endif
+
+commit ff3e026ef4c075559d2522f670a1a2ca0ebe4fda
+Author: jklowden <jklowden>
+Date:   Wed Jan 7 02:58:37 2009 +0000
+
+    organized fakepoll like the other replacements
+
+diff --git a/include/replacements.h b/include/replacements.h
+index 7bf761a..0756b1a 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.18 2007/12/21 09:06:53 freddy77 Exp $ */
++/* $Id: replacements.h,v 1.19 2009/01/07 02:58:37 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -46,11 +46,13 @@
+ #ifdef __cplusplus
+ extern "C"
+ {
+-#if 0
+-}
+-#endif
+ #endif
+ 
++#if !HAVE_POLL
++#include fakepoll.h
++#define poll(fds, nfds, timeout) fakepoll((fds), (nfds), (timeout))
++#endif /* !HAVE_POLL */
++
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef vsnprintf
+ #define vsnprintf _vsnprintf
+@@ -97,9 +99,6 @@ int gettimeofday (struct timeval *tv, void *tz);
+ #endif
+ 
+ #ifdef __cplusplus
+-#if 0
+-{
+-#endif
+ }
+ #endif
+ 
+diff --git a/src/replacements/Makefile.am b/src/replacements/Makefile.am
+index ab13b33..3d9e5e2 100644
+--- a/src/replacements/Makefile.am
++++ b/src/replacements/Makefile.am
+@@ -1,7 +1,7 @@
+-# $Id: Makefile.am,v 1.14 2008/12/20 06:01:47 jklowden Exp $
++# $Id: Makefile.am,v 1.15 2009/01/07 02:58:37 jklowden Exp $
+ AM_CPPFLAGS=			-I$(top_srcdir)/include -I$(top_srcdir)/src/replacements
+ noinst_LTLIBRARIES=		libreplacements.la
+-libreplacements_la_SOURCES=	iconv.c gettimeofday.c fakepoll.c fakepoll.h
++libreplacements_la_SOURCES=	iconv.c gettimeofday.c fakepoll.c
+ libreplacements_la_LDFLAGS=
+ libreplacements_la_LIBADD=	@LTLIBOBJS@
+ EXTRA_DIST=	asprintf.c \
+
+commit a5e94b47b3abb7afb0ceae8389beca2bf9d770bb
+Author: jklowden <jklowden>
+Date:   Wed Jan 7 02:58:47 2009 +0000
+
+    print numeric sized correctly
+
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index c1addcb..0f462ec 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -48,7 +48,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.12 2005/10/12 07:03:21 freddy77 Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.13 2009/01/07 02:58:47 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+@@ -223,6 +223,17 @@ parse_argument(const char argument[], PROCEDURE* procedure)
+ 	}
+ }
+ 
++char * rtrim(char * s);
++
++char *
++rtrim(char * s)
++{
++	char *p = strchr(s, ' ');
++	if (p) 
++		*p = '\0';
++	return s;
++}
++
+ /*
+  * Get the table information from sp_help, because it's easier to get the index information (eventually).  
+  * The column descriptions are in resultset #2, which is where we start.  
+@@ -409,8 +420,11 @@ print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure)
+ 
+ 		/* get size of decimal, numeric, char, and image types */
+ 		if (0 == strcasecmp("decimal", ddl[i].type) || 0 == strcasecmp("numeric", ddl[i].type)) {
+-			if (ddl[i].precision && 0 != strcasecmp("NULL", ddl[i].precision))
+-				ret = asprintf(&type, "%s(%d,%d)", ddl[i].type, *(int*)ddl[i].precision, *(int*)ddl[i].scale);
++			if (ddl[i].precision && 0 != strcasecmp("NULL", ddl[i].precision)) {
++				rtrim(ddl[i].precision);
++				rtrim(ddl[i].scale);
++				ret = asprintf(&type, "%s(%s,%s)", ddl[i].type, ddl[i].precision, ddl[i].scale);
++			}
+ 		} else {
+ 			for (t = varytypenames; *t; t++) {
+ 				if (0 == strcasecmp(*t, ddl[i].type)) {
+
+commit e14ebd3d57026546fd128edebc05d95370db3355
+Author: jklowden <jklowden>
+Date:   Wed Jan 7 02:58:54 2009 +0000
+
+    minor logging
+
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 33e3f9f..78b0258 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.357 2008/11/05 14:54:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.358 2009/01/07 02:58:54 jklowden Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2525,7 +2525,7 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 		return TDS_FAIL;
+ 	}
+ 
+-	tdsdump_log(TDS_DBG_ERROR, "tds_process_msg() reading message from server\n");
++	tdsdump_log(TDS_DBG_ERROR, "tds_process_msg() reading message %d from server\n", msg.msgno);
+ 	
+ 	rc = 0;
+ 	/* the message */
+
+commit deab49f7bbdacfb21186e0fa86533512ab345670
+Author: jklowden <jklowden>
+Date:   Fri Jan 9 04:59:58 2009 +0000
+
+    add LIBICONV to linker flags
+
+diff --git a/ChangeLog b/ChangeLog
+index ca11e0b..b899677 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jan  8 23:47:33 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am src/apps/fisql/Makefile.am
++	* src/replacements/fakepoll.h 
++	- add LIBICONV to linker flags
++
+ Tue Jan  6 21:53:56 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/Makefile.am
+ 	* include/fakepoll.h  src/replacements/fakepoll.h
+@@ -1169,4 +1174,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2705 2009/01/07 02:58:32 jklowden Exp $
++$Id: ChangeLog,v 1.2706 2009/01/09 04:59:58 jklowden Exp $
+diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
+index dd459c8..4545913 100644
+--- a/src/apps/Makefile.am
++++ b/src/apps/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.28 2008/12/11 12:31:31 freddy77 Exp $
++# $Id: Makefile.am,v 1.29 2009/01/09 04:59:58 jklowden Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -25,17 +25,19 @@ tsql_LDADD	= ../tds/libtds.la \
+ 
+ bsqldb_LDADD	= ../dblib/libsybdb.la \
+ 		  ../replacements/libreplacements.la \
+-		  $(NETWORK_LIBS)
++		  $(NETWORK_LIBS) $(LIBICONV)
+ 
+ if ODBC
+-bsqlodbc_LDADD	= $(ODBCLIB) $(ODBCNODMLIBAPP) \
+-		  ../replacements/libreplacements.la $(NETWORK_LIBS)
+ bsqlodbc_CPPFLAGS	= $(ODBC_INC) $(AM_CPPFLAGS)
++bsqlodbc_LDADD	= $(ODBCLIB) $(ODBCNODMLIBAPP) \
++		  ../replacements/libreplacements.la $(NETWORK_LIBS) $(LIBICONV)
+ endif
+ 
+ defncopy_LDADD	= ../dblib/libsybdb.la \
+ 		  ../replacements/libreplacements.la \
+-		  $(NETWORK_LIBS)
++		  $(NETWORK_LIBS) $(LIBICONV)
+ 
+ datacopy_SOURCES= datacopy.c
+-datacopy_LDADD	= ../dblib/libsybdb.la ../replacements/libreplacements.la $(NETWORK_LIBS)
++datacopy_LDADD	= ../dblib/libsybdb.la \
++		  ../replacements/libreplacements.la \
++		$(NETWORK_LIBS) $(LIBICONV)
+diff --git a/src/apps/fisql/Makefile.am b/src/apps/fisql/Makefile.am
+index 3bb30ad..048eeb4 100644
+--- a/src/apps/fisql/Makefile.am
++++ b/src/apps/fisql/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.3 2007/03/18 11:07:30 freddy77 Exp $
++# $Id: Makefile.am,v 1.4 2009/01/09 04:59:58 jklowden Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -6,6 +6,14 @@ if MINGW32
+ else
+ bin_PROGRAMS	= fisql
+ 
+-fisql_LDADD	= ../../dblib/libsybdb.la ../../replacements/libreplacements.la $(NETWORK_LIBS) $(READLINE_LIBS)
+-fisql_SOURCES	= fisql.c terminal.c terminal.h edit.c edit.h handlers.c handlers.h interrupt.c interrupt.h
++fisql_SOURCES	= fisql.c  \
++		terminal.h terminal.c  \
++		edit.h edit.c  \
++		handlers.h handlers.c  \
++		interrupt.h interrupt.c
++		
++
++fisql_LDADD	= ../../dblib/libsybdb.la \
++		  ../../replacements/libreplacements.la \
++		  $(NETWORK_LIBS) $(LIBICONV) $(READLINE_LIBS)
+ endif
+diff --git a/src/replacements/fakepoll.h b/src/replacements/fakepoll.h
+deleted file mode 100644
+index 569b485..0000000
+--- a/src/replacements/fakepoll.h
++++ /dev/null
+@@ -1,55 +0,0 @@
+-/* $Id: fakepoll.h,v 1.2 2008/12/27 21:48:36 jklowden Exp $ */
+-#if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
+-#define _FAKE_POLL_H
+-
+-#if HAVE_CONFIG_H
+-#include <config.h>
+-#endif 
+-
+-
+-#if HAVE_LIMITS_H
+-#include <limits.h>
+-#endif 
+-
+-#if HAVE_SYS_SELECT_H
+-#include <sys/select.h>
+-#endif 
+-
+-#if defined(WIN32)
+-#include <winsock2.h>
+-#endif
+-
+-#if !defined(FD_SETSIZE)
+-# if !defined(OPEN_MAX)
+-# error cannot establish FD_SETSIZE
+-# endif
+-#define FD_SETSIZE OPEN_MAX
+-#endif
+-
+-// poll flags
+-#define POLLIN  0x0001
+-#define POLLOUT 0x0004
+-#define POLLERR 0x0008
+-
+-// synonyms
+-#define POLLNORM POLLIN
+-#define POLLPRI POLLIN
+-#define POLLRDNORM POLLIN
+-#define POLLRDBAND POLLIN
+-#define POLLWRNORM POLLOUT
+-#define POLLWRBAND POLLOUT
+-
+-// ignored
+-#define POLLHUP 0x0010
+-#define POLLNVAL 0x0020
+-
+-typedef struct pollfd {
+-    int fd;		/* file descriptor to poll */
+-    short events;	/* events of interest on fd */
+-    short revents;	/* events that occurred on fd */
+-} pollfd_t;
+-
+-
+-int fakepoll(struct pollfd fds[], int nfds, int timeout);
+-
+-#endif
+
+commit 63ef4053645ad21fe92d4b9f427d5b22174aed5d
+Author: freddy77 <freddy77>
+Date:   Mon Jan 12 08:09:50 2009 +0000
+
+    make get_default_instance_port static
+
+diff --git a/ChangeLog b/ChangeLog
+index b899677..9eeb735 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 12 09:08:21 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/tsql.c: make get_default_instance_port static
++
+ Thu Jan  8 23:47:33 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/Makefile.am src/apps/fisql/Makefile.am
+ 	* src/replacements/fakepoll.h 
+@@ -1174,4 +1177,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2706 2009/01/09 04:59:58 jklowden Exp $
++$Id: ChangeLog,v 1.2707 2009/01/12 08:09:50 freddy77 Exp $
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 59fa741..455bf2d 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns
+- * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008, 2009  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.125 2008/12/16 09:21:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.126 2009/01/12 08:09:50 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -370,7 +370,7 @@ get_opt_flags(char *s, int *opt_flags)
+ 	return 1;
+ }
+ 
+-int
++static int
+ get_default_instance_port(const char hostname[])
+ {
+ 	char ip[24] = {'\0'};
+
+commit ca54be710d5e424b4129567155fe518dbff5d8f5
+Author: freddy77 <freddy77>
+Date:   Mon Jan 12 08:15:52 2009 +0000
+
+    ask for password if not specified
+
+diff --git a/ChangeLog b/ChangeLog
+index 9eeb735..ad031ad 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 12 09:15:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqldb.c: ask for password if not specified
++
+ Mon Jan 12 09:08:21 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/tsql.c: make get_default_instance_port static
+ 
+@@ -1177,4 +1180,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2707 2009/01/12 08:09:50 freddy77 Exp $
++$Id: ChangeLog,v 1.2708 2009/01/12 08:15:52 freddy77 Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index ba4f26b..00e8a8e 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -1,5 +1,5 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 2004, 2005  James K. Lowden
++ * Copyright (C) 2004-2009  James K. Lowden
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -45,7 +45,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.33 2008/04/23 21:35:45 jklowden Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.34 2009/01/12 08:15:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+@@ -755,6 +755,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ {
+ 	LOGINREC *login;
+ 	int ch;
++	int got_password = 0;
+ 
+ 	extern char *optarg;
+ 
+@@ -784,6 +785,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 			DBSETLUSER(login, optarg);
+ 			break;
+ 		case 'P':
++			got_password = 1;
+ 			DBSETLPWD(login, optarg);
+ 			break;
+ 		case 'S':
+@@ -821,7 +823,14 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 			exit(1);
+ 		}
+ 	}
+-	
++
++	if (!got_password) {
++		char password[128];
++
++		readpassphrase("Password: ", password, sizeof(password), RPP_ECHO_OFF);
++		DBSETLPWD(login, password);
++        }
++
+ 	if (!options->servername) {
+ 		usage(options->appname);
+ 		exit(1);
+
+commit 600f73b5c4a422f47bae98e3653c0100d5bfd8c8
+Author: jklowden <jklowden>
+Date:   Fri Jan 16 20:27:55 2009 +0000
+
+    fewer warnings compiling for Win64
+
+diff --git a/ChangeLog b/ChangeLog
+index ad031ad..4f8b5c7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,26 @@
++Fri Jan 16 15:19:20 EST 2009	JK Lowden <jklowden@freetds.org>
++	* include/md4.h include/md5.h
++	* include/replacements.h
++	* include/sqldb.h include/sqlfront.h include/sybdb.h
++	* include/tds.h include/tds_sysdep_private.h
++	* include/tdsstring.h
++	* samples/odbc_rpc.pl
++	* src/dblib/bcp.c src/dblib/dblib.c
++	* src/dblib/dbopen.c src/dblib/dbutil.c
++	* src/dblib/rpc.c src/dblib/xact.c
++	* src/replacements/fakepoll.c src/replacements/readpassphrase.c
++	* src/replacements/vasprintf.c
++	* src/tds/bulk.c src/tds/challenge.c src/tds/config.c
++	* src/tds/convert.c src/tds/getmac.c src/tds/iconv.c
++	* src/tds/log.c src/tds/login.c src/tds/md4.c
++	* src/tds/md5.c src/tds/mem.c src/tds/net.c src/tds/numeric.c
++	* src/tds/query.c src/tds/read.c src/tds/tdsstring.c
++	* src/tds/threadsafe.c src/tds/token.c src/tds/vstrbuild.c
++	* src/tds/write.c 
++	* src/tds/unittests/dynamic1.c src/tds/unittests/flags.c
++	* src/tds/unittests/numeric.c
++	- fewer warnings compiling for Win64
++
+ Mon Jan 12 09:15:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqldb.c: ask for password if not specified
+ 
+@@ -1180,4 +1203,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2708 2009/01/12 08:15:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2709 2009/01/16 20:27:55 jklowden Exp $
+diff --git a/include/md4.h b/include/md4.h
+index 57a3f22..7cc636b 100644
+--- a/include/md4.h
++++ b/include/md4.h
+@@ -1,7 +1,7 @@
+ #ifndef MD4_H
+ #define MD4_H
+ 
+-/* $Id: md4.h,v 1.7 2007/03/12 13:28:50 freddy77 Exp $ */
++/* $Id: md4.h,v 1.8 2009/01/16 20:27:56 jklowden Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -15,7 +15,7 @@ struct MD4Context
+ };
+ 
+ void MD4Init(struct MD4Context *context);
+-void MD4Update(struct MD4Context *context, unsigned char const *buf, unsigned len);
++void MD4Update(struct MD4Context *context, unsigned char const *buf, size_t len);
+ void MD4Final(struct MD4Context *context, unsigned char *digest);
+ void MD4Transform(TDS_UINT buf[4], TDS_UINT const in[16]);
+ 
+diff --git a/include/md5.h b/include/md5.h
+index e7b6c35..86efc0d 100644
+--- a/include/md5.h
++++ b/include/md5.h
+@@ -1,7 +1,7 @@
+ #ifndef MD5_H
+ #define MD5_H
+ 
+-/* $Id: md5.h,v 1.4 2007/03/12 13:28:50 freddy77 Exp $ */
++/* $Id: md5.h,v 1.5 2009/01/16 20:27:56 jklowden Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -14,8 +14,7 @@ struct MD5Context {
+ };
+ 
+ void MD5Init(struct MD5Context *context);
+-void MD5Update(struct MD5Context *context, unsigned char const *buf,
+-	       unsigned len);
++void MD5Update(struct MD5Context *context, unsigned char const *buf, size_t len);
+ void MD5Final(struct MD5Context *context, unsigned char *digest);
+ void MD5Transform(TDS_UINT buf[4], TDS_UINT const in[16]);
+ 
+diff --git a/include/replacements.h b/include/replacements.h
+index 0756b1a..62ea20c 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.19 2009/01/07 02:58:37 jklowden Exp $ */
++/* $Id: replacements.h,v 1.20 2009/01/16 20:27:56 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -49,16 +49,18 @@ extern "C"
+ #endif
+ 
+ #if !HAVE_POLL
+-#include fakepoll.h
++#include <fakepoll.h>
+ #define poll(fds, nfds, timeout) fakepoll((fds), (nfds), (timeout))
+ #endif /* !HAVE_POLL */
+ 
+-#if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
++#if !HAVE_VSNPRINTF
++#if  HAVE__VSNPRINTF
+ #undef vsnprintf
+ #define vsnprintf _vsnprintf
+-#elif !HAVE_VSNPRINTF
++#else
+ int vsnprintf(char *ret, size_t max, const char *fmt, va_list ap);
+-#endif /* !HAVE_VSNPRINTF */
++#endif /*  HAVE_VSNPRINTF */
++#endif /* !HAVE__VSNPRINTF */
+ 
+ #if !HAVE_ASPRINTF
+ int asprintf(char **ret, const char *fmt, ...);
+diff --git a/include/sqldb.h b/include/sqldb.h
+index aa3f972..3b64b71 100644
+--- a/include/sqldb.h
++++ b/include/sqldb.h
+@@ -20,14 +20,46 @@
+ #ifndef SQLDB_h
+ #define SQLDB_h
+ 
+-#include <sybdb.h>
++#include "./sybdb.h"
++
++#define SQLCHAR SYBCHAR
++#define SQLVARCHAR SYBVARCHAR
++#define SQLINTN SYBINTN
++#define SQLINT1 SYBINT1
++#define SQLINT2 SYBINT2
++#define SQLINT4 SYBINT4
++#define SQLINT8 SYBINT8
++#define SQLFLT8 SYBFLT8
++#define SQLDATETIME SYBDATETIME
++#define SQLBIT SYBBIT
++#define SQLTEXT SYBTEXT
++#define SQLIMAGE SYBIMAGE
++#define SQLMONEY4 SYBMONEY4
++#define SQLMONEY SYBMONEY
++#define SQLDATETIM4 SYBDATETIME4
++#define SQLFLT4 SYBREAL
++#define SQLBINARY SYBBINARY
++#define SQLVARBINARY SYBVARBINARY
++#define SQLNUMERIC SYBNUMERIC
++#define SQLDECIMAL SYBDECIMAL
++#define SQLFLTN SYBFLTN
++#define SQLMONEYN SYBMONEYN
++#define SQLDATETIMN SYBDATETIMN
++#define SQLVOID	SYBVOID
++
++#define SMALLDATETIBIND SMALLDATETIMEBIND
++
++#define DBERRHANDLE_PROC EHANDLEFUNC 
++#define DBMSGHANDLE_PROC MHANDLEFUNC 
+ 
+-/* 
+- * TODO: add other Microsoft differences here e.g. SQLMONEY for SYBMONEY
+- */
+ #define dbfreelogin(x) dbloginfree((x))
+ 
+-static const char rcsid_sqldb_h[] = "$Id: sqldb.h,v 1.4 2007/10/24 21:57:32 jklowden Exp $";
++#define dbprocerrhandle(p, h) dberrhandle((h))
++#define dbprocmsghandle(p, h) dbmsghandle((h))
++
++#define dbwinexit()
++
++static const char rcsid_sqldb_h[] = "$Id: sqldb.h,v 1.5 2009/01/16 20:27:56 jklowden Exp $";
+ static const void *const no_unused_sqldb_h_warn[] = { rcsid_sqldb_h, no_unused_sqldb_h_warn };
+ 
+ 
+diff --git a/include/sqlfront.h b/include/sqlfront.h
+index 051e14c..cd38c8e 100644
+--- a/include/sqlfront.h
++++ b/include/sqlfront.h
+@@ -20,9 +20,9 @@
+ #ifndef SQLFRONT_h
+ #define SQLFRONT_h
+ 
+-#include <sybfront.h>
++#include "./sybfront.h"
+ 
+-static const char rcsid_sqlfront_h[] = "$Id: sqlfront.h,v 1.4 2007/08/02 11:32:57 freddy77 Exp $";
++static const char rcsid_sqlfront_h[] = "$Id: sqlfront.h,v 1.5 2009/01/16 20:27:56 jklowden Exp $";
+ static const void *const no_unused_sqlfront_h_warn[] = { rcsid_sqlfront_h, no_unused_sqlfront_h_warn };
+ 
+ typedef DBPROCESS * PDBPROCESS;
+diff --git a/include/sybdb.h b/include/sybdb.h
+index 8f769de..823002d 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.85 2007/12/02 23:01:37 jklowden Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.86 2009/01/16 20:27:56 jklowden Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -182,6 +182,8 @@ enum
+ #define SYBREAL	SYBREAL
+ 	SYBBINARY = 45,		/* 0x2D */
+ #define SYBBINARY	SYBBINARY
++	SYBVOID = 31,		/* 0x1F */
++#define SYBVOID	SYBVOID
+ 	SYBVARBINARY = 37,	/* 0x25 */
+ #define SYBVARBINARY	SYBVARBINARY
+ 	SYBNUMERIC = 108,	/* 0x6C */
+@@ -265,6 +267,7 @@ typedef struct
+ } DBDATETIME4;
+ 
+ #ifdef MSDBLIB
++#define DBDATETIM4 DBDATETIME4
+ #define SQLCHAR SYBCHAR
+ #endif
+ 
+@@ -1052,7 +1055,8 @@ RETCODE dbsetlversion (LOGINREC * login, BYTE version);
+ #define dbsetlapp(x,y)		dbsetlname((x), (y), DBSETAPP)
+ #define DBSETBCP		6
+ #define BCP_SETL(x,y)		dbsetlbool((x), (y), DBSETBCP)
+-#define DBSETNATLANG		7
++#define DBSETLSECURE(x)		dbsetlbool((x), (1), DBSETBCP)
++#define DBSETNATLANG		7	
+ #define DBSETLNATLANG(x,y)	dbsetlname((x), (y), DBSETNATLANG)
+ #define dbsetlnatlang(x,y)	dbsetlname((x), (y), DBSETNATLANG)
+ #define DBSETNOSHORT		8	/* not implemented */
+diff --git a/include/tds.h b/include/tds.h
+index bf96853..bf61881 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.309 2008/12/16 15:41:18 freddy77 Exp $ */
++/* $Id: tds.h,v 1.310 2009/01/16 20:27:57 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1375,7 +1375,7 @@ void tds_cursor_deallocated(TDSSOCKET *tds, TDSCURSOR *cursor);
+ void tds_release_cursor(TDSSOCKET *tds, TDSCURSOR *cursor);
+ void tds_free_bcp_column_data(BCPCOLDATA * coldata);
+ 
+-int tds_put_n(TDSSOCKET * tds, const void *buf, int n);
++int tds_put_n(TDSSOCKET * tds, const void *buf, size_t n);
+ int tds_put_string(TDSSOCKET * tds, const char *buf, int len);
+ int tds_put_int(TDSSOCKET * tds, TDS_INT i);
+ int tds_put_int8(TDSSOCKET * tds, TDS_INT8 i);
+@@ -1407,7 +1407,7 @@ TDSLOCALE *tds_get_locale(void);
+ int tds_alloc_row(TDSRESULTINFO * res_info);
+ int tds_alloc_compute_row(TDSCOMPUTEINFO * res_info);
+ BCPCOLDATA * tds_alloc_bcp_column_data(int column_size);
+-unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, int len, unsigned char *crypt_pass);
++unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsigned char *crypt_pass);
+ TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, const char *id);
+ /*@observer@*/ const char *tds_prtype(int token);
+ 
+@@ -1437,7 +1437,7 @@ char *tds_get_homedir(void);
+ TDSPARAMINFO *tds_alloc_param_result(TDSPARAMINFO * old_param);
+ void tds_free_input_params(TDSDYNAMIC * dyn);
+ void tds_free_dynamic(TDSSOCKET * tds, TDSDYNAMIC * dyn);
+-TDSSOCKET *tds_realloc_socket(TDSSOCKET * tds, int bufsize);
++TDSSOCKET *tds_realloc_socket(TDSSOCKET * tds, size_t bufsize);
+ char *tds_alloc_client_sqlstate(int msgno);
+ char *tds_alloc_lookup_sqlstate(TDSSOCKET * tds, int msgno);
+ TDSLOGIN *tds_alloc_login(void);
+@@ -1558,7 +1558,7 @@ int tdsdump_open(const char *filename);
+ #pragma GCC visibility push(hidden)
+ #endif
+ void tdsdump_close(void);
+-void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, int length);
++void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length);
+ void tdsdump_col(const TDSCOLUMN *col);
+ void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ 
+@@ -1592,7 +1592,7 @@ TDS_INT tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s);
+ TDS_INT tds_numeric_change_prec_scale(TDS_NUMERIC * numeric, unsigned char new_prec, unsigned char new_scale);
+ 
+ /* getmac.c */
+-void tds_getmac(int s, unsigned char mac[6]);
++void tds_getmac(TDS_SYS_SOCKET s, unsigned char mac[6]);
+ 
+ TDSAUTHENTICATION * tds_ntlm_get_auth(TDSSOCKET * tds);
+ TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds);
+@@ -1662,4 +1662,8 @@ int tds_writetext_end(TDSSOCKET *tds);
+ #pragma GCC visibility pop
+ #endif
+ 
++#define TDS_PUT_INT(tds,v) tds_put_int((tds), ((TDS_INT)(v)))
++#define TDS_PUT_SMALLINT(tds,v) tds_put_smallint((tds), ((TDS_SMALLINT)(v)))
++#define TDS_PUT_BYTE(tds,v) tds_put_byte((tds), ((unsigned char)(v)))
++
+ #endif /* _tds_h_ */
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 4b523e0..4089fd4 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.26 2008/11/15 09:57:06 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.27 2009/01/16 20:27:57 jklowden Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -67,7 +67,8 @@ typedef int pid_t;
+ #define getpid() _gethostid()
+ #endif	/* defined(DOS32X) */
+ 
+-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
++#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(_WIN64)
++#include <winsock2.h>
+ #include <windows.h>
+ #define READSOCKET(a,b,c)	recv((a), (char *) (b), (c), TDS_NOSIGNAL)
+ #define WRITESOCKET(a,b,c)	send((a), (const char *) (b), (c), TDS_NOSIGNAL)
+diff --git a/include/tdsstring.h b/include/tdsstring.h
+index 63c732c..6e1aadc 100644
+--- a/include/tdsstring.h
++++ b/include/tdsstring.h
+@@ -20,7 +20,7 @@
+ #ifndef _tdsstring_h_
+ #define _tdsstring_h_
+ 
+-/* $Id: tdsstring.h,v 1.19 2007/07/01 10:10:52 freddy77 Exp $ */
++/* $Id: tdsstring.h,v 1.20 2009/01/16 20:27:57 jklowden Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -61,13 +61,13 @@ void tds_dstr_free(DSTR * s);
+ 
+ DSTR* tds_dstr_dup(DSTR * s, const DSTR * src);
+ DSTR* tds_dstr_copy(DSTR * s, const char *src);
+-DSTR* tds_dstr_copyn(DSTR * s, const char *src, unsigned int length);
++DSTR* tds_dstr_copyn(DSTR * s, const char *src, size_t length);
+ DSTR* tds_dstr_set(DSTR * s, char *src);
+ 
+ /** limit length of string, MUST be <= current length */
+-DSTR* tds_dstr_setlen(DSTR *s, unsigned int length);
++DSTR* tds_dstr_setlen(DSTR *s, size_t length);
+ /** allocate space for length char */
+-DSTR* tds_dstr_alloc(DSTR *s, unsigned int length);
++DSTR* tds_dstr_alloc(DSTR *s, size_t length);
+ 
+ /** @} */
+ 
+diff --git a/samples/odbc_rpc.pl b/samples/odbc_rpc.pl
+index 9e4cf2c..d3771bb 100755
+--- a/samples/odbc_rpc.pl
++++ b/samples/odbc_rpc.pl
+@@ -1,5 +1,5 @@
+ #!/usr/local/bin/perl
+-# $Id: odbc_rpc.pl,v 1.9 2008/07/28 20:58:19 jklowden Exp $
++# $Id: odbc_rpc.pl,v 1.10 2009/01/16 20:27:57 jklowden Exp $
+ #
+ # Contributed by James K. Lowden and is hereby placed in 
+ # the public domain.  No rights reserved.  
+@@ -72,6 +72,7 @@ my $dbh = DBI->connect($dsn, $user, $pass, {RaiseError => 1, PrintError => 1, Au
+ 	or die "Unable for connect to $dsn $DBI::errstr";
+ 
+ setup_error_handler($dbh);
++$dbh->{odbc_putdata_start} = 2 ** 31;
+ 
+ # Construct an odbc placeholder list like (?, ?, ?)
+ # for any arguments after $ARGV[0]. 
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 0a84483..105b1ab 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -41,14 +41,14 @@
+ #include <io.h>
+ #endif
+ 
+-#include "tds.h"
+-#include "tdsiconv.h"
+-#include "tdsconvert.h"
+-#include "replacements.h"
+-#include "sybfront.h"
+-#include "sybdb.h"
+-#include "syberror.h"
+-#include "dblib.h"
++#include <tds.h>
++#include <tdsiconv.h>
++#include <tdsconvert.h>
++#include <replacements.h>
++#include <../../include/sybfront.h>
++#include <../../include/sybdb.h>
++#include <../../include/syberror.h>
++#include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+@@ -61,15 +61,15 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.178 2008/12/16 09:26:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.179 2009/01/16 20:27:57 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+-#elif defined(WIN32)
++#elif defined(WIN32) || defined(WIN64)
+ /* win32 version */
+ typedef __int64 offset_type;
+-#define fseeko(f,o,w) (_lseeki64(fileno(f),o,w) == -1)
+-#define ftello(f) _telli64(fileno(f))
++#define fseeko(f,o,w) (_fseeki64((f),o,w) == -1)
++#define ftello(f) _ftelli64((f))
+ #else
+ /* use old version */
+ #define fseeko(f,o,w) fseek(f,o,w)
+@@ -914,7 +914,7 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 					if ((srctype == SYBDATETIME || srctype == SYBDATETIME4)
+ 					    && (hostcol->datatype == SYBCHAR || hostcol->datatype == SYBVARCHAR)) {
+ 						tds_datecrack(srctype, src, &when);
+-						buflen = tds_strftime((TDS_CHAR *)hostcol->bcp_column_data->data, 256,
++						buflen = (int)tds_strftime((TDS_CHAR *)hostcol->bcp_column_data->data, 256,
+ 									 bcpdatefmt, &when);
+ 					} else {
+ 						/* 
+@@ -1160,9 +1160,9 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 		 * and set collen to the field's post-iconv size.  
+ 		 */
+ 		if (hostcol->term_len > 0) { /* delimited data file */
+-			int file_bytes_left, file_len;
++			int file_len;
+ 			size_t col_bytes_left;
+-			offset_type len;
++			offset_type file_bytes_left, len;
+ 			iconv_t cd;
+ 
+ 			len = _bcp_measure_terminated_field(hostfile, hostcol->terminator, hostcol->term_len);
+@@ -1172,7 +1172,7 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 				dbperror(dbproc, SYBEBCOR, 0);
+ 				return (FAIL);
+ 			}
+-			collen = len;
++			collen = (int)len;
+ 			if (collen == 0)
+ 				data_is_null = 1;
+ 
+@@ -1206,7 +1206,7 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 			col_bytes_left = collen;
+ 			/* TODO make tds_iconv_fread handle terminator directly to avoid fseek in _bcp_measure_terminated_field */
+ 			file_bytes_left = tds_iconv_fread(cd, hostfile, file_len, hostcol->term_len, coldata, &col_bytes_left);
+-			collen -= col_bytes_left;
++			collen -= (int)col_bytes_left;
+ 
+ 			/* tdsdump_log(TDS_DBG_FUNC, "collen is %d after tds_iconv_fread()\n", collen); */
+ 
+@@ -1423,7 +1423,7 @@ _bcp_measure_terminated_field(FILE * hostfile, BYTE * terminator, int term_len)
+ 		return -1;
+ 	}
+ 
+-	for (sample_size = 1; (bytes_read = fread(sample, sample_size, 1, hostfile)) != 0;) {
++	for (sample_size = 1; (bytes_read = (int)fread(sample, sample_size, 1, hostfile)) != 0;) {
+ 
+ 		bytes_read *= sample_size;
+ 
+@@ -1658,8 +1658,8 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 					if (fread(row_in_error, chunk, 1, hostfile) != 1) {
+ 						printf("BILL fread failed after fseek\n");
+ 					}
+-					count = fwrite(row_in_error, chunk, 1, errfile);
+-					if( count < chunk ) {
++					count = (int)fwrite(row_in_error, chunk, 1, errfile);
++					if( (size_t)count < chunk ) {
+ 						dbperror(dbproc, SYBEBWEF, errno);
+ 					}
+ 					error_row_size -= chunk;
+@@ -1778,7 +1778,7 @@ bcp_exec(DBPROCESS * dbproc, DBINT *rows_copied)
+  * \sa 	BCP_SETL(), bcp_batch(), bcp_bind(), bcp_colfmt(), bcp_colfmt_ps(), bcp_collen(), bcp_colptr(), bcp_columns(), bcp_control(), bcp_done(), bcp_exec(), bcp_getl(), bcp_init(), bcp_moretext(), bcp_options(), bcp_readfmt(), bcp_sendrow()
+  */
+ static char *
+-_bcp_fgets(char *buffer, size_t size, FILE *f)
++_bcp_fgets(char *buffer, int size, FILE *f)
+ {
+ 	char *p = fgets(buffer, size, f);
+ 	if (p == NULL) 
+@@ -1833,7 +1833,7 @@ bcp_readfmt(DBPROCESS * dbproc, char *filename)
+ 	}
+ 
+ 	if ((_bcp_fgets(buffer, sizeof(buffer), ffile)) != NULL) {
+-		lf_version = atof(buffer);
++		lf_version = (float)atof(buffer);
+ 	} else if (ferror(ffile)) {
+ 		dbperror(dbproc, SYBEBRFF, errno);
+ 		return FAIL;
+@@ -2366,9 +2366,9 @@ _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset)
+ 			data_is_null = 1;
+ 		else {
+ 			if (collen)
+-				collen = (bindcol->column_bindlen < collen) ? bindcol->column_bindlen : collen;
++				collen = (int) ((bindcol->column_bindlen < (TDS_UINT)collen) ? bindcol->column_bindlen : (TDS_UINT)collen);
+ 			else
+-				collen = bindcol->column_bindlen;
++				collen = (int) bindcol->column_bindlen;
+ 		}
+ 	}
+ 
+@@ -2468,7 +2468,7 @@ rtrim(char *str, int len)
+ 	while (p > str && *p == ' ') {
+ 		*p-- = '\0';
+ 	}
+-	return 1 + p - str;
++	return (int)(1 + p - str);
+ }
+ 
+ /** 
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index ec1d31f..970be28 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -63,20 +63,20 @@
+  * 	strucures are defined.  
+  */
+ #define SYBDBLIB 1
+-#include "tds.h"
+-#include "tdsthread.h"
+-#include "sybfront.h"
+-#include "sybdb.h"
+-#include "syberror.h"
+-#include "dblib.h"
+-#include "tdsconvert.h"
+-#include "replacements.h"
++#include <tds.h>
++#include <tdsthread.h>
++#include <tdsconvert.h>
++#include <replacements.h>
++#include <../../include/sybfront.h>
++#include <../../include/sybdb.h>
++#include <../../include/syberror.h>
++#include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.337 2008/12/17 11:04:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.338 2009/01/16 20:27:57 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -563,7 +563,7 @@ dbgetnull(DBPROCESS *dbproc, int bindtype, int varlen, BYTE* varaddr)
+ 		memcpy(varaddr, pnullrep->bindval, pnullrep->len);
+ 		return SUCCEED;
+ 	default:
+-		if (pnullrep->bindval && (varlen <= 0 || varlen >= pnullrep->len)) {
++		if (pnullrep->bindval && (varlen <= 0 || (size_t)varlen >= pnullrep->len)) {
+ 			memcpy(varaddr, pnullrep->bindval, pnullrep->len);
+ 		}
+ 	}
+@@ -610,7 +610,7 @@ dbgetnull(DBPROCESS *dbproc, int bindtype, int varlen, BYTE* varaddr)
+ 	 * BINARYBIND		Empty array (padded with zeros)
+ 	 */
+ 	varaddr += pnullrep->len;
+-	varlen  -= pnullrep->len;
++	varlen  -= (int)pnullrep->len;
+ 	if (varlen > 0) {
+ 		switch (bindtype) {
+ 		case CHARBIND:
+@@ -931,7 +931,7 @@ dbstring_concat(DBSTRING ** dbstrp, const char *p)
+ 		dbperror(NULL, SYBEMEM, errno);
+ 		return FAIL;
+ 	}
+-	(*strp)->strtotlen = strlen(p);
++	(*strp)->strtotlen = (DBINT)strlen(p);
+ 	if (((*strp)->strtext = malloc((*strp)->strtotlen)) == NULL) {
+ 		TDS_ZERO_FREE(*strp);
+ 		dbperror(NULL, SYBEMEM, errno);
+@@ -1241,9 +1241,6 @@ dbfcmd(DBPROCESS * dbproc, const char *fmt, ...)
+ RETCODE
+ dbcmd(DBPROCESS * dbproc, const char *cmdstring)
+ {
+-	int newsz;
+-	void *p;
+-
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcmd(%p, %s)\n", dbproc, cmdstring);
+ 	CHECK_DBPROC();
+ 	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+@@ -1266,16 +1263,18 @@ dbcmd(DBPROCESS * dbproc, const char *cmdstring)
+ 			return FAIL;
+ 		}
+ 		strcpy((char *) dbproc->dbbuf, cmdstring);
+-		dbproc->dbbufsz = strlen(cmdstring) + 1;
++		dbproc->dbbufsz = (int)strlen(cmdstring) + 1;
+ 	} else {
+-		newsz = strlen(cmdstring) + dbproc->dbbufsz;
++		void *p;
++		size_t newsz = strlen(cmdstring) + dbproc->dbbufsz;
++
+ 		if ((p = realloc(dbproc->dbbuf, newsz)) == NULL) {
+ 			dbperror(dbproc, SYBEMEM, errno);
+ 			return FAIL;
+ 		}
+ 		dbproc->dbbuf = (unsigned char *) p;
+ 		strcat((char *) dbproc->dbbuf, cmdstring);
+-		dbproc->dbbufsz = newsz;
++		dbproc->dbbufsz = (int)newsz;
+ 	}
+ 
+ 	dbproc->command_state = DBCMDPEND;
+@@ -1854,7 +1853,7 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 	case SMALLDATETIMEBIND:
+ 	case SMALLMONEYBIND:
+ 	case TINYBIND:
+-		bindlen = default_null_representations[bindtype].len;
++		bindlen = (int)default_null_representations[bindtype].len;
+ 		break;
+ 
+ 	case CHARBIND:
+@@ -1862,9 +1861,9 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 		CHECK_PARAMETER(bindlen >= 0, SYBEBBL, FAIL);
+ 		break;
+ 		
+-	case NTBSTRINGBIND:	bindlen = strlen((char *) bindval);
++	case NTBSTRINGBIND:	bindlen = (int)strlen((char *) bindval);
+ 		break;
+-	case STRINGBIND:	bindlen = strlen((char *) bindval);
++	case STRINGBIND:	bindlen = (int)strlen((char *) bindval);
+ 		break;
+ 	case VARYBINBIND:	bindlen = ((TDS_VARBINARY*) bindval)->len;
+ 		break;
+@@ -2168,7 +2167,7 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 
+ 	/* srclen of -1 means the source data is definitely NULL terminated */
+ 	if (srclen == -1)
+-		srclen = strlen((const char *) src);
++		srclen = (int)strlen((const char *) src);
+ 
+ 	/* oft times we are asked to convert a data type to itself */
+ 	if (srctype == desttype) {
+@@ -2195,7 +2194,7 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 		case SYBTEXT:
+ 			/* srclen of -1 means the source data is definitely NULL terminated */
+ 			if (srclen == -1)
+-				srclen = strlen((const char *) src);
++				srclen = (int)strlen((const char *) src);
+ 
+ 			switch (destlen) {
+ 			case  0:	/* nothing to copy */
+@@ -2682,7 +2681,7 @@ dbcount(DBPROCESS * dbproc)
+ 
+ 	if (!dbproc || !dbproc->tds_socket || dbproc->tds_socket->rows_affected == TDS_NO_COUNT)
+ 		return -1;
+-	return dbproc->tds_socket->rows_affected;
++	return (DBINT)dbproc->tds_socket->rows_affected;
+ }
+ 
+ /**
+@@ -3188,7 +3187,7 @@ dbspr1row(DBPROCESS * dbproc, char *buffer, DBINT buf_len)
+ 			if (srctype == SYBDATETIME || srctype == SYBDATETIME4) {
+ 				memset(&when, 0, sizeof(when));
+ 				tds_datecrack(srctype, dbdata(dbproc, col + 1), &when);
+-				len = tds_strftime(buffer, buf_len, "%b %d %Y %I:%M%p", &when);
++				len = (int)tds_strftime(buffer, buf_len, "%b %d %Y %I:%M%p", &when);
+ 			} else {
+ 				len = dbconvert(dbproc, srctype, dbdata(dbproc, col + 1), dbdatlen(dbproc, col + 1), 
+ 						desttype, (BYTE *) buffer, buf_len);
+@@ -3294,7 +3293,7 @@ dbprrow(DBPROCESS * dbproc)
+ 					if (srctype == SYBDATETIME || srctype == SYBDATETIME4) {
+ 						memset(&when, 0, sizeof(when));
+ 						tds_datecrack(srctype, dbdata(dbproc, col + 1), &when);
+-						len = tds_strftime(dest, sizeof(dest), STD_DATETIME_FMT, &when);
++						len = (int)tds_strftime(dest, sizeof(dest), STD_DATETIME_FMT, &when);
+ 					} else {
+ 						len = dbconvert(dbproc, srctype, dbdata(dbproc, col + 1), dbdatlen(dbproc, col + 1),
+ 								desttype, (BYTE *) dest, sizeof(dest));
+@@ -3425,7 +3424,7 @@ dbprrow(DBPROCESS * dbproc)
+ 				if (srctype == SYBDATETIME || srctype == SYBDATETIME4) {
+ 					memset(&when, 0, sizeof(when));
+ 					tds_datecrack(srctype, dbadata(dbproc, computeid, col), &when);
+-					len = tds_strftime(dest, sizeof(dest), STD_DATETIME_FMT, &when);
++					len = (int)tds_strftime(dest, sizeof(dest), STD_DATETIME_FMT, &when);
+ 				} else {
+ 					len = dbconvert(dbproc, srctype, dbadata(dbproc, computeid, col), -1, desttype,
+ 							(BYTE *) dest, sizeof(dest));
+@@ -4551,7 +4550,6 @@ dbsqlok(DBPROCESS * dbproc)
+ 	 * We're looking for a result token or a done token.
+          */
+ 	while (!done) {
+-		int retcode;
+ 		marker = tds_peek(tds);
+ 
+ 		/* If we hit a result token, then we know everything is OK.  */
+@@ -4732,7 +4730,7 @@ dbbylist(DBPROCESS * dbproc, int computeid, int *size)
+ 	 * stores these data.
+ 	 */
+ 	if (info->by_cols > 0 && info->bycolumns[0] != byte_flag) {
+-		unsigned int n;
++		int n;
+ 		TDS_TINYINT *p = malloc(sizeof(info->bycolumns[0]) + info->by_cols);
+ 		if (!p) {
+ 			dbperror(dbproc, SYBEMEM, errno);
+@@ -6070,7 +6068,7 @@ dbsafestr(DBPROCESS * dbproc, const char *src, DBINT srclen, char *dest, DBINT d
+ 		return FAIL;
+ 
+ 	if (srclen == -1)
+-		srclen = strlen(src);
++		srclen = (int)strlen(src);
+ 
+ 	if (quotetype == DBSINGLE || quotetype == DBBOTH)
+ 		squote = TRUE;
+@@ -6908,7 +6906,7 @@ dbiordesc(DBPROCESS * dbproc)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbiordesc(%p)\n", dbproc);
+ 	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+-	return dbproc->tds_socket->s;
++	return (int)dbproc->tds_socket->s;
+ }
+ 
+ 
+@@ -6925,7 +6923,7 @@ dbiowdesc(DBPROCESS * dbproc)
+ 	tdsdump_log(TDS_DBG_FUNC, "dbiowdesc(%p)\n", dbproc);
+ 	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+-	return dbproc->tds_socket->s;
++	return (int)dbproc->tds_socket->s;
+ }
+ 
+ DBBOOL
+@@ -7814,7 +7812,7 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 			assert(*(pformats - 1) == '\0'); 
+ 			if(*pformats != '\0') {
+ 				va_list ap;
+-				int result_len, len = 2 * strlen(ptext);
++				int result_len, len = 2 * (int)strlen(ptext);
+ 				char * buffer = calloc(1, len);
+ 
+ 				if (buffer == NULL)
+diff --git a/src/dblib/dbopen.c b/src/dblib/dbopen.c
+index ea70906..34e21ed 100644
+--- a/src/dblib/dbopen.c
++++ b/src/dblib/dbopen.c
+@@ -21,8 +21,8 @@
+ #include <config.h>
+ #endif
+ 
+-#include "tds.h"
+-#include "sybdb.h"
++#include <tds.h>
++#include <../../include/sybdb.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+@@ -32,7 +32,7 @@
+ #undef dbopen
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbopen.c,v 1.11 2007/09/20 15:32:54 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dbopen.c,v 1.12 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ DBPROCESS *
+ dbopen(LOGINREC * login, const char *server)
+diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c
+index da87bf4..d48bf4b 100644
+--- a/src/dblib/dbutil.c
++++ b/src/dblib/dbutil.c
+@@ -29,17 +29,16 @@
+ #include <stdlib.h>
+ #endif /* HAVE_STDLIB_H */
+ 
+-#include "tds.h"
+-#include "sybdb.h"
+-#include "syberror.h"
+-#include "dblib.h"
+-/* #include "fortify.h" */
++#include <tds.h>
++#include <../../include/sybdb.h>
++#include <../../include/syberror.h>
++#include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbutil.c,v 1.44 2008/12/03 08:37:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dbutil.c,v 1.45 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ /*
+  * test include consistency 
+diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c
+index 4b26de4..8483f0c 100644
+--- a/src/dblib/rpc.c
++++ b/src/dblib/rpc.c
+@@ -43,18 +43,18 @@
+ 
+ #include <assert.h>
+ 
+-#include "tds.h"
+-#include "tdsconvert.h"
+-#include "sybfront.h"
+-#include "sybdb.h"
+-#include "dblib.h"
+-#include "replacements.h"
++#include <tds.h>
++#include <tdsconvert.h>
++#include <replacements.h>
++#include <../../include/sybfront.h>
++#include <../../include/sybdb.h>
++#include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: rpc.c,v 1.65 2008/06/12 01:00:48 jklowden Exp $");
++TDS_RCSID(var, "$Id: rpc.c,v 1.66 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ static void rpc_clear(DBREMOTE_PROC * rpc);
+ static void param_clear(DBREMOTE_PROC_PARAM * pparam);
+@@ -415,7 +415,7 @@ param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc)
+ 		/* meta data */
+ 		if (p->name) {
+ 			tds_strlcpy(pcol->column_name, p->name, sizeof(pcol->column_name));
+-			pcol->column_namelen = strlen(pcol->column_name);
++			pcol->column_namelen = (int)strlen(pcol->column_name);
+ 		}
+ 
+ 		tds_set_param_type(tds, pcol, temp_type);
+diff --git a/src/dblib/xact.c b/src/dblib/xact.c
+index 13e505c..6553d68 100644
+--- a/src/dblib/xact.c
++++ b/src/dblib/xact.c
+@@ -28,16 +28,16 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+-#include "tds.h"
+-#include "sybfront.h"
+-#include "sybdb.h"
+-#include "dblib.h"
++#include <tds.h>
++#include <../../include/sybfront.h>
++#include <../../include/sybdb.h>
++#include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: xact.c,v 1.11 2006/12/26 14:56:19 freddy77 Exp $");
++TDS_RCSID(var, "$Id: xact.c,v 1.12 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ 
+ void
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index 3685092..be525d8 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -18,10 +18,10 @@
+  * Converted to C and spruced up by James K. Lowden December 2008. 
+  */
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.5 2009/01/03 14:56:53 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.6 2009/01/16 20:27:58 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#include "fakepoll.h"
++#include <replacements.h>
+ 
+ #if HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+diff --git a/src/replacements/readpassphrase.c b/src/replacements/readpassphrase.c
+index 40c4069..666f33a 100644
+--- a/src/replacements/readpassphrase.c
++++ b/src/replacements/readpassphrase.c
+@@ -73,7 +73,7 @@ static const char rcsid[] = "$OpenBSD: readpassphrase.c,v 1.16 2003/06/17 21:56:
+ 
+ #include <replacements/readpassphrase.h>
+ 
+-#ifndef WIN32
++#if !defined(_WIN32) && !defined(_WIN64)
+ #include <termios.h>
+ 
+ #ifndef _PATH_TTY
+diff --git a/src/replacements/vasprintf.c b/src/replacements/vasprintf.c
+index bdb0df9..7d1ded4 100644
+--- a/src/replacements/vasprintf.c
++++ b/src/replacements/vasprintf.c
+@@ -30,7 +30,7 @@
+ #include "tds_sysdep_private.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: vasprintf.c,v 1.18 2007/12/27 13:45:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: vasprintf.c,v 1.19 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef HAVE_VSNPRINTF
+@@ -48,7 +48,7 @@ int
+ vasprintf(char **ret, const char *fmt, va_list ap)
+ {
+ #if HAVE_VSNPRINTF
+-	int chunks;
++	size_t chunks;
+ 	size_t buflen;
+ 	char *buf;
+ 	int len;
+@@ -61,7 +61,7 @@ vasprintf(char **ret, const char *fmt, va_list ap)
+ 			return -1;
+ 		}
+ 		len = vsnprintf(buf, buflen, fmt, ap);
+-		if (len >= 0 && (size_t) len < (buflen - 1)) {
++		if (0 <= len && (size_t) len < buflen - 1) {
+ 			break;
+ 		}
+ 		free(buf);
+@@ -70,7 +70,7 @@ vasprintf(char **ret, const char *fmt, va_list ap)
+ 		 * len >= 0 are required for vsnprintf implementation that 
+ 		 * return -1 of buffer insufficient
+ 		 */
+-		if (len >= 0 && (size_t) len >= buflen) {
++		if (buflen <= (size_t) len) {
+ 			buflen = len + 1;
+ 		}
+ 	}
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index 856f831..f549571 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.8 2008/12/19 18:43:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.9 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #ifndef MAX
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+@@ -776,7 +776,7 @@ tds_bcp_add_variable_columns(TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_d
+ 			padj[i] = offsets[ncols-i] >> 8;
+ 			poff[i] = offsets[ncols-i] & 0xFF;
+ 		}
+-		row_pos = poff + ncols + 1 - rowbuffer;
++		row_pos = (int)(poff + ncols + 1 - rowbuffer);
+ 	}
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "%4d %8d %8d\n", i, ncols, row_pos);
+@@ -862,8 +862,8 @@ tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 		}
+ 		if (is_blob_type(bcpcol->on_server.column_type)) {
+ 			/* FIXME strlen return len in bytes not in characters required here */
+-			tds_put_smallint(tds, strlen(bcpinfo->tablename));
+-			tds_put_string(tds, bcpinfo->tablename, strlen(bcpinfo->tablename));
++			TDS_PUT_SMALLINT(tds, strlen(bcpinfo->tablename));
++			tds_put_string(tds, bcpinfo->tablename, (int)strlen(bcpinfo->tablename));
+ 		}
+ 		/* FIXME support multibyte string */
+ 		tds_put_byte(tds, bcpcol->column_namelen);
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index 2504f96..6a4c0d1 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.36 2008/11/06 14:39:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.37 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -91,16 +91,16 @@ static void tds_encrypt_answer(const unsigned char *hash, const unsigned char *c
+ static void tds_convert_key(const unsigned char *key_56, DES_KEY * ks);
+ 
+ static void
+-convert_to_upper(char *buf, int len)
++convert_to_upper(char *buf, size_t len)
+ {
+-	int i;
++	size_t i;
+ 
+ 	for (i = 0; i < len; i++)
+ 		buf[i] = toupper(buf[i]);
+ }
+ 
+-static int
+-convert_to_usc2le_string(TDSSOCKET * tds, const char *s, int len, char *out)
++static size_t
++convert_to_usc2le_string(TDSSOCKET * tds, const char *s, size_t len, char *out)
+ {
+ 	const char *ib;
+ 	char *ob;
+@@ -143,9 +143,9 @@ static int
+ make_ntlm_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_hash[16])
+ {
+ 	MD4_CTX context;
+-	int passwd_len = 0;
++	size_t passwd_len = 0;
+ 	char passwd_usc2le[256];
+-	int passwd_usc2le_len = 0;
++	size_t passwd_usc2le_len = 0;
+ 
+ 	passwd_len = strlen(passwd);
+ 
+@@ -174,13 +174,13 @@ static int
+ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_hash[16])
+ {
+ 	const char *user_name, *domain;
+-	int domain_len, user_name_len;
++	size_t domain_len, user_name_len, len, buf_usc2le_len = 0;
+ 	const char *p;
+ 
+ 	unsigned char ntlm_hash[16];
+ 	char buf[128];
+ 	char buf_usc2le[512];
+-	int buf_usc2le_len = 0, l, res;
++	int res;
+ 
+ 	user_name = tds_dstr_cstr(&tds->connection->user_name);
+ 	user_name_len = strlen(user_name);
+@@ -199,19 +199,19 @@ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_has
+ 	memcpy(buf, user_name, user_name_len);
+ 	convert_to_upper(buf, user_name_len);
+ 
+-	l = convert_to_usc2le_string(tds, buf, user_name_len, buf_usc2le);
+-	if (l < 0)
++	len = convert_to_usc2le_string(tds, buf, user_name_len, buf_usc2le);
++	if (len < 0)
+ 		return TDS_FAIL;
+-	buf_usc2le_len = l;
++	buf_usc2le_len = len;
+ 
+ 	if (domain_len > 128)
+ 		domain_len = 128;
+ 	/* Target is supposed to be case-sensitive */
+ 
+-	l = convert_to_usc2le_string(tds, domain, domain_len, buf_usc2le + l);
+-	if (l < 0)
++	len = convert_to_usc2le_string(tds, domain, domain_len, buf_usc2le + len);
++	if (len < 0)
+ 		return TDS_FAIL;
+-	buf_usc2le_len += l;
++	buf_usc2le_len += len;
+ 
+ 
+ 	res = make_ntlm_hash(tds, passwd, ntlm_hash);
+@@ -265,8 +265,8 @@ tds_answer_challenge(TDSSOCKET * tds,
+ {
+ #define MAX_PW_SZ 14
+ 	const char *passwd = tds_dstr_cstr(&connection->password);
+-	int len;
+-	int i;
++	size_t len;
++	size_t i;
+ 	static const des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+ 	DES_KEY ks;
+ 	unsigned char hash[24], ntlm2_challenge[16];
+@@ -402,22 +402,18 @@ tds_convert_key(const unsigned char *key_56, DES_KEY * ks)
+ 	memset(&key, 0, sizeof(key));
+ }
+ 
+-
+ static int
+ tds7_send_auth(TDSSOCKET * tds,
+ 	       const unsigned char *challenge, TDS_UINT flags, const unsigned char *names_blob, TDS_INT names_blob_len)
+ {
+-	int current_pos;
++	size_t current_pos;
+ 	TDSANSWER answer;
+ 
+ 	/* FIXME: stuff duplicate in tds7_send_login */
+ 	const char *domain;
+ 	const char *user_name;
+ 	const char *p;
+-	int user_name_len;
+-	int host_name_len;
+-	int password_len;
+-	int domain_len;
++	size_t user_name_len, host_name_len, password_len, domain_len;
+ 	int rc;
+ 
+ 	unsigned char *ntlm_v2_response = NULL;
+@@ -465,38 +461,38 @@ tds7_send_auth(TDSSOCKET * tds,
+ 	/* LM/LMv2 Response */
+ 	tds_put_smallint(tds, lm_response_len);	/* lan man resp length */
+ 	tds_put_smallint(tds, lm_response_len);	/* lan man resp length */
+-	tds_put_int(tds, current_pos);	/* resp offset */
++	TDS_PUT_INT(tds, current_pos);	/* resp offset */
+ 	current_pos += lm_response_len;
+ 
+ 	/* NTLM/NTLMv2 Response */
+ 	tds_put_smallint(tds, ntlm_response_len);	/* nt resp length */
+ 	tds_put_smallint(tds, ntlm_response_len);	/* nt resp length */
+-	tds_put_int(tds, current_pos);	/* nt resp offset */
++	TDS_PUT_INT(tds, current_pos);	/* nt resp offset */
+ 
+ 	current_pos = 64;
+ 
+ 	/* Target Name - domain or server name */
+-	tds_put_smallint(tds, domain_len * 2);
+-	tds_put_smallint(tds, domain_len * 2);
+-	tds_put_int(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, domain_len * 2);
++	TDS_PUT_SMALLINT(tds, domain_len * 2);
++	TDS_PUT_INT(tds, current_pos);
+ 	current_pos += domain_len * 2;
+ 
+ 	/* username */
+-	tds_put_smallint(tds, user_name_len * 2);
+-	tds_put_smallint(tds, user_name_len * 2);
+-	tds_put_int(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, user_name_len * 2);
++	TDS_PUT_SMALLINT(tds, user_name_len * 2);
++	TDS_PUT_INT(tds, current_pos);
+ 	current_pos += user_name_len * 2;
+ 
+ 	/* Workstation Name */
+-	tds_put_smallint(tds, host_name_len * 2);
+-	tds_put_smallint(tds, host_name_len * 2);
+-	tds_put_int(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, host_name_len * 2);
++	TDS_PUT_SMALLINT(tds, host_name_len * 2);
++	TDS_PUT_INT(tds, current_pos);
+ 	current_pos += host_name_len * 2;
+ 
+ 	/* Session Key (optional) */
+ 	tds_put_smallint(tds, 0);
+ 	tds_put_smallint(tds, 0);
+-	tds_put_int(tds, current_pos + lm_response_len + ntlm_response_len);
++	TDS_PUT_INT(tds, current_pos + lm_response_len + ntlm_response_len);
+ 
+ 	/* flags */
+ 	/* "challenge" is 8 bytes long */
+@@ -506,9 +502,9 @@ tds7_send_auth(TDSSOCKET * tds,
+ 	/* OS Version Structure (Optional) */
+ 
+ 	/* Data itself */
+-	tds_put_string(tds, domain, domain_len);
+-	tds_put_string(tds, user_name, user_name_len);
+-	tds_put_string(tds, tds_dstr_cstr(&connection->client_host_name), host_name_len);
++	tds_put_string(tds, domain, (int)domain_len);
++	tds_put_string(tds, user_name, (int)user_name_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->client_host_name), (int)host_name_len);
+ 
+ 	/* data block */
+ 	tds_put_n(tds, answer.lm_resp, lm_response_len);
+@@ -598,6 +594,7 @@ fill_names_blob_prefix(names_blob_prefix_t * prefix)
+ static int
+ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t len)
+ {
++	const int length = (int)len;
+ 	unsigned char nonce[8];
+ 	TDS_UINT flags;
+ 	int where;
+@@ -633,7 +630,7 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 	/*data_block_offset == 32 */
+ 	/* Version 1 -- The Context, Target Information, and OS Version structure are all omitted */
+ 
+-	if (data_block_offset >= 48 && where + 16 <= len) {
++	if (data_block_offset >= 48 && where + 16 <= length) {
+ 		/* Version 2 -- The Context and Target Information fields are present, but the OS Version structure is not. */
+ 		tds_get_n(tds, NULL, 8);	/* Context (two consecutive longs) */
+ 
+@@ -643,7 +640,7 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 
+ 		where += 16;
+ 
+-		if (data_block_offset >= 56 && where + 8 <= len) {
++		if (data_block_offset >= 56 && where + 8 <= length) {
+ 			/* Version 3 -- The Context, Target Information, and OS Version structure are all present. */
+ 			tds_get_n(tds, NULL, 8);	/* OS Version Structure */
+ 			where += 8;
+@@ -651,7 +648,7 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 	}
+ 
+ 	/* read Target Info if possible */
+-	if (target_info_len > 0 && target_info_offset >= where && target_info_offset + target_info_len <= len) {
++	if (target_info_len > 0 && target_info_offset >= where && target_info_offset + target_info_len <= length) {
+ 		tds_get_n(tds, NULL, target_info_offset - where);
+ 		where = target_info_offset;
+ 
+@@ -677,7 +674,7 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 		names_blob_len = 0;
+ 	}
+ 	/* discard anything left */
+-	tds_get_n(tds, NULL, len - where);
++	tds_get_n(tds, NULL, length - where);
+ 	tdsdump_log(TDS_DBG_INFO1, "Draining %d bytes\n", (int) (len - where));
+ 
+ 	rc = tds7_send_auth(tds, nonce, flags, names_blob, names_blob_len);
+@@ -708,14 +705,14 @@ tds_ntlm_get_auth(TDSSOCKET * tds)
+ 		return NULL;
+ 
+ 	user_name = tds_dstr_cstr(&tds->connection->user_name);
+-	host_name_len = tds_dstr_len(&tds->connection->client_host_name);
++	host_name_len = (int)tds_dstr_len(&tds->connection->client_host_name);
+ 
+ 	/* check override of domain */
+ 	if ((p = strchr(user_name, '\\')) == NULL)
+ 		return NULL;
+ 
+ 	domain = user_name;
+-	domain_len = p - user_name;
++	domain_len = (int)(p - user_name);
+ 
+ 	auth = (struct tds_ntlm_auth *) calloc(1, sizeof(struct tds_ntlm_auth));
+ 
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 2cb061c..b361510 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.140 2008/12/17 11:12:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.141 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -286,7 +286,7 @@ tds_get_home_file(const char *file)
+ 	home = tds_get_homedir();
+ 	if (!home)
+ 		return NULL;
+-	if (asprintf(&path, "%s" TDS_SDIR_SEPARATOR "%s", home, file) < 0)
++	if (asprintf(&path, "%s/%s", home, file) < 0)
+ 		path = NULL;
+ 	free(home);
+ 	return path;
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index a9694c5..5810975 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.186 2009/01/03 15:26:09 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.187 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -156,7 +156,7 @@ string_to_result(int desttype, const char *s, CONV_RESULT * cr)
+ 	} else {
+ 		memcpy(cr->cc.c, s, len < cr->cc.len ? len : cr->cc.len);
+ 	}
+-	return len;
++	return (TDS_INT)len;
+ }
+ 
+ #define string_to_result(s, cr) \
+@@ -175,7 +175,7 @@ binary_to_result(int desttype, const void *data, size_t len, CONV_RESULT * cr)
+ 	} else {
+ 		memcpy(cr->cb.ib, data, len < cr->cb.len ? len : cr->cb.len);
+ 	}
+-	return len;
++	return (TDS_INT)len;
+ }
+ 
+ #define binary_to_result(data, len, cr) \
+@@ -206,7 +206,7 @@ tds_convert_binary(int srctype, const TDS_UCHAR * src, TDS_INT srclen, int destt
+ 	switch (desttype) {
+ 	case TDS_CONVERT_CHAR:
+ 		cplen = srclen * 2;
+-		if (cplen > cr->cc.len)
++		if ((TDS_UINT)cplen > cr->cc.len)
+ 			cplen = cr->cc.len;
+ 
+ 		c = cr->cc.c;
+@@ -402,7 +402,7 @@ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttyp
+ 	case SYBREAL:
+ 		/* FIXME not null terminated */
+ 		/* TODO check syntax and overflow */
+-		cr->r = atof(src);
++		cr->r = (TDS_REAL)atof(src);
+ 		return sizeof(TDS_REAL);
+ 		break;
+ 	case SYBBIT:
+@@ -1517,7 +1517,7 @@ tds_convert_flt8(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
+ 		break;
+ 	case SYBREAL:
+ 		/* TODO check overflow */
+-		cr->r = the_value;
++		cr->r = (TDS_REAL)the_value;
+ 		return sizeof(TDS_REAL);
+ 		break;
+ 	case SYBFLT8:
+diff --git a/src/tds/getmac.c b/src/tds/getmac.c
+index 44c2631..86bedd1 100644
+--- a/src/tds/getmac.c
++++ b/src/tds/getmac.c
+@@ -44,7 +44,7 @@
+ 
+ /* TODO get real MAC */
+ void
+-tds_getmac(int s, unsigned char mac[6])
++tds_getmac(TDS_SYS_SOCKET s, unsigned char mac[6])
+ {
+ /* implementation for Linux */
+ #ifdef __linux__
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 89d1656..18fe7ce 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.135 2008/10/17 08:39:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.136 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -59,7 +59,7 @@ TDS_RCSID(var, "$Id: iconv.c,v 1.135 2008/10/17 08:39:16 freddy77 Exp $");
+ static int bytes_per_char(TDS_ENCODING * charset);
+ #endif
+ static const char *collate2charset(int sql_collate, int lcid);
+-static int skip_one_input_sequence(iconv_t cd, const TDS_ENCODING * charset, const char **input, size_t * input_size);
++static size_t skip_one_input_sequence(iconv_t cd, const TDS_ENCODING * charset, const char **input, size_t * input_size);
+ static int tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *server_name);
+ static int tds_iconv_init(void);
+ static int tds_canonical_charset(const char *charset_name);
+@@ -624,7 +624,7 @@ tds_iconv(TDSSOCKET * tds, const TDSICONV * conv, TDS_ICONV_DIRECTION io,
+ 	ICONV_CONST char *pquest_mark = quest_mark;
+ 	size_t lquest_mark;
+ 	size_t irreversible;
+-	char one_character;
++	size_t one_character;
+ 	char *p;
+ 	int eilseq_raised = 0;
+ 	/* cast away const-ness */
+@@ -1080,7 +1080,7 @@ bytes_per_char(TDS_ENCODING * charset)
+  * \returns number of bytes to skip.
+  */
+ /* FIXME possible buffer reading overflow ?? */
+-static int
++static size_t
+ skip_one_input_sequence(iconv_t cd, const TDS_ENCODING * charset, const char **input, size_t * input_size)
+ {
+ 	int charsize = CHARSIZE(charset);
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 4beb990..7b814e4 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.10 2008/12/15 05:31:15 jklowden Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.11 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+@@ -277,10 +277,9 @@ tdsdump_start(FILE *file, const char *fname, int line)
+  * \param length   number of bytes in the buffer
+  */
+ void
+-tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, int length)
++tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length)
+ {
+-	int i;
+-	int j;
++	size_t i, j;
+ #define BYTES_PER_LINE 16
+ 	const unsigned char *data = (const unsigned char *) buf;
+ 	const int debug_lvl = level_line & 15;
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 81be9db..6b1ed45 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.179 2008/12/20 06:01:21 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.180 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -506,7 +506,13 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ static int
+ tds_put_login_string(TDSSOCKET * tds, const char *buf, int n)
+ {
+-	int buf_len = (buf ? strlen(buf) : 0);
++	char string[32];
++	const int buf_len = buf ? (int)strlen(buf) : 0;
++	memset(string, '<', sizeof(string));
++	memcpy(string, buf, n);
++	string[sizeof(string)-1] = '\0';
++	if(n)
++		tdsdump_dump_buf(TDS_DBG_INFO1, "login string", buf, n);
+ 
+ 	return tds_put_buf(tds, (const unsigned char *) buf, n, buf_len);
+ }
+@@ -616,7 +622,7 @@ tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	if (IS_TDS42(tds)) {
+ 		tds_put_login_string(tds, tds_dstr_cstr(&connection->password), 255);
+ 	} else {
+-		len = tds_dstr_len(&connection->password);
++		len = (int)tds_dstr_len(&connection->password);
+ 		if (len > 253)
+ 			len = 0;
+ 		tds_put_byte(tds, 0);
+@@ -713,20 +719,21 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	char unicode_string[256];
+ 	char *punicode;
+ 	size_t unicode_left;
+-	int packet_size;
+-	int block_size;
+-	int current_pos;
++	size_t packet_size;
++	TDS_INT block_size;
++	size_t current_pos;
+ 
+ 	const char *user_name = tds_dstr_cstr(&connection->user_name);
+-	int user_name_len = strlen(user_name);
+-	int host_name_len = tds_dstr_len(&connection->client_host_name);
+-	int app_name_len = tds_dstr_len(&connection->app_name);
++	// FIXME: These are defined as size_t, but should be TDS_SMALLINT. 
++	size_t user_name_len = strlen(user_name);
++	size_t host_name_len = tds_dstr_len(&connection->client_host_name);
++	size_t app_name_len = tds_dstr_len(&connection->app_name);
+ 	size_t password_len = tds_dstr_len(&connection->password);
+-	int server_name_len = tds_dstr_len(&connection->server_name);
+-	int library_len = tds_dstr_len(&connection->library);
+-	int language_len = tds_dstr_len(&connection->language);
+-	int database_len = tds_dstr_len(&connection->database);
+-	int auth_len = 0;
++	size_t server_name_len = tds_dstr_len(&connection->server_name);
++	size_t library_len = tds_dstr_len(&connection->library);
++	size_t language_len = tds_dstr_len(&connection->language);
++	size_t database_len = tds_dstr_len(&connection->database);
++	size_t auth_len = 0;
+ 
+ 	tds->out_flag = TDS7_LOGIN;
+ 
+@@ -768,7 +775,7 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	tdsdump_log(TDS_DBG_INFO2, "quietly sending TDS 7+ login packet\n");
+ 	tdsdump_off();
+ 
+-	tds_put_int(tds, packet_size);
++	TDS_PUT_INT(tds, packet_size);
+ 	if (IS_TDS90(tds)) {
+ 		tds_put_n(tds, tds9Version, 4);
+ 	} else if (IS_TDS8_PLUS(tds)) {
+@@ -810,8 +817,8 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	tds_put_n(tds, collation, 4);
+ 
+ 	/* host name */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, host_name_len);
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, host_name_len);
+ 	current_pos += host_name_len * 2;
+ 	if (tds->authentication) {
+ 		tds_put_smallint(tds, 0);
+@@ -820,36 +827,36 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		tds_put_smallint(tds, 0);
+ 	} else {
+ 		/* username */
+-		tds_put_smallint(tds, current_pos);
+-		tds_put_smallint(tds, user_name_len);
++		TDS_PUT_SMALLINT(tds, current_pos);
++		TDS_PUT_SMALLINT(tds, user_name_len);
+ 		current_pos += user_name_len * 2;
+ 		/* password */
+-		tds_put_smallint(tds, current_pos);
+-		tds_put_smallint(tds, password_len);
++		TDS_PUT_SMALLINT(tds, current_pos);
++		TDS_PUT_SMALLINT(tds, password_len);
+ 		current_pos += password_len * 2;
+ 	}
+ 	/* app name */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, app_name_len);
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, app_name_len);
+ 	current_pos += app_name_len * 2;
+ 	/* server name */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, server_name_len);
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, server_name_len);
+ 	current_pos += server_name_len * 2;
+ 	/* unknown */
+ 	tds_put_smallint(tds, 0);
+ 	tds_put_smallint(tds, 0);
+ 	/* library name */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, library_len);
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, library_len);
+ 	current_pos += library_len * 2;
+ 	/* language  - kostya@warmcat.excom.spb.su */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, language_len);
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, language_len);
+ 	current_pos += language_len * 2;
+ 	/* database name */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, database_len);
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, database_len);
+ 	current_pos += database_len * 2;
+ 
+ 	/* MAC address */
+@@ -857,27 +864,27 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	tds_put_n(tds, hwaddr, 6);
+ 
+ 	/* authentication stuff */
+-	tds_put_smallint(tds, current_pos);
+-	tds_put_smallint(tds, auth_len);	/* this matches numbers at end of packet */
++	TDS_PUT_SMALLINT(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, auth_len);	/* this matches numbers at end of packet */
+ 	current_pos += auth_len;
+ 
+ 	/* unknown */
+-	tds_put_smallint(tds, current_pos);
++	TDS_PUT_SMALLINT(tds, current_pos);
+ 	tds_put_smallint(tds, 0);
+ 
+ 	if (IS_TDS90(tds)) {
+-		tds_put_smallint(tds, current_pos);
++		TDS_PUT_SMALLINT(tds, current_pos);
+ 		tds_put_smallint(tds, 0);
+ 
+ 		tds_put_int(tds, 0);
+ 	}
+ 
+ 	/* FIXME here we assume single byte, do not use *2 to compute bytes, convert before !!! */
+-	tds_put_string(tds, tds_dstr_cstr(&connection->client_host_name), host_name_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->client_host_name), (int)host_name_len);
+ 	if (!tds->authentication) {
+ 		const char *p;
+ 		TDSICONV *char_conv = tds->char_convs[client2ucs2];
+-		tds_put_string(tds, tds_dstr_cstr(&connection->user_name), user_name_len);
++		tds_put_string(tds, tds_dstr_cstr(&connection->user_name), (int)user_name_len);
+ 		p = tds_dstr_cstr(&connection->password);
+ 		punicode = unicode_string;
+ 		unicode_left = sizeof(unicode_string);
+@@ -892,11 +899,11 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		tds7_crypt_pass((unsigned char *) unicode_string, password_len, (unsigned char *) unicode_string);
+ 		tds_put_n(tds, unicode_string, password_len);
+ 	}
+-	tds_put_string(tds, tds_dstr_cstr(&connection->app_name), app_name_len);
+-	tds_put_string(tds, tds_dstr_cstr(&connection->server_name), server_name_len);
+-	tds_put_string(tds, tds_dstr_cstr(&connection->library), library_len);
+-	tds_put_string(tds, tds_dstr_cstr(&connection->language), language_len);
+-	tds_put_string(tds, tds_dstr_cstr(&connection->database), database_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->app_name), (int)app_name_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->server_name), (int)server_name_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->library), (int)library_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->language), (int)language_len);
++	tds_put_string(tds, tds_dstr_cstr(&connection->database), (int)database_len);
+ 
+ 	if (tds->authentication)
+ 		tds_put_n(tds, tds->authentication->packet, auth_len);
+@@ -913,9 +920,9 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+  * 'len' characters
+  */
+ unsigned char *
+-tds7_crypt_pass(const unsigned char *clear_pass, int len, unsigned char *crypt_pass)
++tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsigned char *crypt_pass)
+ {
+-	int i;
++	size_t i;
+ 
+ 	for (i = 0; i < len; i++)
+ 		crypt_pass[i] = ((clear_pass[i] << 4) | (clear_pass[i] >> 4)) ^ 0xA5;
+diff --git a/src/tds/md4.c b/src/tds/md4.c
+index 1d891d3..6b570d9 100644
+--- a/src/tds/md4.c
++++ b/src/tds/md4.c
+@@ -42,7 +42,7 @@
+ #include "tds.h"
+ #include "md4.h"
+ 
+-TDS_RCSID(var, "$Id: md4.c,v 1.7 2005/07/07 13:06:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: md4.c,v 1.8 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #undef word32
+ #define word32 TDS_UINT
+@@ -92,7 +92,7 @@ MD4Init(struct MD4Context *ctx)
+  * of bytes.
+  */
+ void
+-MD4Update(struct MD4Context *ctx, unsigned char const *buf, unsigned len)
++MD4Update(struct MD4Context *ctx, unsigned char const *buf, size_t len)
+ {
+ 	register word32 t;
+ 
+@@ -101,7 +101,7 @@ MD4Update(struct MD4Context *ctx, unsigned char const *buf, unsigned len)
+ 	t = ctx->bits[0];
+ 	if ((ctx->bits[0] = t + ((word32) len << 3)) < t)
+ 		ctx->bits[1]++;	/* Carry from low to high */
+-	ctx->bits[1] += len >> 29;
++	ctx->bits[1] += (TDS_UINT)len >> 29;
+ 
+ 	t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+ 
+diff --git a/src/tds/md5.c b/src/tds/md5.c
+index 5e7a012..3195baa 100644
+--- a/src/tds/md5.c
++++ b/src/tds/md5.c
+@@ -29,7 +29,7 @@
+ #include "tds.h"
+ #include "md5.h"
+ 
+-TDS_RCSID(var, "$Id: md5.c,v 1.2 2005/07/07 13:06:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: md5.c,v 1.3 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #undef word32
+ #define word32 TDS_UINT
+@@ -73,7 +73,7 @@ void MD5Init(struct MD5Context *ctx)
+  * Update context to reflect the concatenation of another buffer full
+  * of bytes.
+  */
+-void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
++void MD5Update(struct MD5Context *ctx, unsigned char const *buf, size_t len)
+ {
+     register word32 t;
+ 
+@@ -82,7 +82,7 @@ void MD5Update(struct MD5Context *ctx, unsigned char const *buf, unsigned len)
+     t = ctx->bits[0];
+     if ((ctx->bits[0] = t + ((word32) len << 3)) < t)
+ 	ctx->bits[1]++;		/* Carry from low to high */
+-    ctx->bits[1] += len >> 29;
++    ctx->bits[1] += (TDS_UINT)len >> 29;
+ 
+     t = (t >> 3) & 0x3f;	/* Bytes already in shsInfo->data */
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 730f70d..2c027a1 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.184 2008/12/20 19:16:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.185 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -613,6 +613,31 @@ tds_free_all_results(TDSSOCKET * tds)
+ 	tds->has_status = 0;
+ 	tds->ret_status = 0;
+ }
++/*
++ * Return 1 if winsock is initialized, else 0.
++ */
++static int
++winsock_initialized()
++{
++#if defined(_WIN32) || defined(_WIN64)
++	WSADATA wsa_data;
++	int erc;
++	DWORD how_much = 0;
++	WORD requested_version = MAKEWORD(2, 2);
++	 
++	if (SOCKET_ERROR != WSAEnumProtocols(NULL, NULL, &how_much)) 
++		return 1;
++
++	if (WSANOTINITIALISED != WSAGetLastError()) 
++		return 0;
++	
++	if (SOCKET_ERROR == (erc = WSAStartup(requested_version, &wsa_data))) {
++		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d(%s)\n", erc, WSAGetLastError() ); 
++		return 0;
++	}
++#endif
++	return 1;
++}
+ 
+ TDSCONTEXT *
+ tds_alloc_context(void * parent)
+@@ -620,12 +645,13 @@ tds_alloc_context(void * parent)
+ 	TDSCONTEXT *context;
+ 	TDSLOCALE *locale;
+ 
+-	locale = tds_get_locale();
+-	if (!locale)
++	if (!winsock_initialized())
++		return NULL;
++
++	if ((locale = tds_get_locale()) == NULL)
+ 		return NULL;
+ 
+-	context = (TDSCONTEXT *) calloc(1, sizeof(TDSCONTEXT));
+-	if (!context) {
++	if ((context = calloc(1, sizeof(TDSCONTEXT))) == NULL) {
+ 		tds_free_locale(locale);
+ 		return NULL;
+ 	}
+@@ -1037,7 +1063,7 @@ tds_alloc_socket(TDSCONTEXT * context, int bufsize)
+ }
+ 
+ TDSSOCKET *
+-tds_realloc_socket(TDSSOCKET * tds, int bufsize)
++tds_realloc_socket(TDSSOCKET * tds, size_t bufsize)
+ {
+ 	unsigned char *new_out_buf;
+ 
+@@ -1049,7 +1075,7 @@ tds_realloc_socket(TDSSOCKET * tds, int bufsize)
+ 	if (tds->out_pos <= bufsize && bufsize > 0 && 
+ 	    (new_out_buf = (unsigned char *) realloc(tds->out_buf, bufsize + TDS_ADDITIONAL_SPACE)) != NULL) {
+ 		tds->out_buf = new_out_buf;
+-		tds->env.block_size = bufsize;
++		tds->env.block_size = (int)bufsize;
+ 		return tds;
+ 	}
+ 	return NULL;
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 1a35c6e..7b5a63a 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.84 2008/12/22 15:33:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.85 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -416,8 +416,8 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 		if (exceptfds)
+ 			FD_SET(tds->s, exceptfds);
+ 
+-		rc = select(tds->s + 1, readfds, writefds, exceptfds, ptv); 
+-#endif
++		rc = select((int)tds->s + 1, readfds, writefds, exceptfds, ptv); 
++#endif /* USE_POLL */
+ 
+ 		if (rc > 0 ) {
+ 			return rc;
+@@ -603,7 +603,7 @@ tds_read_packet(TDSSOCKET * tds)
+ 	/*
+ 	 * If this packet size is the largest we have gotten allocate space for it
+ 	 */
+-	if (len > tds->in_buf_max) {
++	if ((unsigned int)len > tds->in_buf_max) {
+ 		unsigned char *p;
+ 
+ 		if (!tds->in_buf) {
+@@ -881,7 +881,7 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 		selecttimeout.tv_sec = 1;
+ 		selecttimeout.tv_usec = 0;
+ 		
+-		retval = select(s + 1, &fds, NULL, NULL, &selecttimeout);
++		retval = select((int)s + 1, &fds, NULL, NULL, &selecttimeout);
+ #endif
+ 		
+ 		/* on interrupt ignore */
+@@ -1031,7 +1031,7 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		/* send the request */
+ 		msg[0] = 4;
+ 		tds_strlcpy(msg + 1, instance, sizeof(msg) - 1);
+-		sendto(s, msg, strlen(msg) + 1, 0, (struct sockaddr *) &sin, sizeof(sin));
++		sendto(s, msg, (int)strlen(msg) + 1, 0, (struct sockaddr *) &sin, sizeof(sin));
+ 
+ #if USE_POLL
+ 		fd.fd = s;
+@@ -1045,7 +1045,7 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		selecttimeout.tv_sec = 1;
+ 		selecttimeout.tv_usec = 0;
+ 		
+-		retval = select(s + 1, &fds, NULL, NULL, &selecttimeout);
++		retval = select((int)s + 1, &fds, NULL, NULL, &selecttimeout);
+ #endif
+ 		
+ 		/* on interrupt ignore */
+diff --git a/src/tds/numeric.c b/src/tds/numeric.c
+index 0c20c76..148a0a8 100644
+--- a/src/tds/numeric.c
++++ b/src/tds/numeric.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: numeric.c,v 1.44 2008/08/18 13:31:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: numeric.c,v 1.45 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ /* 
+  * these routines use arrays of unsigned char to handle arbitrary
+@@ -323,7 +323,7 @@ tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s)
+ 	}
+ 
+ 	/* transform to 10 base number and output */
+-	i = 4 * ((packet10k + TDS_VECTOR_SIZE(packet10k)) - p);	/* current digit */
++	i = 4 * (unsigned int)((packet10k + TDS_VECTOR_SIZE(packet10k)) - p);	/* current digit */
+ 	/* skip leading zeroes */
+ 	n = 1000;
+ 	remainder = *p;
+@@ -371,21 +371,20 @@ tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s)
+ static int
+ tds_packet_check_overflow(TDS_WORD *packet, unsigned int packet_len, unsigned int prec)
+ {
+-	unsigned int i;
+-	int l, stop;
++	unsigned int i, len, stop;
+ 	const TDS_WORD *limit = &limits[limit_indexes[prec] + LIMIT_INDEXES_ADJUST * prec];
+-	l = limit_indexes[prec+1] - limit_indexes[prec] + LIMIT_INDEXES_ADJUST;
++	len = limit_indexes[prec+1] - limit_indexes[prec] + LIMIT_INDEXES_ADJUST;
+ 	stop = prec / (sizeof(TDS_WORD) * 8);
+ 	/*
+ 	 * Now a number is
+ 	 * ... P[3] P[2] P[1] P[0]
+ 	 * while upper limit + 1 is
+- 	 * zeroes limit[0 .. l-1] 0[0 .. stop-1]
++ 	 * zeroes limit[0 .. len-1] 0[0 .. stop-1]
+ 	 * we must assure that number < upper limit + 1
+ 	 */
+-	if (packet_len >= l + stop) {
++	if (packet_len >= len + stop) {
+ 		/* higher packets must be zero */
+-		for (i = packet_len; --i >= l + stop; )
++		for (i = packet_len; --i >= len + stop; )
+ 			if (packet[i] > 0)
+ 				return TDS_CONVERT_OVERFLOW;
+ 		/* test limit */
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 059aa75..04828ba 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,14 +46,14 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.228 2008/11/05 14:27:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.229 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+-static void tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len);
++static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+ static void tds7_put_params_definition(TDSSOCKET * tds, const char *param_definition, size_t param_length);
+ static int tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags);
+ static int tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol);
+-static char *tds7_build_param_def_from_query(TDSSOCKET * tds, const char* converted_query, int converted_query_len, TDSPARAMINFO * params, size_t *out_len);
++static char *tds7_build_param_def_from_query(TDSSOCKET * tds, const char* converted_query, size_t converted_query_len, TDSPARAMINFO * params, size_t *out_len);
+ static char *tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t query_len, TDSPARAMINFO * params, size_t *out_len);
+ static int tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ 
+@@ -89,7 +89,7 @@ static int tds_count_placeholders_ucs2le(const char *query, const char *query_en
+  * \param buf string to write
+  * \return bytes written
+  */
+-static int
++static size_t
+ tds_ascii_to_ucs2(char *buffer, const char *buf)
+ {
+ 	char *s;
+@@ -118,7 +118,7 @@ tds_ascii_to_ucs2(char *buffer, const char *buf)
+  * \return string allocated (or input pointer if no conversion required) or NULL if error
+  */
+ static const char *
+-tds_convert_string(TDSSOCKET * tds, const TDSICONV * char_conv, const char *s, int len, int *out_len)
++tds_convert_string(TDSSOCKET * tds, const TDSICONV * char_conv, const char *s, int len, size_t *out_len)
+ {
+ 	char *buf;
+ 
+@@ -132,7 +132,7 @@ tds_convert_string(TDSSOCKET * tds, const TDSICONV * char_conv, const char *s, i
+ 	CHECK_TDS_EXTRA(tds);
+ 
+ 	if (len < 0)
+-		len = strlen(s);
++		len = (int)strlen(s);
+ 	if (char_conv->flags == TDS_ENCODING_MEMCPY) {
+ 		*out_len = len;
+ 		return s;
+@@ -192,11 +192,12 @@ tds_submit_query(TDSSOCKET * tds, const char *query)
+ }
+ 
+ static char *
+-tds5_fix_dot_query(const char *query, int *query_len, TDSPARAMINFO * params)
++tds5_fix_dot_query(const char *query, size_t *query_len, TDSPARAMINFO * params)
+ {
+-	int i, pos, l;
++	int i;
++	size_t len, pos;
+ 	const char *e, *s;
+-	int size = *query_len + 30;
++	size_t size = *query_len + 30;
+ 	char *out = (char *) malloc(size);
+ 	if (!out)
+ 		return NULL;
+@@ -205,10 +206,10 @@ tds5_fix_dot_query(const char *query, int *query_len, TDSPARAMINFO * params)
+ 	s = query;
+ 	for (i = 0;; ++i) {
+ 		e = tds_next_placeholder(s);
+-		l = e ? e - s : strlen(s);
+-		if (pos + l + 12 >= size) {
++		len = e ? e - s : strlen(s);
++		if (pos + len + 12 >= size) {
+ 			char *p;
+-			size = pos + l + 30;
++			size = pos + len + 30;
+ 			p = realloc(out, size);
+ 			if (!p) {
+ 				free(out);
+@@ -216,8 +217,8 @@ tds5_fix_dot_query(const char *query, int *query_len, TDSPARAMINFO * params)
+ 			}
+ 			out = p;
+ 		}
+-		memcpy(out + pos, s, l);
+-		pos += l;
++		memcpy(out + pos, s, len);
++		pos += len;
+ 		if (!e)
+ 			break;
+ 		pos += sprintf(out + pos, "@P%d", i + 1);
+@@ -226,7 +227,7 @@ tds5_fix_dot_query(const char *query, int *query_len, TDSPARAMINFO * params)
+ 			return NULL;
+ 		}
+ 		sprintf(params->columns[i]->column_name, "@P%d", i + 1);
+-		params->columns[i]->column_namelen = strlen(params->columns[i]->column_name);
++		params->columns[i]->column_namelen = (TDS_SMALLINT)strlen(params->columns[i]->column_name);
+ 
+ 		s = e + 1;
+ 	}
+@@ -279,7 +280,7 @@ tds_start_query(TDSSOCKET *tds)
+ int
+ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ {
+-	int query_len;
++	size_t query_len;
+ 	int num_params = params ? params->num_cols : 0;
+  
+ 	CHECK_TDS_EXTRA(tds);
+@@ -308,7 +309,7 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 		tds->out_flag = TDS_NORMAL;
+ 		tds_put_byte(tds, TDS_LANGUAGE_TOKEN);
+ 		/* TODO ICONV use converted size, not input size and convert string */
+-		tds_put_int(tds, query_len + 1);
++		TDS_PUT_INT(tds, query_len + 1);
+ 		tds_put_byte(tds, params ? 1 : 0);  /* 1 if there are params, 0 otherwise */
+ 		tds_put_n(tds, query, query_len);
+ 		if (params) {
+@@ -319,16 +320,16 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 	} else if (!IS_TDS7_PLUS(tds) || !params || !params->num_cols) {
+ 		tds->out_flag = TDS_QUERY;
+ 		START_QUERY;
+-		tds_put_string(tds, query, query_len);
++		tds_put_string(tds, query, (int)query_len);
+ 	} else {
+ 		TDSCOLUMN *param;
+ 		size_t definition_len;
+ 		int count, i;
+ 		char *param_definition;
+-		int converted_query_len;
++		size_t converted_query_len;
+ 		const char *converted_query;
+  
+-		converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], query, query_len, &converted_query_len);
++		converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], query, (int)query_len, &converted_query_len);
+ 		if (!converted_query) {
+ 			tds_set_state(tds, TDS_IDLE);
+ 			return TDS_FAIL;
+@@ -348,7 +349,7 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 			 * TODO perhaps functions that calls tds7_build_param_def_from_query
+ 			 * should call also tds7_build_param_def_from_params ??
+ 			 */
+-			param_definition = tds7_build_param_def_from_query(tds, converted_query, converted_query_len, params, &definition_len);
++			param_definition = tds7_build_param_def_from_query(tds, converted_query, (int)converted_query_len, params, &definition_len);
+ 			if (!param_definition) {
+ 				tds_set_state(tds, TDS_IDLE);
+ 				return TDS_FAIL;
+@@ -372,13 +373,13 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 			tds_put_byte(tds, 0);
+ 			tds_put_byte(tds, 0);
+ 			tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+-			tds_put_int(tds, converted_query_len);
++			TDS_PUT_INT(tds, converted_query_len);
+ 			if (IS_TDS8_PLUS(tds))
+ 				tds_put_n(tds, tds->collation, 5);
+-			tds_put_int(tds, converted_query_len);
++			TDS_PUT_INT(tds, converted_query_len);
+ 			tds_put_n(tds, converted_query, converted_query_len);
+ 		} else {
+-			tds7_put_query_params(tds, converted_query, converted_query_len);
++			tds7_put_query_params(tds, converted_query, (int)converted_query_len);
+ 		}
+ 		tds_convert_string_free(query, converted_query);
+  
+@@ -747,7 +748,7 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+  */
+ /* TODO find a better name for this function */
+ static char *
+-tds7_build_param_def_from_query(TDSSOCKET * tds, const char* converted_query, int converted_query_len, TDSPARAMINFO * params, size_t *out_len)
++tds7_build_param_def_from_query(TDSSOCKET * tds, const char* converted_query, size_t converted_query_len, TDSPARAMINFO * params, size_t *out_len)
+ {
+ 	size_t size = 512;
+ 	char *param_str;
+@@ -925,9 +926,9 @@ tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t quer
+  * \param query_len query length in bytes
+  */
+ static void
+-tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len)
++tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len)
+ {
+-	int len, i, num_placeholders;
++	size_t len, i, num_placeholders;
+ 	const char *s, *e;
+ 	char buf[24];
+ 	const char *const query_end = query + query_len;
+@@ -950,10 +951,10 @@ tds7_put_query_params(TDSSOCKET * tds, const char *query, int query_len)
+ 	tds_put_byte(tds, 0);
+ 	tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+ 	len = 2 * len + query_len;
+-	tds_put_int(tds, len);
++	TDS_PUT_INT(tds, len);
+ 	if (IS_TDS8_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+-	tds_put_int(tds, len);
++	TDS_PUT_INT(tds, len);
+ 	s = query;
+ 	/* TODO do a test with "...?" and "...?)" */
+ 	for (i = 1;; ++i) {
+@@ -979,10 +980,10 @@ tds7_put_params_definition(TDSSOCKET * tds, const char *param_definition, size_t
+ 	tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+ 
+ 	/* put parameters definitions */
+-	tds_put_int(tds, param_length);
++	TDS_PUT_INT(tds, param_length);
+ 	if (IS_TDS8_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+-	tds_put_int(tds, param_length ? param_length : -1);
++	TDS_PUT_INT(tds, param_length ? param_length : -1);
+ 	tds_put_n(tds, param_definition, param_length);
+ }
+ 
+@@ -1038,12 +1039,12 @@ tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMI
+ 	if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
+ 		goto failure_nostate;
+ 
+-	query_len = strlen(query);
++	query_len = (int)strlen(query);
+ 
+ 	if (IS_TDS7_PLUS(tds)) {
+ 		size_t definition_len = 0;
+ 		char *param_definition = NULL;
+-		int converted_query_len;
++		size_t converted_query_len;
+ 		const char *converted_query;
+ 
+ 		converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], query, query_len, &converted_query_len);
+@@ -1076,7 +1077,7 @@ tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMI
+ 		tds_put_byte(tds, 0);
+ 
+ 		tds7_put_params_definition(tds, param_definition, definition_len);
+-		tds7_put_query_params(tds, converted_query, converted_query_len);
++		tds7_put_query_params(tds, converted_query, (int)converted_query_len);
+ 		tds_convert_string_free(query, converted_query);
+ 		free(param_definition);
+ 
+@@ -1093,7 +1094,7 @@ tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMI
+ 
+ 		tds->out_flag = TDS_NORMAL;
+ 
+-		id_len = strlen(dyn->id);
++		id_len = (int)strlen(dyn->id);
+ 		tds_put_byte(tds, TDS5_DYNAMIC_TOKEN);
+ 		tds_put_smallint(tds, query_len + id_len * 2 + 21);
+ 		tds_put_byte(tds, 0x01);
+@@ -1135,10 +1136,10 @@ failure_nostate:
+ int
+ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ {
+-	int query_len;
++	size_t query_len;
+ 	TDSCOLUMN *param;
+ 	TDSDYNAMIC *dyn;
+-	int id_len;
++	size_t id_len;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_PARAMINFO_EXTRA(params);
+@@ -1151,13 +1152,13 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ 		size_t definition_len = 0;
+ 		int i;
+ 		char *param_definition = NULL;
+-		int converted_query_len;
++		size_t converted_query_len;
+ 		const char *converted_query;
+ 
+ 		if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
+ 			return TDS_FAIL;
+ 
+-		converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], query, query_len, &converted_query_len);
++		converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], query, (int)query_len, &converted_query_len);
+ 		if (!converted_query) {
+ 			tds_set_state(tds, TDS_IDLE);
+ 			return TDS_FAIL;
+@@ -1244,18 +1245,18 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ 
+ 	id_len = strlen(dyn->id);
+ 	tds_put_byte(tds, TDS5_DYNAMIC_TOKEN);
+-	tds_put_smallint(tds, query_len + id_len * 2 + 21);
++	TDS_PUT_SMALLINT(tds, query_len + id_len * 2 + 21);
+ 	tds_put_byte(tds, 0x08);
+ 	tds_put_byte(tds, params ? 0x01 : 0);
+-	tds_put_byte(tds, id_len);
++	TDS_PUT_BYTE(tds, id_len);
+ 	tds_put_n(tds, dyn->id, id_len);
+ 	/* TODO ICONV convert string, do not put with tds_put_n */
+ 	/* TODO how to pass parameters type? like store procedures ? */
+-	tds_put_smallint(tds, query_len + id_len + 16);
++	TDS_PUT_SMALLINT(tds, query_len + id_len + 16);
+ 	tds_put_n(tds, "create proc ", 12);
+-	tds_put_n(tds, dyn->id, id_len);
++	tds_put_n(tds, dyn->id, (int)id_len);
+ 	tds_put_n(tds, " as ", 4);
+-	tds_put_n(tds, query, query_len);
++	tds_put_n(tds, query, (int)query_len);
+ 
+ 	if (params)
+ 		tds_put_params(tds, params, 0);
+@@ -1322,7 +1323,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 		tdsdump_log(TDS_DBG_ERROR, "tds_put_data_info putting param_name \n");
+ 
+ 		if (IS_TDS7_PLUS(tds)) {
+-			int converted_param_len;
++			size_t converted_param_len;
+ 			const char *converted_param;
+ 
+ 			/* TODO use a fixed buffer to avoid error ? */
+@@ -1332,9 +1333,9 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 			if (!converted_param)
+ 				return TDS_FAIL;
+ 			if (!(flags & TDS_PUT_DATA_PREFIX_NAME)) {
+-				tds_put_byte(tds, converted_param_len / 2);
++				TDS_PUT_BYTE(tds, converted_param_len / 2);
+ 			} else {
+-				tds_put_byte(tds, converted_param_len / 2 + 1);
++				TDS_PUT_BYTE(tds, converted_param_len / 2 + 1);
+ 				tds_put_n(tds, "@", 2);
+ 			}
+ 			tds_put_n(tds, converted_param, converted_param_len);
+@@ -1357,6 +1358,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 	tds_put_byte(tds, curcol->column_output);	/* status (input) */
+ 	if (!IS_TDS7_PLUS(tds))
+ 		tds_put_int(tds, curcol->column_usertype);	/* usertype */
++	// FIXME: column_type is wider than one byte.  Do something sensible, not just lop off the high byte. 
+ 	tds_put_byte(tds, curcol->on_server.column_type);
+ 
+ 	if (is_numeric_type(curcol->on_server.column_type)) {
+@@ -1490,6 +1492,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 
+ 		/* convert string if needed */
+ 		if (curcol->char_conv && curcol->char_conv->flags != TDS_ENCODING_MEMCPY) {
++			size_t output_size;
+ #if 0
+ 			/* TODO this case should be optimized */
+ 			/* we know converted bytes */
+@@ -1502,7 +1505,8 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			/* we need to convert data before */
+ 			/* TODO this can be a waste of memory... */
+ 			converted = 1;
+-			s = tds_convert_string(tds, curcol->char_conv, s, colsize, &colsize);
++			s = tds_convert_string(tds, curcol->char_conv, s, colsize, &output_size);
++			colsize = (TDS_INT)output_size;
+ 			if (!s) {
+ 				/* on conversion error put a empty string */
+ 				/* TODO on memory failure we should compute converted size and use chunks */
+@@ -1702,7 +1706,7 @@ tds_submit_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn)
+ 
+ 	tds->out_flag = TDS_NORMAL;
+ 	/* dynamic id */
+-	id_len = strlen(dyn->id);
++	id_len = (int)strlen(dyn->id);
+ 
+ 	tds_put_byte(tds, TDS5_DYNAMIC_TOKEN);
+ 	tds_put_smallint(tds, id_len + 5);
+@@ -1812,7 +1816,7 @@ tds_submit_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn)
+ 
+ 	tds->out_flag = TDS_NORMAL;
+ 	/* dynamic id */
+-	id_len = strlen(dyn->id);
++	id_len = (int)strlen(dyn->id);
+ 
+ 	tds_put_byte(tds, TDS5_DYNAMIC_TOKEN);
+ 	tds_put_smallint(tds, id_len + 5);
+@@ -1852,10 +1856,10 @@ tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params)
+ 	/* distinguish from dynamic query  */
+ 	tds->cur_dyn = NULL;
+ 
+-	rpc_name_len = strlen(rpc_name);
++	rpc_name_len = (int)strlen(rpc_name);
+ 	if (IS_TDS7_PLUS(tds)) {
+ 		const char *converted_name;
+-		int converted_name_len;
++		size_t converted_name_len;
+ 
+ 		tds->out_flag = TDS_RPC;
+ 		/* procedure name */
+@@ -1865,8 +1869,8 @@ tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params)
+ 			return TDS_FAIL;
+ 		}
+ 		START_QUERY;
+-		tds_put_smallint(tds, converted_name_len / 2);
+-		tds_put_n(tds, converted_name, converted_name_len);
++		TDS_PUT_SMALLINT(tds, converted_name_len / 2);
++		tds_put_n(tds, converted_name, (int)converted_name_len);
+ 		tds_convert_string_free(rpc_name, converted_name);
+ 
+ 		/*
+@@ -1978,7 +1982,7 @@ tds_quote(TDSSOCKET * tds, char *buffer, char quoting, const char *id, int len)
+ 	}
+ 	*dst++ = quoting;
+ 	*dst = 0;
+-	return dst - buffer;
++	return (int)(dst - buffer);
+ }
+ 
+ /**
+@@ -1998,7 +2002,7 @@ tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen)
+ 	CHECK_TDS_EXTRA(tds);
+ 
+ 	if (idlen < 0)
+-		idlen = strlen(id);
++		idlen = (int)strlen(id);
+ 
+ 	/* need quote ?? */
+ 	for (i = 0; i < idlen; ++i) {
+@@ -2034,7 +2038,7 @@ tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen)
+ int
+ tds_quote_string(TDSSOCKET * tds, char *buffer, const char *str, int len)
+ {
+-	return tds_quote(tds, buffer, '\'', str, len < 0 ? strlen(str) : len);
++	return tds_quote(tds, buffer, '\'', str, len < 0 ? (int)strlen(str) : len);
+ }
+ 
+ static inline void
+@@ -2075,17 +2079,17 @@ tds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, in
+ 		tds_put_byte(tds, TDS_CURDECLARE_TOKEN);
+ 
+ 		/* length of the data stream that follows */
+-		tds_put_smallint(tds, (6 + strlen(cursor->cursor_name) + strlen(cursor->query)));
++		TDS_PUT_SMALLINT(tds, (6 + strlen(cursor->cursor_name) + strlen(cursor->query)));
+ 
+ 		tdsdump_log(TDS_DBG_ERROR, "size = %u\n", (unsigned int) (6u + strlen(cursor->cursor_name) + strlen(cursor->query)));
+ 
+-		tds_put_tinyint(tds, strlen(cursor->cursor_name));
+-		tds_put_n(tds, cursor->cursor_name, strlen(cursor->cursor_name));
++		TDS_PUT_BYTE(tds, strlen(cursor->cursor_name));
++		tds_put_n(tds, cursor->cursor_name, (int)strlen(cursor->cursor_name));
+ 		tds_put_byte(tds, 1);	/* cursor option is read only=1, unused=0 */
+ 		tds_put_byte(tds, 0);	/* status unused=0 */
+ 		/* TODO iconv */
+-		tds_put_smallint(tds, strlen(cursor->query));
+-		tds_put_n(tds, cursor->query, strlen(cursor->query));
++		TDS_PUT_SMALLINT(tds, strlen(cursor->query));
++		tds_put_n(tds, cursor->query, (int)strlen(cursor->query));
+ 		tds_put_tinyint(tds, 0);	/* number of columns = 0 , valid value applicable only for updatable cursor */
+ 		*something_to_send = 1;
+ 	}
+@@ -2096,7 +2100,7 @@ tds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, in
+ int
+ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *something_to_send)
+ {
+-	int converted_query_len;
++	size_t converted_query_len;
+ 	const char *converted_query;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+@@ -2119,13 +2123,13 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 
+ 		tds->out_flag = TDS_NORMAL;
+ 		tds_put_byte(tds, TDS_CUROPEN_TOKEN);
+-		tds_put_smallint(tds, 6 + strlen(cursor->cursor_name));	/* length of the data stream that follows */
++		TDS_PUT_SMALLINT(tds, 6 + strlen(cursor->cursor_name));	/* length of the data stream that follows */
+ 
+ 		/*tds_put_int(tds, cursor->cursor_id); *//* Only if cursor id is passed as zero, the cursor name need to be sent */
+ 
+ 		tds_put_int(tds, 0);
+-		tds_put_tinyint(tds, strlen(cursor->cursor_name));
+-		tds_put_n(tds, cursor->cursor_name, strlen(cursor->cursor_name));
++		TDS_PUT_BYTE(tds, strlen(cursor->cursor_name));
++		tds_put_n(tds, cursor->cursor_name, (int)strlen(cursor->cursor_name));
+ 		tds_put_byte(tds, 0);	/* Cursor status : 0 for no arguments */
+ 		*something_to_send = 1;
+ 	}
+@@ -2136,7 +2140,7 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 
+ 		/* cursor statement */
+ 		converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2],
+-						     cursor->query, strlen(cursor->query), &converted_query_len);
++						     cursor->query, (int)strlen(cursor->query), &converted_query_len);
+ 		if (!converted_query) {
+ 			if (!*something_to_send)
+ 				tds_set_state(tds, TDS_IDLE);
+@@ -2184,11 +2188,11 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 			tds_put_byte(tds, 0);
+ 			tds_put_byte(tds, 0);
+ 			tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+-			tds_put_int(tds, converted_query_len);
++			TDS_PUT_INT(tds, converted_query_len);
+ 			if (IS_TDS8_PLUS(tds))
+ 				tds_put_n(tds, tds->collation, 5);
+-			tds_put_int(tds, converted_query_len);
+-			tds_put_n(tds, converted_query, converted_query_len);
++			TDS_PUT_INT(tds, converted_query_len);
++			tds_put_n(tds, converted_query, (int)converted_query_len);
+ 		}
+ 		tds_convert_string_free(cursor->query, converted_query);
+ 
+@@ -2270,14 +2274,14 @@ tds_cursor_setrows(TDSSOCKET * tds, TDSCURSOR * cursor, int *something_to_send)
+ 		tds_set_cur_cursor(tds, cursor);
+ 		tds_put_byte(tds, TDS_CURINFO_TOKEN);
+ 
+-		tds_put_smallint(tds, 12 + strlen(cursor->cursor_name));
++		TDS_PUT_SMALLINT(tds, 12 + strlen(cursor->cursor_name));
+ 		/* length of data stream that follows */
+ 
+ 		/* tds_put_int(tds, tds->cursor->cursor_id); */ /* Cursor id */
+ 
+ 		tds_put_int(tds, 0);
+-		tds_put_tinyint(tds, strlen(cursor->cursor_name));
+-		tds_put_n(tds, cursor->cursor_name, strlen(cursor->cursor_name));
++		TDS_PUT_BYTE(tds, strlen(cursor->cursor_name));
++		tds_put_n(tds, cursor->cursor_name, (int)strlen(cursor->cursor_name));
+ 		tds_put_byte(tds, 1);	/* Command  TDS_CUR_CMD_SETCURROWS */
+ 		tds_put_byte(tds, 0x00);	/* Status - TDS_CUR_ISTAT_ROWCNT 0x0020 */
+ 		tds_put_byte(tds, 0x20);	/* Status - TDS_CUR_ISTAT_ROWCNT 0x0020 */
+@@ -2372,12 +2376,12 @@ tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_typ
+ 
+ 		/*tds_put_smallint(tds, 8); */
+ 
+-		tds_put_smallint(tds, 6 + len + row_len);	/* length of the data stream that follows */
++		TDS_PUT_SMALLINT(tds, 6 + len + row_len);	/* length of the data stream that follows */
+ 
+ 		/*tds_put_int(tds, cursor->cursor_id); *//* cursor id returned by the server */
+ 
+ 		tds_put_int(tds, 0);
+-		tds_put_tinyint(tds, len);
++		TDS_PUT_BYTE(tds, len);
+ 		tds_put_n(tds, cursor->cursor_name, len);
+ 		tds_put_tinyint(tds, fetch_type);
+ 
+@@ -2659,7 +2663,7 @@ tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor)
+ 	tds_put_byte(tds, 0);
+ 	/* TODO convert ?? */
+ 	tds_put_byte(tds, XSYBVARCHAR);
+-	len = strlen(cursor->cursor_name);
++	len = (int)strlen(cursor->cursor_name);
+ 	tds_put_smallint(tds, len);
+ 	if (IS_TDS8_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+@@ -2667,8 +2671,8 @@ tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor)
+ 	tds_put_n(tds, cursor->cursor_name, len);
+ 
+ 	tds->internal_sp_called = TDS_SP_CURSOROPTION;
+-	return tds_query_flush_packet(tds);
+ 
++	return tds_query_flush_packet(tds);
+ }
+ 
+ int 
+@@ -2743,7 +2747,7 @@ tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op,
+ 			TDSCOLUMN *param;
+ 			unsigned int n, num_params;
+ 			const char *table_name = NULL;
+-			int converted_table_len = 0;
++			size_t converted_table_len = 0;
+ 			const char *converted_table = NULL;
+ 
+ 			/* empty table name */
+@@ -2761,17 +2765,17 @@ tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op,
+ 			if (table_name) {
+ 				converted_table =
+ 					tds_convert_string(tds, tds->char_convs[client2ucs2], 
+-							   table_name, strlen(table_name), &converted_table_len);
++							   table_name, (int)strlen(table_name), &converted_table_len);
+ 				if (!converted_table) {
+ 					/* FIXME not here, in the middle of a packet */
+ 					tds_set_state(tds, TDS_IDLE);
+ 					return TDS_FAIL;
+ 				}
+ 			}
+-			tds_put_smallint(tds, converted_table_len);
++			TDS_PUT_SMALLINT(tds, converted_table_len);
+ 			if (IS_TDS8_PLUS(tds))
+ 				tds_put_n(tds, tds->collation, 5);
+-			tds_put_smallint(tds, converted_table_len);
++			TDS_PUT_SMALLINT(tds, converted_table_len);
+ 			tds_put_n(tds, converted_table, converted_table_len);
+ 			tds_convert_string_free(table_name, converted_table);
+ 
+@@ -2970,7 +2974,7 @@ tds_send_emulated_execute(TDSSOCKET * tds, const char *query, TDSPARAMINFO * par
+ 	s = query;
+ 	for (i = 0;; ++i) {
+ 		e = tds_next_placeholder(s);
+-		tds_put_string(tds, s, e ? e - s : -1);
++		tds_put_string(tds, s, (int)(e ? e - s : -1));
+ 		if (!e)
+ 			break;
+ 		/* now translate parameter in string */
+diff --git a/src/tds/read.c b/src/tds/read.c
+index 76a8b48..ac76c7c 100644
+--- a/src/tds/read.c
++++ b/src/tds/read.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: read.c,v 1.107 2008/09/17 12:16:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: read.c,v 1.108 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ 			    size_t * wire_size, char **outbuf, size_t * outbytesleft);
+@@ -201,7 +201,7 @@ tds_get_string(TDSSOCKET * tds, int string_len, char *dest, size_t dest_size)
+ 
+ 	if (IS_TDS7_PLUS(tds)) {
+ 		if (dest == NULL) {
+-			tds_get_n(tds, NULL, wire_bytes);
++			tds_get_n(tds, NULL, (int)wire_bytes);
+ 			return string_len;
+ 		}
+ 
+@@ -270,8 +270,8 @@ tds_get_char_data(TDSSOCKET * tds, char *row_buffer, size_t wire_size, TDSCOLUMN
+ 			return TDS_FAIL;
+ 		}
+ 	} else {
+-		curcol->column_cur_size = wire_size;
+-		if (tds_get_n(tds, dest, wire_size) == NULL) {
++		curcol->column_cur_size = (TDS_INT)wire_size;
++		if (tds_get_n(tds, dest, (int)wire_size) == NULL) {
+ 			tdsdump_log(TDS_DBG_NETWORK, "error: tds_get_char_data: failed to read %u from wire. \n",
+ 				    (unsigned int) wire_size);
+ 			return TDS_FAIL;
+@@ -347,7 +347,7 @@ read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv, size_t * wire_size
+ 		bufleft = TEMP_SIZE - bufleft;
+ 		if (bufleft > *wire_size)
+ 			bufleft = *wire_size;
+-		tds_get_n(tds, (char *) bufp, bufleft);
++		tds_get_n(tds, (char *) bufp, (int)bufleft);
+ 		*wire_size -= bufleft;
+ 		bufleft += bufp - temp;
+ 
+@@ -366,7 +366,7 @@ read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv, size_t * wire_size
+ 			if (bufp == temp) {	/* tds_iconv did not convert anything, avoid infinite loop */
+ 				tdsdump_log(TDS_DBG_NETWORK, "No conversion possible: draining remaining %u bytes.\n",
+ 							     (unsigned int) *wire_size);
+-				tds_get_n(tds, NULL, *wire_size); /* perhaps we should read unconverted data into outbuf? */
++				tds_get_n(tds, NULL, (int)(*wire_size)); /* perhaps we should read unconverted data into outbuf? */
+ 				*wire_size = 0;
+ 				break;
+ 			}
+@@ -380,7 +380,7 @@ read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv, size_t * wire_size
+ 	assert(*wire_size == 0 || *outbytesleft == 0);
+ 
+ 	TEMP_FREE;
+-	return max_output - *outbytesleft;
++	return (int)(max_output - *outbytesleft);
+ }
+ 
+ /** @} */
+diff --git a/src/tds/tdsstring.c b/src/tds/tdsstring.c
+index 65d4b1c..3778c87 100644
+--- a/src/tds/tdsstring.c
++++ b/src/tds/tdsstring.c
+@@ -40,7 +40,7 @@
+ #include "tds.h"
+ #include "tdsstring.h"
+ 
+-TDS_RCSID(var, "$Id: tdsstring.c,v 1.19 2007/07/01 10:10:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tdsstring.c,v 1.20 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ 
+ /**
+@@ -83,7 +83,7 @@ tds_dstr_free(DSTR * s)
+  * @return string copied or NULL on memory error
+  */
+ DSTR*
+-tds_dstr_copyn(DSTR * s, const char *src, unsigned int length)
++tds_dstr_copyn(DSTR * s, const char *src, size_t length)
+ {
+ 	if (s->dstr_s != tds_str_empty)
+ 		free(s->dstr_s);
+@@ -151,7 +151,7 @@ tds_dstr_dup(DSTR * s, const DSTR * src)
+  * @param length   new length 
+  */
+ DSTR*
+-tds_dstr_setlen(DSTR *s, unsigned int length)
++tds_dstr_setlen(DSTR *s, size_t length)
+ {
+ #if ENABLE_EXTRA_CHECKS
+ 	assert(s->dstr_size >= length);
+@@ -171,7 +171,7 @@ tds_dstr_setlen(DSTR *s, unsigned int length)
+  * @return string allocated or NULL on memory error
+  */
+ DSTR*
+-tds_dstr_alloc(DSTR *s, unsigned int length)
++tds_dstr_alloc(DSTR *s, size_t length)
+ {
+ 	char *p;
+ 	if (s->dstr_s != tds_str_empty)
+diff --git a/src/tds/threadsafe.c b/src/tds/threadsafe.c
+index a050eb1..f392ab9 100644
+--- a/src/tds/threadsafe.c
++++ b/src/tds/threadsafe.c
+@@ -74,7 +74,8 @@
+ #include <arpa/inet.h>
+ #endif /* HAVE_ARPA_INET_H */
+ 
+-#ifdef WIN32
++#if defined(WIN32) || defined(WIN64)
++#include <winsock2.h>
+ #include <shlobj.h>
+ #endif
+ 
+@@ -84,12 +85,12 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: threadsafe.c,v 1.46 2007/05/30 07:56:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: threadsafe.c,v 1.47 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ char *
+ tds_timestamp_str(char *str, int maxlen)
+ {
+-#if !defined(WIN32)
++#if !defined(WIN32) && !defined(WIN64)
+ 	struct tm *tm;
+ 	time_t t;
+ 
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 78b0258..0641bc9 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.358 2009/01/07 02:58:54 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.359 2009/01/16 20:27:58 jklowden Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -925,7 +925,7 @@ tds_process_col_name(TDSSOCKET * tds)
+ 		for (col = 0; col < num_names; ++col) {
+ 			curcol = info->columns[col];
+ 			tds_strlcpy(curcol->column_name, cur->name, sizeof(curcol->column_name));
+-			curcol->column_namelen = strlen(curcol->column_name);
++			curcol->column_namelen = (TDS_SMALLINT)strlen(curcol->column_name);
+ 			prev = cur;
+ 			cur = cur->next;
+ 			free(prev->name);
+@@ -1159,7 +1159,7 @@ tds_process_colinfo(TDSSOCKET * tds, char **names, int num_names)
+ 
+ 			if (names && col_info[1] > 0 && col_info[1] <= num_names) {
+ 				tds_strlcpy(curcol->table_name, names[col_info[1] - 1], sizeof(curcol->table_name));
+-				curcol->table_namelen = strlen(curcol->table_name);
++				curcol->table_namelen = (TDS_SMALLINT)strlen(curcol->table_name);
+ 			}
+ 		}
+ 		/* read real column name */
+@@ -1353,7 +1353,7 @@ tds_process_compute_result(TDSSOCKET * tds)
+ 
+ 		if (curcol->column_namelen == 0) {
+ 			strcpy(curcol->column_name, tds_pr_op(curcol->column_operator));
+-			curcol->column_namelen = strlen(curcol->column_name);
++			curcol->column_namelen = (TDS_SMALLINT)strlen(curcol->column_name);
+ 		}
+ 
+ 		/*  User defined data type of the column */
+@@ -1831,7 +1831,7 @@ tds5_process_result(TDSSOCKET * tds)
+ 		/* if label is empty, use the table column name */
+ 		if (!curcol->column_namelen && curcol->table_column_name) {
+ 			tds_strlcpy(curcol->column_name, curcol->table_column_name, sizeof(curcol->column_name));
+-			curcol->column_namelen = strlen(curcol->column_name);
++			curcol->column_namelen = (TDS_SMALLINT)strlen(curcol->column_name);
+ 		}
+ 
+ 		/* flags (4 bytes) */
+@@ -2990,7 +2990,7 @@ tds_process_compute_names(TDSSOCKET * tds)
+ 
+ 			assert(strlen(curcol->column_name) == curcol->column_namelen);
+ 			tds_strlcpy(curcol->column_name, cur->name, sizeof(curcol->column_name));
+-			curcol->column_namelen = strlen(curcol->column_name);
++			curcol->column_namelen = (TDS_SMALLINT)strlen(curcol->column_name);
+ 
+ 			next = cur->next;
+ 			free(cur->name);
+@@ -3083,7 +3083,7 @@ tds7_process_compute_result(TDSSOCKET * tds)
+ 
+ 		if (!curcol->column_namelen) {
+ 			strcpy(curcol->column_name, tds_pr_op(curcol->column_operator));
+-			curcol->column_namelen = strlen(curcol->column_name);
++			curcol->column_namelen = (TDS_SMALLINT)strlen(curcol->column_name);
+ 		}
+ 	}
+ 
+diff --git a/src/tds/unittests/dynamic1.c b/src/tds/unittests/dynamic1.c
+index 8115452..8bb2150 100644
+--- a/src/tds/unittests/dynamic1.c
++++ b/src/tds/unittests/dynamic1.c
+@@ -18,7 +18,7 @@
+  */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: dynamic1.c,v 1.18 2007/09/13 06:58:48 freddy77 Exp $";
++static char software_version[] = "$Id: dynamic1.c,v 1.19 2009/01/16 20:27:59 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int discard_result(TDSSOCKET * tds);
+@@ -35,7 +35,7 @@ test(TDSSOCKET * tds, TDSDYNAMIC * dyn, TDS_INT n, const char *s)
+ {
+ 	TDSPARAMINFO *params;
+ 	TDSCOLUMN *curcol;
+-	int len = strlen(s);
++	int len = (int)strlen(s);
+ 
+ 	tds_free_input_params(dyn);
+ 
+diff --git a/src/tds/unittests/flags.c b/src/tds/unittests/flags.c
+index 5c5f28b..a284043 100644
+--- a/src/tds/unittests/flags.c
++++ b/src/tds/unittests/flags.c
+@@ -21,7 +21,7 @@
+ 
+ #include <tdsconvert.h>
+ 
+-static char software_version[] = "$Id: flags.c,v 1.14 2005/04/14 11:35:47 freddy77 Exp $";
++static char software_version[] = "$Id: flags.c,v 1.15 2009/01/16 20:27:59 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static TDSLOGIN *login;
+@@ -39,7 +39,7 @@ check_flags(TDSCOLUMN * curcol, int n, const char *possible_results)
+ {
+ 	char msg[256];
+ 	char flags[256];
+-	int l;
++	size_t l;
+ 	char *all_res = strdup(possible_results);
+ 	char *res;
+ 	int correct = 0;
+diff --git a/src/tds/unittests/numeric.c b/src/tds/unittests/numeric.c
+index ecf447e..3e987e9 100644
+--- a/src/tds/unittests/numeric.c
++++ b/src/tds/unittests/numeric.c
+@@ -23,14 +23,14 @@
+ 
+ /* test numeric scale */
+ 
+-static char software_version[] = "$Id: numeric.c,v 1.4 2005/07/28 08:06:31 freddy77 Exp $";
++static char software_version[] = "$Id: numeric.c,v 1.5 2009/01/16 20:27:59 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+ static TDSCONTEXT ctx;
+ 
+ static void
+-test0(const char *src, int prec, int scale, int prec2, int scale2)
++test0(const char *src, int prec, int scale, int prec2, unsigned char scale2)
+ {
+ 	int i;
+ 	char buf[256];
+@@ -43,7 +43,7 @@ test0(const char *src, int prec, int scale, int prec2, int scale2)
+ 	memset(&cr.n, 0, sizeof(cr.n));
+ 	cr.n.precision = prec;
+ 	cr.n.scale = scale;
+-	if (tds_convert(&ctx, SYBVARCHAR, src, strlen(src), SYBNUMERIC, &cr) < 0) {
++	if (tds_convert(&ctx, SYBVARCHAR, src, (TDS_UINT)strlen(src), SYBNUMERIC, &cr) < 0) {
+ 		fprintf(stderr, "Error getting numeric %s(%d,%d)\n", src, prec, scale);
+ 		exit(1);
+ 	}
+@@ -68,7 +68,7 @@ test0(const char *src, int prec, int scale, int prec2, int scale2)
+ 	}
+ 	cr.n.precision = prec2;
+ 	cr.n.scale = scale2;
+-	if (tds_convert(&ctx, SYBVARCHAR, src, strlen(src), SYBNUMERIC, &cr) < 0)
++	if (tds_convert(&ctx, SYBVARCHAR, src, (TDS_UINT)strlen(src), SYBNUMERIC, &cr) < 0)
+ 		strcpy(buf, "error");
+ 
+ 	/* change scale with function */
+diff --git a/src/tds/vstrbuild.c b/src/tds/vstrbuild.c
+index af7a519..92b4065 100644
+--- a/src/tds/vstrbuild.c
++++ b/src/tds/vstrbuild.c
+@@ -35,7 +35,7 @@
+ #include "tds.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: vstrbuild.c,v 1.15 2008/01/24 21:14:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: vstrbuild.c,v 1.16 2009/01/16 20:27:59 jklowden Exp $");
+ 
+ struct string_linked_list
+ {
+@@ -49,7 +49,7 @@ struct string_linked_list
+  */
+ 
+ static char *
+-norm_fmt(const char *fmt, int fmtlen)
++norm_fmt(const char *fmt, size_t fmtlen)
+ {
+ 	char *newfmt;
+ 	char *cp;
+@@ -102,7 +102,7 @@ tds_vstrbuild(char *buffer, int buflen, int *resultlen, char *text, int textlen,
+ 
+ 	*resultlen = 0;
+ 	if (textlen == TDS_NULLTERM) {
+-		textlen = strlen(text);
++		textlen = (int)strlen(text);
+ 	}
+ 	if ((newformat = norm_fmt(formats, formatlen)) == NULL) {
+ 		return TDS_FAIL;
+diff --git a/src/tds/write.c b/src/tds/write.c
+index 74f85a3..5e70c56 100644
+--- a/src/tds/write.c
++++ b/src/tds/write.c
+@@ -49,7 +49,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: write.c,v 1.76 2006/12/26 14:56:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: write.c,v 1.77 2009/01/16 20:27:59 jklowden Exp $");
+ 
+ /**
+  * \addtogroup network
+@@ -61,9 +61,9 @@ TDS_RCSID(var, "$Id: write.c,v 1.76 2006/12/26 14:56:21 freddy77 Exp $");
+  *		much like read() and memcpy()
+  */
+ int
+-tds_put_n(TDSSOCKET * tds, const void *buf, int n)
++tds_put_n(TDSSOCKET * tds, const void *buf, size_t n)
+ {
+-	int left;
++	size_t left;
+ 	const unsigned char *bufp = (const unsigned char *) buf;
+ 
+ 	assert(n >= 0);
+@@ -82,7 +82,7 @@ tds_put_n(TDSSOCKET * tds, const void *buf, int n)
+ 		} else {
+ 			memset(tds->out_buf + tds->out_pos, 0, left);
+ 		}
+-		tds->out_pos += left;
++		tds->out_pos += (unsigned int)left;
+ 		n -= left;
+ 	}
+ 	return 0;
+@@ -108,13 +108,13 @@ tds_put_string(TDSSOCKET * tds, const char *s, int len)
+ 
+ 	if (len < 0) {
+ 		if (client->min_bytes_per_char == 1) {	/* ascii or UTF-8 */
+-			len = strlen(s);
++			len = (int)strlen(s);
+ 		} else if (client->min_bytes_per_char == 2 && client->max_bytes_per_char == 2) {	/* UCS-2 or variant */
+ 			const char *p = s;
+ 
+ 			while (p[0] || p[1])
+ 				p += 2;
+-			len = p - s;
++			len = (int)(p - s);
+ 
+ 		} else {
+ 			assert(client->min_bytes_per_char < 3);	/* FIXME */
+@@ -162,7 +162,7 @@ tds_put_string(TDSSOCKET * tds, const char *s, int len)
+ 		tds_put_n(tds, outbuf, poutbuf - outbuf);
+ 	}
+ 	tdsdump_log(TDS_DBG_NETWORK, "tds_put_string wrote %d bytes\n", (int) bytes_out);
+-	return bytes_out;
++	return (int)bytes_out;
+ }
+ 
+ int
+@@ -269,7 +269,7 @@ tds_put_smallint(TDSSOCKET * tds, TDS_SMALLINT si)
+ int
+ tds_put_byte(TDSSOCKET * tds, unsigned char c)
+ {
+-	if (tds->out_pos >= tds->env.block_size)
++	if (tds->out_pos >= (unsigned int)tds->env.block_size)
+ 		tds_write_packet(tds, 0x0);
+ 	tds->out_buf[tds->out_pos++] = c;
+ 	return 0;
+
+commit 7846c87750ee2570a667526cb39662afc1d219cb
+Author: jklowden <jklowden>
+Date:   Fri Jan 16 20:31:10 2009 +0000
+
+    add Visual Studio project files
+
+diff --git a/ChangeLog b/ChangeLog
+index 4f8b5c7..0214083 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Fri Jan 16 15:28:57 EST 2009	JK Lowden <jklowden@freetds.org>
++	* FreeTDS.sln 
++	* src/ctlib/ct-lib.vcproj src/dblib/db-lib.vcproj
++	* src/odbc/odbc.vcproj src/replacements/replacements.vcproj
++	* src/tds/TDS.vcproj
++	- add Visual Studio project files
++
+ Fri Jan 16 15:19:20 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/md4.h include/md5.h
+ 	* include/replacements.h
+@@ -1203,4 +1210,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2709 2009/01/16 20:27:55 jklowden Exp $
++$Id: ChangeLog,v 1.2710 2009/01/16 20:31:10 jklowden Exp $
+diff --git a/FreeTDS.sln b/FreeTDS.sln
+new file mode 100755
+index 0000000..432ea3a
+--- /dev/null
++++ b/FreeTDS.sln
+@@ -0,0 +1,50 @@
++
++Microsoft Visual Studio Solution File, Format Version 9.00
++# Visual Studio 2005
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "TDS", "src\tds\TDS.vcproj", "{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}"
++EndProject
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "db-lib", "src\dblib\db-lib.vcproj", "{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}"
++	ProjectSection(ProjectDependencies) = postProject
++		{A7619118-36E9-434B-A87E-DBDEC14CF137} = {A7619118-36E9-434B-A87E-DBDEC14CF137}
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9} = {B9D6D61B-5E3B-42F4-A758-7A137594E3E9}
++	EndProjectSection
++EndProject
++Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "replacements", "src\replacements\replacements.vcproj", "{A7619118-36E9-434B-A87E-DBDEC14CF137}"
++EndProject
++Global
++	GlobalSection(SolutionConfigurationPlatforms) = preSolution
++		Debug|Win32 = Debug|Win32
++		Debug|x64 = Debug|x64
++		Release|Win32 = Release|Win32
++		Release|x64 = Release|x64
++	EndGlobalSection
++	GlobalSection(ProjectConfigurationPlatforms) = postSolution
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Debug|Win32.ActiveCfg = Debug|Win32
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Debug|Win32.Build.0 = Debug|Win32
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Debug|x64.ActiveCfg = Debug|x64
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Debug|x64.Build.0 = Debug|x64
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Release|Win32.ActiveCfg = Release|Win32
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Release|Win32.Build.0 = Release|Win32
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Release|x64.ActiveCfg = Release|x64
++		{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}.Release|x64.Build.0 = Release|x64
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Debug|Win32.ActiveCfg = Debug|Win32
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Debug|Win32.Build.0 = Debug|Win32
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Debug|x64.ActiveCfg = Debug|x64
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Debug|x64.Build.0 = Debug|x64
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Release|Win32.ActiveCfg = Release|Win32
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Release|Win32.Build.0 = Release|Win32
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Release|x64.ActiveCfg = Release|x64
++		{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}.Release|x64.Build.0 = Release|x64
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Debug|Win32.ActiveCfg = Debug|Win32
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Debug|Win32.Build.0 = Debug|Win32
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Debug|x64.ActiveCfg = Debug|x64
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Debug|x64.Build.0 = Debug|x64
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Release|Win32.ActiveCfg = Release|Win32
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Release|Win32.Build.0 = Release|Win32
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Release|x64.ActiveCfg = Release|x64
++		{A7619118-36E9-434B-A87E-DBDEC14CF137}.Release|x64.Build.0 = Release|x64
++	EndGlobalSection
++	GlobalSection(SolutionProperties) = preSolution
++		HideSolutionNode = FALSE
++	EndGlobalSection
++EndGlobal
+diff --git a/src/ctlib/ct-lib.vcproj b/src/ctlib/ct-lib.vcproj
+new file mode 100755
+index 0000000..8c087cd
+--- /dev/null
++++ b/src/ctlib/ct-lib.vcproj
+@@ -0,0 +1,184 @@
++<?xml version="1.0" encoding="Windows-1252"?>
++<VisualStudioProject
++	ProjectType="Visual C++"
++	Version="8.00"
++	Name="db-lib"
++	ProjectGUID="{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}"
++	RootNamespace="dblib"
++	>
++	<Platforms>
++		<Platform
++			Name="Win32"
++		/>
++	</Platforms>
++	<ToolFiles>
++	</ToolFiles>
++	<Configurations>
++		<Configuration
++			Name="Debug|Win32"
++			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="1"
++			CharacterSet="2"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				MinimalRebuild="true"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="3"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="4"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLinkerTool"
++				GenerateDebugInformation="true"
++				TargetMachine="1"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCManifestTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCAppVerifierTool"
++			/>
++			<Tool
++				Name="VCWebDeploymentTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|Win32"
++			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="1"
++			CharacterSet="2"
++			WholeProgramOptimization="1"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				RuntimeLibrary="2"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLinkerTool"
++				GenerateDebugInformation="true"
++				OptimizeReferences="2"
++				EnableCOMDATFolding="2"
++				TargetMachine="1"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCManifestTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCAppVerifierTool"
++			/>
++			<Tool
++				Name="VCWebDeploymentTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++	</Configurations>
++	<References>
++	</References>
++	<Files>
++		<Filter
++			Name="Source Files"
++			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
++			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
++			>
++		</Filter>
++		<Filter
++			Name="Header Files"
++			Filter="h;hpp;hxx;hm;inl;inc;xsd"
++			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
++			>
++		</Filter>
++		<Filter
++			Name="Resource Files"
++			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
++			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
++			>
++		</Filter>
++	</Files>
++	<Globals>
++	</Globals>
++</VisualStudioProject>
+diff --git a/src/dblib/db-lib.vcproj b/src/dblib/db-lib.vcproj
+new file mode 100755
+index 0000000..b42af8a
+--- /dev/null
++++ b/src/dblib/db-lib.vcproj
+@@ -0,0 +1,351 @@
++<?xml version="1.0" encoding="Windows-1252"?>
++<VisualStudioProject
++	ProjectType="Visual C++"
++	Version="8.00"
++	Name="db-lib"
++	ProjectGUID="{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}"
++	RootNamespace="dblib"
++	>
++	<Platforms>
++		<Platform
++			Name="Win32"
++		/>
++		<Platform
++			Name="x64"
++		/>
++	</Platforms>
++	<ToolFiles>
++	</ToolFiles>
++	<Configurations>
++		<Configuration
++			Name="Debug|Win32"
++			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				MinimalRebuild="true"
++				ExceptionHandling="0"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="1"
++				BrowseInformation="1"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="4"
++				CompileAs="1"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++				AdditionalDependencies="../tds/$(IntDir)/tds.lib ../replacements/$(IntDir)/replacements.lib"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Debug|x64"
++			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
++			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++				TargetEnvironment="3"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				MinimalRebuild="true"
++				ExceptionHandling="0"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="1"
++				BrowseInformation="1"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++				CompileAs="1"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++				AdditionalDependencies="../tds/$(IntDir)/tds.lib ../replacements/$(IntDir)/replacements.lib"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++				Description="Building dblib.lib using FreeTDS"
++				CommandLine="lib -OUT:dblib.lib ..\tds\$(IntDir)\db-lib.lib ../tds/$(IntDir)/db-lib.lib ../replacements/$(IntDir)/db-lib.lib  "
++				ExcludedFromBuild="true"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|Win32"
++			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			WholeProgramOptimization="1"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				RuntimeLibrary="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++				AdditionalDependencies="../tds/$(IntDir)/tds.lib ../replacements/$(IntDir)/replacements.lib"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|x64"
++			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
++			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			WholeProgramOptimization="1"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++				TargetEnvironment="3"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				RuntimeLibrary="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++				AdditionalDependencies="../tds/$(IntDir)/tds.lib ../replacements/$(IntDir)/replacements.lib"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++				Description="Building dblib.lib using FreeTDS"
++				CommandLine="lib -OUT:dblib.lib ..\tds\$(IntDir)\db-lib.lib ../tds/$(IntDir)/db-lib.lib ../replacements/$(IntDir)/db-lib.lib  "
++				ExcludedFromBuild="true"
++			/>
++		</Configuration>
++	</Configurations>
++	<References>
++	</References>
++	<Files>
++		<Filter
++			Name="Source Files"
++			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
++			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
++			>
++			<File
++				RelativePath=".\bcp.c"
++				>
++			</File>
++			<File
++				RelativePath=".\dblib.c"
++				>
++			</File>
++			<File
++				RelativePath=".\dbopen.c"
++				>
++			</File>
++			<File
++				RelativePath=".\dbutil.c"
++				>
++			</File>
++			<File
++				RelativePath=".\rpc.c"
++				>
++			</File>
++			<File
++				RelativePath=".\xact.c"
++				>
++			</File>
++		</Filter>
++		<Filter
++			Name="Header Files"
++			Filter="h;hpp;hxx;hm;inl;inc;xsd"
++			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
++			>
++			<File
++				RelativePath=".\buffering.h"
++				>
++			</File>
++			<File
++				RelativePath=".\error_table.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\sybdb.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\syberror.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\sybfront.h"
++				>
++			</File>
++		</Filter>
++		<Filter
++			Name="Resource Files"
++			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
++			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
++			>
++		</Filter>
++	</Files>
++	<Globals>
++	</Globals>
++</VisualStudioProject>
+diff --git a/src/odbc/odbc.vcproj b/src/odbc/odbc.vcproj
+new file mode 100755
+index 0000000..8c087cd
+--- /dev/null
++++ b/src/odbc/odbc.vcproj
+@@ -0,0 +1,184 @@
++<?xml version="1.0" encoding="Windows-1252"?>
++<VisualStudioProject
++	ProjectType="Visual C++"
++	Version="8.00"
++	Name="db-lib"
++	ProjectGUID="{F3CDE19D-7E97-4874-8E9F-994A82CDBDDA}"
++	RootNamespace="dblib"
++	>
++	<Platforms>
++		<Platform
++			Name="Win32"
++		/>
++	</Platforms>
++	<ToolFiles>
++	</ToolFiles>
++	<Configurations>
++		<Configuration
++			Name="Debug|Win32"
++			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="1"
++			CharacterSet="2"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				MinimalRebuild="true"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="3"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="4"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLinkerTool"
++				GenerateDebugInformation="true"
++				TargetMachine="1"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCManifestTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCAppVerifierTool"
++			/>
++			<Tool
++				Name="VCWebDeploymentTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|Win32"
++			OutputDirectory="$(SolutionDir)$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="1"
++			CharacterSet="2"
++			WholeProgramOptimization="1"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				RuntimeLibrary="2"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLinkerTool"
++				GenerateDebugInformation="true"
++				OptimizeReferences="2"
++				EnableCOMDATFolding="2"
++				TargetMachine="1"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCManifestTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCAppVerifierTool"
++			/>
++			<Tool
++				Name="VCWebDeploymentTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++	</Configurations>
++	<References>
++	</References>
++	<Files>
++		<Filter
++			Name="Source Files"
++			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
++			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
++			>
++		</Filter>
++		<Filter
++			Name="Header Files"
++			Filter="h;hpp;hxx;hm;inl;inc;xsd"
++			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
++			>
++		</Filter>
++		<Filter
++			Name="Resource Files"
++			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
++			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
++			>
++		</Filter>
++	</Files>
++	<Globals>
++	</Globals>
++</VisualStudioProject>
+diff --git a/src/replacements/replacements.vcproj b/src/replacements/replacements.vcproj
+new file mode 100755
+index 0000000..d38ed72
+--- /dev/null
++++ b/src/replacements/replacements.vcproj
+@@ -0,0 +1,387 @@
++<?xml version="1.0" encoding="Windows-1252"?>
++<VisualStudioProject
++	ProjectType="Visual C++"
++	Version="8.00"
++	Name="replacements"
++	ProjectGUID="{A7619118-36E9-434B-A87E-DBDEC14CF137}"
++	RootNamespace="replacements"
++	>
++	<Platforms>
++		<Platform
++			Name="Win32"
++		/>
++		<Platform
++			Name="x64"
++		/>
++	</Platforms>
++	<ToolFiles>
++	</ToolFiles>
++	<Configurations>
++		<Configuration
++			Name="Debug|Win32"
++			OutputDirectory="$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				MinimalRebuild="true"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="1"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="4"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Debug|x64"
++			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
++			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++				TargetEnvironment="3"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				MinimalRebuild="true"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="1"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|Win32"
++			OutputDirectory="$(ConfigurationName)"
++			IntermediateDirectory="$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			WholeProgramOptimization="1"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				RuntimeLibrary="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|x64"
++			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
++			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
++			ConfigurationType="4"
++			CharacterSet="2"
++			WholeProgramOptimization="1"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++				TargetEnvironment="3"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				PreprocessorDefinitions="HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				RuntimeLibrary="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++	</Configurations>
++	<References>
++	</References>
++	<Files>
++		<Filter
++			Name="Source Files"
++			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
++			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
++			>
++			<File
++				RelativePath=".\asprintf.c"
++				>
++				<FileConfiguration
++					Name="Debug|Win32"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++						ShowIncludes="false"
++					/>
++				</FileConfiguration>
++				<FileConfiguration
++					Name="Debug|x64"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++						ShowIncludes="false"
++					/>
++				</FileConfiguration>
++			</File>
++			<File
++				RelativePath=".\atoll.c"
++				>
++				<FileConfiguration
++					Name="Debug|Win32"
++					ExcludedFromBuild="true"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++					/>
++				</FileConfiguration>
++				<FileConfiguration
++					Name="Debug|x64"
++					ExcludedFromBuild="true"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++					/>
++				</FileConfiguration>
++				<FileConfiguration
++					Name="Release|Win32"
++					ExcludedFromBuild="true"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++					/>
++				</FileConfiguration>
++				<FileConfiguration
++					Name="Release|x64"
++					ExcludedFromBuild="true"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++					/>
++				</FileConfiguration>
++			</File>
++			<File
++				RelativePath=".\basename.c"
++				>
++			</File>
++			<File
++				RelativePath=".\fakepoll.c"
++				>
++			</File>
++			<File
++				RelativePath=".\gettimeofday.c"
++				>
++			</File>
++			<File
++				RelativePath=".\iconv.c"
++				>
++			</File>
++			<File
++				RelativePath=".\readpassphrase.c"
++				>
++			</File>
++			<File
++				RelativePath=".\strlcat.c"
++				>
++			</File>
++			<File
++				RelativePath=".\strlcpy.c"
++				>
++			</File>
++			<File
++				RelativePath=".\strtok_r.c"
++				>
++			</File>
++			<File
++				RelativePath=".\vasprintf.c"
++				>
++			</File>
++		</Filter>
++		<Filter
++			Name="Header Files"
++			Filter="h;hpp;hxx;hm;inl;inc;xsd"
++			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
++			>
++			<File
++				RelativePath=".\fakepoll.h"
++				>
++			</File>
++		</Filter>
++		<Filter
++			Name="Resource Files"
++			Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
++			UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
++			>
++		</Filter>
++	</Files>
++	<Globals>
++	</Globals>
++</VisualStudioProject>
+diff --git a/src/tds/TDS.vcproj b/src/tds/TDS.vcproj
+new file mode 100755
+index 0000000..8faeebb
+--- /dev/null
++++ b/src/tds/TDS.vcproj
+@@ -0,0 +1,455 @@
++<?xml version="1.0" encoding="UTF-8"?>
++<VisualStudioProject
++	ProjectType="Visual C++"
++	Version="8.00"
++	Name="TDS"
++	ProjectGUID="{B9D6D61B-5E3B-42F4-A758-7A137594E3E9}"
++	Keyword="Win32Proj"
++	>
++	<Platforms>
++		<Platform
++			Name="Win32"
++		/>
++		<Platform
++			Name="x64"
++		/>
++	</Platforms>
++	<ToolFiles>
++	</ToolFiles>
++	<Configurations>
++		<Configuration
++			Name="Debug|Win32"
++			OutputDirectory="Debug"
++			IntermediateDirectory="Debug"
++			ConfigurationType="4"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				AdditionalIncludeDirectories="../../include;../../include/x64"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				MinimalRebuild="true"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="1"
++				UsePrecompiledHeader="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="4"
++				ShowIncludes="false"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Debug|x64"
++			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
++			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
++			ConfigurationType="4"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++				TargetEnvironment="3"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				Optimization="0"
++				AdditionalIncludeDirectories="../../include;../../include/x64"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				MinimalRebuild="true"
++				ExceptionHandling="0"
++				BasicRuntimeChecks="3"
++				RuntimeLibrary="1"
++				UsePrecompiledHeader="0"
++				BrowseInformation="1"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++				CompileAs="1"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|Win32"
++			OutputDirectory="Release"
++			IntermediateDirectory="Release"
++			ConfigurationType="4"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				AdditionalIncludeDirectories="../../include;../../include/x64"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				RuntimeLibrary="0"
++				UsePrecompiledHeader="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++		<Configuration
++			Name="Release|x64"
++			OutputDirectory="$(PlatformName)\$(ConfigurationName)"
++			IntermediateDirectory="$(PlatformName)\$(ConfigurationName)"
++			ConfigurationType="4"
++			>
++			<Tool
++				Name="VCPreBuildEventTool"
++			/>
++			<Tool
++				Name="VCCustomBuildTool"
++			/>
++			<Tool
++				Name="VCXMLDataGeneratorTool"
++			/>
++			<Tool
++				Name="VCWebServiceProxyGeneratorTool"
++			/>
++			<Tool
++				Name="VCMIDLTool"
++				TargetEnvironment="3"
++			/>
++			<Tool
++				Name="VCCLCompilerTool"
++				AdditionalIncludeDirectories="../../include;../../include/x64"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				RuntimeLibrary="0"
++				UsePrecompiledHeader="0"
++				WarningLevel="3"
++				Detect64BitPortabilityProblems="true"
++				DebugInformationFormat="3"
++			/>
++			<Tool
++				Name="VCManagedResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCResourceCompilerTool"
++			/>
++			<Tool
++				Name="VCPreLinkEventTool"
++			/>
++			<Tool
++				Name="VCLibrarianTool"
++			/>
++			<Tool
++				Name="VCALinkTool"
++			/>
++			<Tool
++				Name="VCXDCMakeTool"
++			/>
++			<Tool
++				Name="VCBscMakeTool"
++			/>
++			<Tool
++				Name="VCFxCopTool"
++			/>
++			<Tool
++				Name="VCPostBuildEventTool"
++			/>
++		</Configuration>
++	</Configurations>
++	<References>
++	</References>
++	<Files>
++		<Filter
++			Name="Header Files"
++			Filter="h;hpp;hxx;hm;inl;inc;xsd"
++			UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
++			>
++			<File
++				RelativePath=".\alternative_character_sets.h"
++				>
++			</File>
++			<File
++				RelativePath=".\character_sets.h"
++				>
++			</File>
++			<File
++				RelativePath=".\unittests\common.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\x64\config.h"
++				>
++			</File>
++			<File
++				RelativePath=".\enum_cap.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\x64\mscompat.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\x64\num_limits.h"
++				>
++			</File>
++			<File
++				RelativePath=".\sybase_character_sets.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\tds.h"
++				>
++			</File>
++			<File
++				RelativePath=".\tds_checks.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\tds_sysdep_private.h"
++				>
++			</File>
++			<File
++				RelativePath="..\..\include\x64\tds_sysdep_public.h"
++				>
++			</File>
++		</Filter>
++		<Filter
++			Name="Source Files"
++			Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
++			UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
++			>
++			<File
++				RelativePath=".\bulk.c"
++				>
++			</File>
++			<File
++				RelativePath=".\challenge.c"
++				>
++			</File>
++			<File
++				RelativePath=".\unittests\common.c"
++				>
++			</File>
++			<File
++				RelativePath=".\config.c"
++				>
++				<FileConfiguration
++					Name="Debug|Win32"
++					>
++					<Tool
++						Name="VCCLCompilerTool"
++						ShowIncludes="false"
++					/>
++				</FileConfiguration>
++			</File>
++			<File
++				RelativePath=".\convert.c"
++				>
++			</File>
++			<File
++				RelativePath=".\data.c"
++				>
++			</File>
++			<File
++				RelativePath=".\des.c"
++				>
++			</File>
++			<File
++				RelativePath=".\getmac.c"
++				>
++			</File>
++			<File
++				RelativePath=".\gssapi.c"
++				>
++			</File>
++			<File
++				RelativePath=".\hmac_md5.c"
++				>
++			</File>
++			<File
++				RelativePath=".\iconv.c"
++				>
++			</File>
++			<File
++				RelativePath=".\locale.c"
++				>
++			</File>
++			<File
++				RelativePath=".\log.c"
++				>
++			</File>
++			<File
++				RelativePath=".\login.c"
++				>
++			</File>
++			<File
++				RelativePath=".\md4.c"
++				>
++			</File>
++			<File
++				RelativePath=".\md5.c"
++				>
++			</File>
++			<File
++				RelativePath=".\mem.c"
++				>
++			</File>
++			<File
++				RelativePath=".\net.c"
++				>
++			</File>
++			<File
++				RelativePath=".\numeric.c"
++				>
++			</File>
++			<File
++				RelativePath=".\query.c"
++				>
++			</File>
++			<File
++				RelativePath=".\read.c"
++				>
++			</File>
++			<File
++				RelativePath=".\tds_checks.c"
++				>
++			</File>
++			<File
++				RelativePath=".\tdsstring.c"
++				>
++			</File>
++			<File
++				RelativePath=".\threadsafe.c"
++				>
++			</File>
++			<File
++				RelativePath=".\token.c"
++				>
++			</File>
++			<File
++				RelativePath=".\util.c"
++				>
++			</File>
++			<File
++				RelativePath=".\vstrbuild.c"
++				>
++			</File>
++			<File
++				RelativePath=".\write.c"
++				>
++			</File>
++		</Filter>
++	</Files>
++	<Globals>
++	</Globals>
++</VisualStudioProject>
+
+commit 75c95f4e4d658ee6d96e28f794d73e04b7bdf358
+Author: freddy77 <freddy77>
+Date:   Mon Jan 19 14:37:24 2009 +0000
+
+    dos2unix
+
+diff --git a/ChangeLog b/ChangeLog
+index 0214083..751233c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 19 15:36:50 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: dos2unix
++
+ Fri Jan 16 15:28:57 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* FreeTDS.sln 
+ 	* src/ctlib/ct-lib.vcproj src/dblib/db-lib.vcproj
+@@ -1210,4 +1213,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2710 2009/01/16 20:31:10 jklowden Exp $
++$Id: ChangeLog,v 1.2711 2009/01/19 14:37:24 freddy77 Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 2c027a1..75e13de 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.185 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.186 2009/01/19 14:37:24 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -620,19 +620,19 @@ static int
+ winsock_initialized()
+ {
+ #if defined(_WIN32) || defined(_WIN64)
+-	WSADATA wsa_data;
+-	int erc;
++	WSADATA wsa_data;
++	int erc;
+ 	DWORD how_much = 0;
+-	WORD requested_version = MAKEWORD(2, 2);
+-	 
+-	if (SOCKET_ERROR != WSAEnumProtocols(NULL, NULL, &how_much)) 
++	WORD requested_version = MAKEWORD(2, 2);
++
++	if (SOCKET_ERROR != WSAEnumProtocols(NULL, NULL, &how_much))
+ 		return 1;
+ 
+-	if (WSANOTINITIALISED != WSAGetLastError()) 
++	if (WSANOTINITIALISED != WSAGetLastError())
+ 		return 0;
+-	
++
+ 	if (SOCKET_ERROR == (erc = WSAStartup(requested_version, &wsa_data))) {
+-		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d(%s)\n", erc, WSAGetLastError() ); 
++		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d(%s)\n", erc, WSAGetLastError() );
+ 		return 0;
+ 	}
+ #endif
+
+commit fdbff5ae722033ddb8028358f25dda358e5d506c
+Author: freddy77 <freddy77>
+Date:   Wed Jan 21 08:34:01 2009 +0000
+
+    fix unsigned/signed issues
+
+diff --git a/ChangeLog b/ChangeLog
+index 751233c..51b679c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jan 21 09:33:39 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/vasprintf.c: fix portability problem
++	* src/tds/challenge.c: check correctly error converting to ucs2
++
+ Mon Jan 19 15:36:50 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/mem.c: dos2unix
+ 
+@@ -1213,4 +1217,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2711 2009/01/19 14:37:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2712 2009/01/21 08:34:01 freddy77 Exp $
+diff --git a/src/replacements/vasprintf.c b/src/replacements/vasprintf.c
+index 7d1ded4..9183903 100644
+--- a/src/replacements/vasprintf.c
++++ b/src/replacements/vasprintf.c
+@@ -30,7 +30,7 @@
+ #include "tds_sysdep_private.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: vasprintf.c,v 1.19 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: vasprintf.c,v 1.20 2009/01/21 08:34:01 freddy77 Exp $");
+ 
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef HAVE_VSNPRINTF
+@@ -67,10 +67,10 @@ vasprintf(char **ret, const char *fmt, va_list ap)
+ 		free(buf);
+ 		buflen = (++chunks) * CHUNKSIZE;
+ 		/* 
+-		 * len >= 0 are required for vsnprintf implementation that 
+-		 * return -1 of buffer insufficient
++		 * len >= 0 is required for vsnprintf implementations that 
++		 * return -1 for insufficient buffer
+ 		 */
+-		if (buflen <= (size_t) len) {
++		if (len >= 0 && buflen <= (size_t) len) {
+ 			buflen = len + 1;
+ 		}
+ 	}
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index 6a4c0d1..ae0b7a0 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2005-2008  Frediano Ziglio
++ * Copyright (C) 2005-2009  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.37 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.38 2009/01/21 08:34:01 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -123,7 +123,7 @@ convert_to_usc2le_string(TDSSOCKET * tds, const char *s, size_t len, char *out)
+ 	ol = len * 2;
+ 	memset(suppress, 0, sizeof(char_conv->suppress));
+ 	if (tds_iconv(tds, char_conv, to_server, &ib, &il, &ob, &ol) == (size_t) - 1)
+-		return -1;
++		return (size_t) -1;
+ 
+ 	return ob - out;
+ }
+@@ -153,7 +153,7 @@ make_ntlm_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_hash[16])
+ 		passwd_len = 128;
+ 
+ 	passwd_usc2le_len = convert_to_usc2le_string(tds, passwd, passwd_len, passwd_usc2le);
+-	if (passwd_usc2le_len < 0) {
++	if (passwd_usc2le_len == (size_t) -1) {
+ 		memset((char *) passwd_usc2le, 0, sizeof(passwd_usc2le));
+ 		return TDS_FAIL;
+ 	}
+@@ -200,7 +200,7 @@ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_has
+ 	convert_to_upper(buf, user_name_len);
+ 
+ 	len = convert_to_usc2le_string(tds, buf, user_name_len, buf_usc2le);
+-	if (len < 0)
++	if (len == (size_t) -1)
+ 		return TDS_FAIL;
+ 	buf_usc2le_len = len;
+ 
+@@ -209,7 +209,7 @@ make_ntlm_v2_hash(TDSSOCKET * tds, const char *passwd, unsigned char ntlm_v2_has
+ 	/* Target is supposed to be case-sensitive */
+ 
+ 	len = convert_to_usc2le_string(tds, domain, domain_len, buf_usc2le + len);
+-	if (len < 0)
++	if (len == (size_t) -1)
+ 		return TDS_FAIL;
+ 	buf_usc2le_len += len;
+ 
+@@ -265,8 +265,6 @@ tds_answer_challenge(TDSSOCKET * tds,
+ {
+ #define MAX_PW_SZ 14
+ 	const char *passwd = tds_dstr_cstr(&connection->password);
+-	size_t len;
+-	size_t i;
+ 	static const des_cblock magic = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 };
+ 	DES_KEY ks;
+ 	unsigned char hash[24], ntlm2_challenge[16];
+@@ -276,6 +274,7 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 
+ 	if (!(*flags & 0x80000)) {
+ 		/* NTLM */
++		size_t len, i;
+ 		unsigned char passwd_buf[MAX_PW_SZ];
+ 
+ 		/* convert password to upper and pad to 14 chars */
+@@ -456,7 +455,7 @@ tds7_send_auth(TDSSOCKET * tds,
+ 	tds_put_int(tds, 3);	/* sequence 3 */
+ 
+ 	/* FIXME *2 work only for single byte encodings */
+-	current_pos = 64 + (domain_len + user_name_len + host_name_len) * 2;
++	current_pos = 64u + (domain_len + user_name_len + host_name_len) * 2u;
+ 
+ 	/* LM/LMv2 Response */
+ 	tds_put_smallint(tds, lm_response_len);	/* lan man resp length */
+@@ -475,19 +474,19 @@ tds7_send_auth(TDSSOCKET * tds,
+ 	TDS_PUT_SMALLINT(tds, domain_len * 2);
+ 	TDS_PUT_SMALLINT(tds, domain_len * 2);
+ 	TDS_PUT_INT(tds, current_pos);
+-	current_pos += domain_len * 2;
++	current_pos += domain_len * 2u;
+ 
+ 	/* username */
+ 	TDS_PUT_SMALLINT(tds, user_name_len * 2);
+ 	TDS_PUT_SMALLINT(tds, user_name_len * 2);
+ 	TDS_PUT_INT(tds, current_pos);
+-	current_pos += user_name_len * 2;
++	current_pos += user_name_len * 2u;
+ 
+ 	/* Workstation Name */
+ 	TDS_PUT_SMALLINT(tds, host_name_len * 2);
+ 	TDS_PUT_SMALLINT(tds, host_name_len * 2);
+ 	TDS_PUT_INT(tds, current_pos);
+-	current_pos += host_name_len * 2;
++	current_pos += host_name_len * 2u;
+ 
+ 	/* Session Key (optional) */
+ 	tds_put_smallint(tds, 0);
+
+commit 9d65511e89e48530e3b246e6f63d431956835a9c
+Author: freddy77 <freddy77>
+Date:   Wed Jan 21 08:43:54 2009 +0000
+
+    make fakepoll compile
+
+diff --git a/ChangeLog b/ChangeLog
+index 51b679c..c851bde 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jan 21 09:43:32 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/fakepoll.c: make it compile
++
+ Wed Jan 21 09:33:39 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/vasprintf.c: fix portability problem
+ 	* src/tds/challenge.c: check correctly error converting to ucs2
+@@ -1217,4 +1220,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2712 2009/01/21 08:34:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2713 2009/01/21 08:43:54 freddy77 Exp $
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index be525d8..753153e 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -1,4 +1,3 @@
+-#ifndef HAVE_POLL
+ /*
+  * poll(2) implemented with select(2), for systems without poll(2). 
+  * Warning: a call to this poll() takes about 4K of stack space.
+@@ -18,10 +17,19 @@
+  * Converted to C and spruced up by James K. Lowden December 2008. 
+  */
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.6 2009/01/16 20:27:58 jklowden Exp $";
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#ifndef HAVE_POLL
++
++static char software_version[] = "$Id: fakepoll.c,v 1.7 2009/01/21 08:43:54 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#include <replacements.h>
++#include <stdarg.h>
++#include <stdio.h>
++
++#include "replacements.h"
+ 
+ #if HAVE_SYS_TYPES_H
+ #include <sys/types.h>
+
+commit 5570f71f1cef9bd654151046567d71f54fe01fc3
+Author: freddy77 <freddy77>
+Date:   Fri Jan 23 09:42:36 2009 +0000
+
+    remove buffer overflow reading
+
+diff --git a/ChangeLog b/ChangeLog
+index c851bde..76cc17e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 23 10:42:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: remove buffer overflow reading
++
+ Wed Jan 21 09:43:32 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/fakepoll.c: make it compile
+ 
+@@ -1220,4 +1223,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2713 2009/01/21 08:43:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2714 2009/01/23 09:42:36 freddy77 Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 6b1ed45..17490fa 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.180 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.181 2009/01/23 09:42:36 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -506,14 +506,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ static int
+ tds_put_login_string(TDSSOCKET * tds, const char *buf, int n)
+ {
+-	char string[32];
+ 	const int buf_len = buf ? (int)strlen(buf) : 0;
+-	memset(string, '<', sizeof(string));
+-	memcpy(string, buf, n);
+-	string[sizeof(string)-1] = '\0';
+-	if(n)
+-		tdsdump_dump_buf(TDS_DBG_INFO1, "login string", buf, n);
+-
+ 	return tds_put_buf(tds, (const unsigned char *) buf, n, buf_len);
+ }
+ 
+
+commit 6b4affc9d96da0f3b19d49312b1fa8572d140e0f
+Author: freddy77 <freddy77>
+Date:   Fri Jan 23 10:37:35 2009 +0000
+
+    fix minor unsigned/signed issues
+
+diff --git a/ChangeLog b/ChangeLog
+index 76cc17e..7800097 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jan 23 11:35:21 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c src/tds/query.c src/tds/write.c:
++	- fix minor unsigned/signed issues
++
+ Fri Jan 23 10:42:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/login.c: remove buffer overflow reading
+ 
+@@ -1223,4 +1227,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2714 2009/01/23 09:42:36 freddy77 Exp $
++$Id: ChangeLog,v 1.2715 2009/01/23 10:37:35 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 970be28..898f7a6 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.338 2009/01/16 20:27:57 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.339 2009/01/23 10:37:35 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1834,6 +1834,7 @@ RETCODE
+ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ {
+ 	BYTE *pval;
++	size_t len;
+ 	
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsetnull(%p, %d, %d, %p)\n", dbproc, bindtype, bindlen, bindval);
+ 	
+@@ -1853,21 +1854,22 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 	case SMALLDATETIMEBIND:
+ 	case SMALLMONEYBIND:
+ 	case TINYBIND:
+-		bindlen = (int)default_null_representations[bindtype].len;
++		len = default_null_representations[bindtype].len;
+ 		break;
+ 
+ 	case CHARBIND:
+ 	case BINARYBIND:
+ 		CHECK_PARAMETER(bindlen >= 0, SYBEBBL, FAIL);
++		len = bindlen;
+ 		break;
+ 		
+-	case NTBSTRINGBIND:	bindlen = (int)strlen((char *) bindval);
++	case NTBSTRINGBIND:	len = strlen((char *) bindval);
+ 		break;
+-	case STRINGBIND:	bindlen = (int)strlen((char *) bindval);
++	case STRINGBIND:	len = strlen((char *) bindval);
+ 		break;
+-	case VARYBINBIND:	bindlen = ((TDS_VARBINARY*) bindval)->len;
++	case VARYBINBIND:	len = ((TDS_VARBINARY*) bindval)->len;
+ 		break;
+-	case VARYCHARBIND:	bindlen = ((TDS_VARCHAR*) bindval)->len;
++	case VARYCHARBIND:	len = ((TDS_VARCHAR*) bindval)->len;
+ 		break;
+ 
+ #if 0
+@@ -1879,7 +1881,7 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 		return FAIL;
+ 	}
+ 
+-	if ((pval = malloc(bindlen)) == NULL) {
++	if ((pval = malloc(len)) == NULL) {
+ 		dbperror(dbproc, SYBEMEM, errno);
+ 		return FAIL;
+ 	}
+@@ -1888,12 +1890,12 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 	if (dbproc->nullreps[bindtype].bindval != default_null_representations[bindtype].bindval)
+ 		free((BYTE*)dbproc->nullreps[bindtype].bindval);
+ 
+-	memcpy(pval, bindval, bindlen);
++	memcpy(pval, bindval, len);
+ 	
+ 	dbproc->nullreps[bindtype].bindval = pval;
+-	dbproc->nullreps[bindtype].len = bindlen;
++	dbproc->nullreps[bindtype].len = len;
+ 
+-	tdsdump_dump_buf(TDS_DBG_NETWORK, "null representation set ", pval,  bindlen);
++	tdsdump_dump_buf(TDS_DBG_NETWORK, "null representation set ", pval,  len);
+ 	return SUCCEED;
+ }
+ 
+@@ -4607,7 +4609,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 				}
+ 				break;
+ #else
+-				retcode = (done_flags & TDS_DONE_ERROR)? FAIL : SUCCEED;
++				int retcode = (done_flags & TDS_DONE_ERROR)? FAIL : SUCCEED;
+ 				dbproc->dbresults_state = (done_flags & TDS_DONE_MORE_RESULTS)?
+ 					_DB_RES_NEXT_RESULT : _DB_RES_NO_MORE_RESULTS;
+ 
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 04828ba..59a7c44 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.229 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.230 2009/01/23 10:37:36 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -55,7 +55,7 @@ static int tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags);
+ static int tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ static char *tds7_build_param_def_from_query(TDSSOCKET * tds, const char* converted_query, size_t converted_query_len, TDSPARAMINFO * params, size_t *out_len);
+ static char *tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t query_len, TDSPARAMINFO * params, size_t *out_len);
+-static int tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol);
++static size_t tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ 
+ static int tds_send_emulated_execute(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
+ static const char *tds_skip_comment(const char *s);
+@@ -131,21 +131,19 @@ tds_convert_string(TDSSOCKET * tds, const TDSICONV * char_conv, const char *s, i
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 
+-	if (len < 0)
+-		len = (int)strlen(s);
++	il = len < 0 ? strlen(s) : len;
+ 	if (char_conv->flags == TDS_ENCODING_MEMCPY) {
+-		*out_len = len;
++		*out_len = il;
+ 		return s;
+ 	}
+ 
+ 	/* allocate needed buffer (+1 is to exclude 0 case) */
+-	ol = len * char_conv->server_charset.max_bytes_per_char / char_conv->client_charset.min_bytes_per_char + 1;
++	ol = il * char_conv->server_charset.max_bytes_per_char / char_conv->client_charset.min_bytes_per_char + 1;
+ 	buf = (char *) malloc(ol);
+ 	if (!buf)
+ 		return NULL;
+ 
+ 	ib = s;
+-	il = len;
+ 	ob = buf;
+ 	memset(suppress, 0, sizeof(char_conv->suppress));
+ 	if (tds_iconv(tds, char_conv, to_server, &ib, &il, &ob, &ol) == (size_t)-1) {
+@@ -349,7 +347,7 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 			 * TODO perhaps functions that calls tds7_build_param_def_from_query
+ 			 * should call also tds7_build_param_def_from_params ??
+ 			 */
+-			param_definition = tds7_build_param_def_from_query(tds, converted_query, (int)converted_query_len, params, &definition_len);
++			param_definition = tds7_build_param_def_from_query(tds, converted_query, converted_query_len, params, &definition_len);
+ 			if (!param_definition) {
+ 				tds_set_state(tds, TDS_IDLE);
+ 				return TDS_FAIL;
+@@ -614,8 +612,9 @@ static int
+ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ {
+ 	const char *fmt = NULL;
+-	int max_len = IS_TDS7_PLUS(tds) ? 8000 : 255;
+-	int size;
++	/* unsigned int is required by printf format, don't use size_t */
++	unsigned int max_len = IS_TDS7_PLUS(tds) ? 8000 : 255;
++	unsigned int size;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+@@ -625,11 +624,11 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 	switch (tds_get_conversion_type(curcol->on_server.column_type, curcol->on_server.column_size)) {
+ 	case XSYBCHAR:
+ 	case SYBCHAR:
+-		fmt = "CHAR(%d)";
++		fmt = "CHAR(%u)";
+ 		break;
+ 	case SYBVARCHAR:
+ 	case XSYBVARCHAR:
+-		fmt = "VARCHAR(%d)";
++		fmt = "VARCHAR(%u)";
+ 		break;
+ 	case SYBINT1:
+ 		fmt = "TINYINT";
+@@ -674,11 +673,11 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 		break;
+ 	case SYBBINARY:
+ 	case XSYBBINARY:
+-		fmt = "BINARY(%d)";
++		fmt = "BINARY(%u)";
+ 		break;
+ 	case SYBVARBINARY:
+ 	case XSYBVARBINARY:
+-		fmt = "VARBINARY(%d)";
++		fmt = "VARBINARY(%u)";
+ 		break;
+ 	case SYBNUMERIC:
+ 		fmt = "NUMERIC(%d,%d)";
+@@ -700,16 +699,16 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 	case SYBNVARCHAR:
+ 	case XSYBNVARCHAR:
+ 		if (IS_TDS7_PLUS(tds)) {
+-			fmt = "NVARCHAR(%d)";
++			fmt = "NVARCHAR(%u)";
+ 			max_len = 4000;
+-			size /= 2;
++			size /= 2u;
+ 		}
+ 		break;
+ 	case XSYBNCHAR:
+ 		if (IS_TDS7_PLUS(tds)) {
+-			fmt = "NCHAR(%d)";
++			fmt = "NCHAR(%u)";
+ 			max_len = 4000;
+-			size /= 2;
++			size /= 2u;
+ 		}
+ 		break;
+ 		/* nullable types should not occur here... */
+@@ -731,7 +730,7 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 
+ 	if (fmt) {
+ 		/* fill out */
+-		sprintf(out, fmt, size > 0 ? (size > max_len ? max_len : size) : 1);
++		sprintf(out, fmt, size > 0 ? (size > max_len ? max_len : size) : 1u);
+ 		return TDS_SUCCEED;
+ 	}
+ 
+@@ -950,7 +949,7 @@ tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len)
+ 	tds_put_byte(tds, 0);
+ 	tds_put_byte(tds, 0);
+ 	tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+-	len = 2 * len + query_len;
++	len = 2u * len + query_len;
+ 	TDS_PUT_INT(tds, len);
+ 	if (IS_TDS8_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+@@ -1077,7 +1076,7 @@ tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMI
+ 		tds_put_byte(tds, 0);
+ 
+ 		tds7_put_params_definition(tds, param_definition, definition_len);
+-		tds7_put_query_params(tds, converted_query, (int)converted_query_len);
++		tds7_put_query_params(tds, converted_query, converted_query_len);
+ 		tds_convert_string_free(query, converted_query);
+ 		free(param_definition);
+ 
+@@ -1267,15 +1266,15 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ /**
+  * Get column size for wire
+  */
+-static int
++static size_t
+ tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ {
+-	int size = curcol->on_server.column_size, min;
++	size_t size = curcol->on_server.column_size, min;
+ 
+ 	if (!size) {
+ 		size = curcol->column_size;
+ 		if (is_unicode_type(curcol->on_server.column_type))
+-			size *= 2;
++			size *= 2u;
+ 	}
+ 
+ 	switch (curcol->column_varint_size) {
+@@ -1290,13 +1289,13 @@ tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			min = 2;
+ 		else
+ 			min = 1;
+-		size = MAX(MIN(size, 8000), min);
++		size = MAX(MIN(size, 8000u), min);
+ 		break;
+ 	case 4:
+ 		if (curcol->on_server.column_type == SYBNTEXT)
+-			size = MAX(MIN(size, 0x7ffffffe), 2);
++			size = MAX(MIN(size, 0x7ffffffeu), 2u);
+ 		else
+-			size = MAX(MIN(size, 0x7fffffff), 1);
++			size = MAX(MIN(size, 0x7fffffffu), 1u);
+ 		break;
+ 	}
+ /*	return curcol->on_server.column_size = size; */
+@@ -1358,7 +1357,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 	tds_put_byte(tds, curcol->column_output);	/* status (input) */
+ 	if (!IS_TDS7_PLUS(tds))
+ 		tds_put_int(tds, curcol->column_usertype);	/* usertype */
+-	// FIXME: column_type is wider than one byte.  Do something sensible, not just lop off the high byte. 
++	/* FIXME: column_type is wider than one byte.  Do something sensible, not just lop off the high byte. */
+ 	tds_put_byte(tds, curcol->on_server.column_type);
+ 
+ 	if (is_numeric_type(curcol->on_server.column_type)) {
+@@ -1373,7 +1372,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 		tds_put_byte(tds, num->scale);
+ #endif
+ 	} else {
+-		int size = tds_fix_column_size(tds, curcol);
++		size_t size = tds_fix_column_size(tds, curcol);
+ 		switch (curcol->column_varint_size) {
+ 		case 0:
+ 			break;
+@@ -1442,17 +1441,16 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	unsigned char *src;
+ 	TDS_NUMERIC *num;
+ 	TDSBLOB *blob = NULL;
+-	TDS_INT colsize, size;
++	size_t colsize, size;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
+-	colsize = curcol->column_cur_size;
+ 	src = curcol->column_data;
+ 
+ 	tdsdump_log(TDS_DBG_INFO1, "tds_put_data: colsize = %d\n", (int) colsize);
+ 
+-	if (colsize < 0) {
++	if (curcol->column_cur_size < 0) {
+ 		tdsdump_log(TDS_DBG_INFO1, "tds_put_data: null param\n");
+ 		switch (curcol->column_varint_size) {
+ 		case 4:
+@@ -1469,6 +1467,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		}
+ 		return TDS_SUCCEED;
+ 	}
++	colsize = curcol->column_cur_size;
+ 
+ 	size = tds_fix_column_size(tds, curcol);
+ 
+@@ -2100,9 +2099,6 @@ tds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, in
+ int
+ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *something_to_send)
+ {
+-	size_t converted_query_len;
+-	const char *converted_query;
+-
+ 	CHECK_TDS_EXTRA(tds);
+ 
+ 	if (!cursor)
+@@ -2134,7 +2130,8 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 		*something_to_send = 1;
+ 	}
+ 	if (IS_TDS7_PLUS(tds)) {
+-		size_t definition_len = 0;
++		const char *converted_query;
++		size_t definition_len = 0, converted_query_len;
+ 		char *param_definition = NULL;
+ 		int num_params = params ? params->num_cols : 0;
+ 
+diff --git a/src/tds/write.c b/src/tds/write.c
+index 5e70c56..1eb1d1a 100644
+--- a/src/tds/write.c
++++ b/src/tds/write.c
+@@ -49,7 +49,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: write.c,v 1.77 2009/01/16 20:27:59 jklowden Exp $");
++TDS_RCSID(var, "$Id: write.c,v 1.78 2009/01/23 10:37:36 freddy77 Exp $");
+ 
+ /**
+  * \addtogroup network
+@@ -66,8 +66,6 @@ tds_put_n(TDSSOCKET * tds, const void *buf, size_t n)
+ 	size_t left;
+ 	const unsigned char *bufp = (const unsigned char *) buf;
+ 
+-	assert(n >= 0);
+-
+ 	for (; n;) {
+ 		left = tds->env.block_size - tds->out_pos;
+ 		if (left <= 0) {
+@@ -149,7 +147,7 @@ tds_put_string(TDSSOCKET * tds, const char *s, int len)
+ 				tdsdump_log(TDS_DBG_NETWORK, "Error: tds_put_string: "
+ 							     "Gave up converting %d bytes due to error %d.\n", 
+ 							     (int) inbytesleft, errno);
+-				tdsdump_dump_buf(TDS_DBG_NETWORK, "Troublesome bytes", s, (int) inbytesleft);
++				tdsdump_dump_buf(TDS_DBG_NETWORK, "Troublesome bytes", s, inbytesleft);
+ 			}
+ 
+ 			if (poutbuf == outbuf) {	/* tds_iconv did not convert anything, avoid infinite loop */
+
+commit e764626d1ba2c7a922078d5a0e908f3b2f20c2e8
+Author: freddy77 <freddy77>
+Date:   Fri Jan 23 10:42:25 2009 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index 7800097..a91b761 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 23 11:41:15 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: remove warning
++
+ Fri Jan 23 11:35:21 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c src/tds/query.c src/tds/write.c:
+ 	- fix minor unsigned/signed issues
+@@ -1227,4 +1230,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2715 2009/01/23 10:37:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2716 2009/01/23 10:42:25 freddy77 Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 75e13de..218ecfd 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.186 2009/01/19 14:37:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.187 2009/01/23 10:42:25 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -617,7 +617,7 @@ tds_free_all_results(TDSSOCKET * tds)
+  * Return 1 if winsock is initialized, else 0.
+  */
+ static int
+-winsock_initialized()
++winsock_initialized(void)
+ {
+ #if defined(_WIN32) || defined(_WIN64)
+ 	WSADATA wsa_data;
+
+commit b87f74f41170edf91731f88a3fd4ed90dd7cef61
+Author: jklowden <jklowden>
+Date:   Sat Jan 31 19:13:19 2009 +0000
+
+    s/char*/const char arg[]/g: constify db-lib functions
+
+diff --git a/ChangeLog b/ChangeLog
+index a91b761..527f788 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Sat Jan 31 13:15:26 EST 2009	JK Lowden <jklowden@freetds.org>
++	* doc/api_status.txt
++	* include/sybdb.h
++	* src/dblib/bcp.c src/dblib/dblib.c
++	* src/dblib/rpc.c src/dblib/xact.c
++	- s/char*/const char arg[]/g: constify db-lib functions
++
+ Fri Jan 23 11:41:15 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/mem.c: remove warning
+ 
+@@ -1230,4 +1237,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2716 2009/01/23 10:42:25 freddy77 Exp $
++$Id: ChangeLog,v 1.2717 2009/01/31 19:13:19 jklowden Exp $
+diff --git a/doc/api_status.txt b/doc/api_status.txt
+index f071889..162104c 100644
+--- a/doc/api_status.txt
++++ b/doc/api_status.txt
+@@ -1,7 +1,7 @@
+ #!/usr/pkg/bin/perl
+ # API status document
+ #
+-# $Id: api_status.txt,v 1.60 2008/05/22 01:32:31 jklowden Exp $s
++# $Id: api_status.txt,v 1.61 2009/01/31 19:13:20 jklowden Exp $s
+ #
+ # This tab-delimited file is a database of the "readiness" of the various
+ # APIs.  Please feel free to modify it if you notice something is missing or 
+@@ -370,9 +370,9 @@ dblib	core     	dbnumorders			DBNUMORDERS	never
+ dblib	core     	dbopen				(same)		OK
+ dblib	core     	dbordercol			(same)		never
+ dblib	core     	dbprhead			(same)		OK
+-dblib	core     	dbprocerrhandle			n/a		never
++dblib	core     	dbprocerrhandle			n/a		aliases dberrhandle
+ dblib	core     	dbprocinfo			n/a		never
+-dblib	core     	dbprocmsghandle			n/a		never
++dblib	core     	dbprocmsghandle			n/a		aliases dbmsghandle
+ dblib	core     	dbprrow				(same)		OK
+ dblib	core     	dbprtype			(same)		OK
+ dblib	core     	dbresults			(same)		OK
+@@ -409,7 +409,7 @@ dblib	core     	dbuse				(same)		OK
+ dblib	core     	dbvarylen			(same)		OK
+ dblib	core     	n/a				dbversion	OK
+ dblib	core     	dbwillconvert			(same)		OK
+-dblib	core     	dbwinexit (Windows only)	n/a		never
++dblib	core     	dbwinexit (Windows only)	n/a		no-op macro
+ dblib	cursor   	dbcursor			(same)		never
+ dblib	cursor   	dbcursorbind			(same)		never
+ dblib	cursor   	dbcursorclose			(same)		never
+diff --git a/include/sybdb.h b/include/sybdb.h
+index 823002d..f2b7d04 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.86 2009/01/16 20:27:56 jklowden Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.87 2009/01/31 19:13:20 jklowden Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -458,7 +458,115 @@ typedef int (*MHANDLEFUNC) (DBPROCESS * dbproc, DBINT msgno, int msgstate, int s
+ #define DBRPCRESET 	TDS_STATIC_CAST(DBSMALLINT, 0x0002)
+ #define DBRPCCURSOR 	TDS_STATIC_CAST(DBSMALLINT, 0x0008)
+ 
+-DBBOOL db12hour(DBPROCESS * dbprocess, char *language);
++#if defined(DBLIB_UNIMPLEMENTED)
++DBBOOL db12hour(DBPROCESS * dbprocess, const char language[]);
++
++DBBOOL dbcolbrowse(DBPROCESS * dbprocess, int colnum);
++
++RETCODE dbcursor(DBCURSOR * hc, DBINT optype, DBINT bufno, BYTE * table, BYTE * values);
++RETCODE dbcursorbind(DBCURSOR * hc, int col, int vartype, DBINT varlen, DBINT * poutlen, BYTE * pvaraddr, DBTYPEINFO * typeinfo);
++void dbcursorclose(DBCURSOR * hc);
++RETCODE dbcursorcolinfo(DBCURSOR * hc, DBINT column, DBCHAR * colname, DBINT * coltype, DBINT * collen, DBINT * usertype);
++RETCODE dbcursorfetch(DBCURSOR * hc, DBINT fetchtype, DBINT rownum);
++RETCODE dbcursorinfo(DBCURSOR * hc, DBINT * ncols, DBINT * nrows);
++DBCURSOR *dbcursoropen(DBPROCESS * dbprocess, BYTE * stmt, SHORT scollopt, SHORT concuropt, USHORT nrows, DBINT * pstatus);
++
++int dbdate4cmp(DBPROCESS * dbprocess, DBDATETIME4 * d1, DBDATETIME4 * d2);
++RETCODE dbdate4zero(DBPROCESS * dbprocess, DBDATETIME4 * d1);
++RETCODE dbdatechar(DBPROCESS * dbprocess, char *buf, int datepart, int value);
++int dbdatename(DBPROCESS * dbprocess, char *buf, int date, DBDATETIME * datetime);
++char *dateorder(DBPROCESS * dbprocess, char *language);
++DBINT dbdatepart(DBPROCESS * dbprocess, int datepart, DBDATETIME * datetime);
++RETCODE dbdatezero(DBPROCESS * dbprocess, DBDATETIME * d1);
++char *dbdayname(DBPROCESS * dbprocess, char *language, int daynum);
++
++int dbgetoff(DBPROCESS * dbprocess, DBUSMALLINT offtype, int startfrom);
++
++char *dbqual(DBPROCESS * dbprocess, int tabnum, char *tabname);
++void dbfreequal(char *qualptr);
++
++DBSORTORDER *dbloadsort(DBPROCESS * dbprocess);
++RETCODE dbfreesort(DBPROCESS * dbprocess, DBSORTORDER * sortorder);
++
++RETCODE dbload_xlate(DBPROCESS * dbprocess, char *srv_charset, char *clt_name, DBXLATE ** xlt_tosrv, DBXLATE ** xlt_todisp);
++
++RETCODE dbmny4divide(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * quotient);
++RETCODE dbmny4mul(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * prod);
++RETCODE dbmnyadd(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * sum);
++RETCODE dbmnydivide(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * quotient);
++RETCODE dbmnydown(DBPROCESS * dbproc, DBMONEY * mnyptr, int divisor, int *remainder);
++RETCODE dbmnyinit(DBPROCESS * dbproc, DBMONEY * mnyptr, int trim, DBBOOL * negative);
++RETCODE dbmnyndigit(DBPROCESS * dbproc, DBMONEY * mnyptr, DBCHAR * value, DBBOOL * zero);
++RETCODE dbmnymul(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * prod);
++RETCODE dbmnydigit(DBPROCESS * dbprocess, DBMONEY * m1, DBCHAR * value, DBBOOL * zero);
++RETCODE dbmnyscale(DBPROCESS * dbproc, DBMONEY * dest, int multiplier, int addend);
++
++
++RETCODE dbnpcreate(DBPROCESS * dbprocess);
++RETCODE dbnpdefine(DBPROCESS * dbprocess, DBCHAR * procedure_name, DBSMALLINT namelen);
++
++int DBNUMORDERS(DBPROCESS * dbprocess);
++
++int dbordercol(DBPROCESS * dbprocess, int order);
++
++RETCODE dbregdrop(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen);
++RETCODE dbregexec(DBPROCESS * dbproc, DBUSMALLINT options);
++RETCODE dbreghandle(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen, INTFUNCPTR handler);
++RETCODE dbreginit(DBPROCESS * dbproc, DBCHAR * procedure_name, DBSMALLINT namelen);
++RETCODE dbreglist(DBPROCESS * dbproc);
++RETCODE dbregnowatch(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen);
++RETCODE dbregparam(DBPROCESS * dbproc, char *param_name, int type, DBINT datalen, BYTE * data);
++RETCODE dbregwatch(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen, DBUSMALLINT options);
++RETCODE dbregwatchlist(DBPROCESS * dbprocess);
++
++void dbrpwclr(LOGINREC * login);
++RETCODE dbrpwset(LOGINREC * login, char *srvname, char *password, int pwlen);
++
++DBINT dbreadpage(DBPROCESS * dbprocess, char *p_dbname, DBINT pageno, BYTE * buf);
++RETCODE dbwritepage(DBPROCESS * dbprocess, char *p_dbname, DBINT pageno, DBINT size, BYTE * buf);
++
++RETCODE dbsetdeflang(char *language);
++
++int dbstrcmp(DBPROCESS * dbprocess, char *s1, int l1, char *s2, int l2, DBSORTORDER * sort);
++int dbstrsort(DBPROCESS * dbprocess, char *s1, int l1, char *s2, int l2, DBSORTORDER * sort);
++
++DBBOOL dbtabbrowse(DBPROCESS * dbprocess, int tabnum);
++int dbtabcount(DBPROCESS * dbprocess);
++char *dbtabname(DBPROCESS * dbprocess, int tabnum);
++char *dbtabsoruce(DBPROCESS * dbprocess, int colnum, int *tabnum);
++
++RETCODE dbsetlshort(LOGINREC * login, int value, int which);
++#define DBSETLHIER(x,y)		dbsetlshort((x), (y), DBSETHIER)
++
++RETCODE dbsendpassthru(DBPROCESS * dbprocess, DBVOIDPTR bufp);
++RETCODE dbrecvpassthru(DBPROCESS * dbprocess, DBVOIDPTR * bufp);
++
++RETCODE dbgetloginfo(DBPROCESS * dbprocess, DBLOGINFO ** loginfo);
++RETCODE dbsetloginfo(LOGINREC * loginrec, DBLOGINFO * loginfo);
++
++int dbtsnewlen(DBPROCESS * dbprocess);
++DBBINARY *dbtsnewval(DBPROCESS * dbprocess);
++RETCODE dbtsput(DBPROCESS * dbprocess, DBBINARY * newts, int newtslen, int tabnum, char *tabname);
++
++RETCODE dbfree_xlate(DBPROCESS * dbprocess, DBXLATE * xlt_tosrv, DBXLATE * clt_todisp);
++int dbxlate(DBPROCESS * dbprocess, char *src, int srclen, char *dest, int destlen, DBXLATE * xlt, int *srcbytes_used,
++	    DBBOOL srcend, int status);
++
++RETCODE bcp_moretext(DBPROCESS * dbproc, DBINT size, BYTE * text);
++RETCODE bcp_writefmt(DBPROCESS * dbproc, const char filename[]);
++
++void build_xact_string(char *xact_name, char *service_name, DBINT commid, char *result);
++RETCODE remove_xact(DBPROCESS * connect, DBINT commid, int n);
++RETCODE abort_xact(DBPROCESS * connect, DBINT commid);
++void close_commit(DBPROCESS * connect);
++RETCODE commit_xact(DBPROCESS * connect, DBINT commid);
++DBPROCESS *open_commit(LOGINREC * login, char *servername);
++RETCODE scan_xact(DBPROCESS * connect, DBINT commid);
++DBINT start_xact(DBPROCESS * connect, char *application_name, char *xact_name, int site_count);
++DBINT stat_xact(DBPROCESS * connect, DBINT commid);
++
++#endif /* define unimplemented */
++
+ BYTE *dbadata(DBPROCESS * dbproc, int computeid, int column);
+ DBINT dbadlen(DBPROCESS * dbproc, int computeid, int column);
+ RETCODE dbaltbind(DBPROCESS * dbprocess, int computeid, int column, int vartype, DBINT varlen, BYTE * varaddr);
+@@ -480,14 +588,13 @@ char *dbchange(DBPROCESS * dbprocess);
+ DBBOOL dbcharsetconv(DBPROCESS * dbprocess);
+ void dbclose(DBPROCESS * dbproc);
+ void dbclrbuf(DBPROCESS * dbproc, DBINT n);
+-RETCODE dbclropt(DBPROCESS * dbproc, int option, char *param);
+-RETCODE dbcmd(DBPROCESS * dbproc, const char *cmdstring);
++RETCODE dbclropt(DBPROCESS * dbproc, int option, const char param[]);
++RETCODE dbcmd(DBPROCESS * dbproc, const char cmdstring[]);
+ RETCODE dbcmdrow(DBPROCESS * dbproc);
+ 
+ #define DBCMDROW(x) dbcmdrow((x))
+-DBBOOL dbcolbrowse(DBPROCESS * dbprocess, int colnum);
+-RETCODE	dbcolinfo (DBPROCESS *dbproc, CI_TYPE type, DBINT column, DBINT computeid, DBCOL *pdbcol);
+ RETCODE dbtablecolinfo (DBPROCESS *dbproc, DBINT column, DBCOL *pdbcol );
++RETCODE	dbcolinfo (DBPROCESS *dbproc, CI_TYPE type, DBINT column, DBINT computeid, DBCOL *pdbcol);
+ DBINT dbcollen(DBPROCESS * dbproc, int column);
+ char *dbcolname(DBPROCESS * dbproc, int column);
+ char *dbcolsource(DBPROCESS * dbproc, int colnum);
+@@ -506,25 +613,10 @@ int dbcurcmd(DBPROCESS * dbproc);
+ DBINT dbcurrow(DBPROCESS * dbproc);
+ 
+ #define DBCURROW(x) dbcurrow((x))
+-RETCODE dbcursor(DBCURSOR * hc, DBINT optype, DBINT bufno, BYTE * table, BYTE * values);
+-RETCODE dbcursorbind(DBCURSOR * hc, int col, int vartype, DBINT varlen, DBINT * poutlen, BYTE * pvaraddr, DBTYPEINFO * typeinfo);
+-void dbcursorclose(DBCURSOR * hc);
+-RETCODE dbcursorcolinfo(DBCURSOR * hc, DBINT column, DBCHAR * colname, DBINT * coltype, DBINT * collen, DBINT * usertype);
+-RETCODE dbcursorfetch(DBCURSOR * hc, DBINT fetchtype, DBINT rownum);
+-RETCODE dbcursorinfo(DBCURSOR * hc, DBINT * ncols, DBINT * nrows);
+-DBCURSOR *dbcursoropen(DBPROCESS * dbprocess, BYTE * stmt, SHORT scollopt, SHORT concuropt, USHORT nrows, DBINT * pstatus);
+ BYTE *dbdata(DBPROCESS * dbproc, int column);
+-int dbdate4cmp(DBPROCESS * dbprocess, DBDATETIME4 * d1, DBDATETIME4 * d2);
+-RETCODE dbdate4zero(DBPROCESS * dbprocess, DBDATETIME4 * d1);
+-RETCODE dbdatechar(DBPROCESS * dbprocess, char *buf, int datepart, int value);
+ RETCODE dbdatecmp(DBPROCESS * dbproc, DBDATETIME * d1, DBDATETIME * d2);
+ RETCODE dbdatecrack(DBPROCESS * dbproc, DBDATEREC * di, DBDATETIME * dt);
+-int dbdatename(DBPROCESS * dbprocess, char *buf, int date, DBDATETIME * datetime);
+-char *dateorder(DBPROCESS * dbprocess, char *language);
+-DBINT dbdatepart(DBPROCESS * dbprocess, int datepart, DBDATETIME * datetime);
+-RETCODE dbdatezero(DBPROCESS * dbprocess, DBDATETIME * d1);
+ DBINT dbdatlen(DBPROCESS * dbproc, int column);
+-char *dbdayname(DBPROCESS * dbprocess, char *language, int daynum);
+ DBBOOL dbdead(DBPROCESS * dbproc);
+ 
+ #define DBDEAD(x) dbdead((x))
+@@ -534,17 +626,12 @@ RETCODE dbfcmd(DBPROCESS * dbproc, const char *fmt, ...);
+ DBINT dbfirstrow(DBPROCESS * dbproc);
+ 
+ #define DBFIRSTROW(x) dbfirstrow((x))
+-RETCODE dbfree_xlate(DBPROCESS * dbprocess, DBXLATE * xlt_tosrv, DBXLATE * clt_todisp);
+ void dbfreebuf(DBPROCESS * dbproc);
+-void dbfreequal(char *qualptr);
+-RETCODE dbfreesort(DBPROCESS * dbprocess, DBSORTORDER * sortorder);
+ char *dbgetchar(DBPROCESS * dbprocess, int n);
+ char *dbgetcharset(DBPROCESS * dbprocess);
+-RETCODE dbgetloginfo(DBPROCESS * dbprocess, DBLOGINFO ** loginfo);
+ int dbgetlusername(LOGINREC * login, BYTE * name_buffer, int buffer_len);
+ int dbgetmaxprocs(void);
+ char *dbgetnatlanf(DBPROCESS * dbprocess);
+-int dbgetoff(DBPROCESS * dbprocess, DBUSMALLINT offtype, int startfrom);
+ int dbgetpacket(DBPROCESS * dbproc);
+ RETCODE dbgetrow(DBPROCESS * dbproc, DBINT row);
+ int dbgettime(void);
+@@ -561,54 +648,44 @@ int dbiowdesc(DBPROCESS * dbproc);
+ DBBOOL dbisavail(DBPROCESS * dbprocess);
+ 
+ #define DBISAVAIL(x) dbisavail((x))
+-DBBOOL dbisopt(DBPROCESS * dbproc, int option, char *param);
++DBBOOL dbisopt(DBPROCESS * dbproc, int option, const char param[]);
+ DBINT dblastrow(DBPROCESS * dbproc);
+ 
+ #define DBLASTROW(x) dblastrow((x))
+-RETCODE dbload_xlate(DBPROCESS * dbprocess, char *srv_charset, char *clt_name, DBXLATE ** xlt_tosrv, DBXLATE ** xlt_todisp);
+-DBSORTORDER *dbloadsort(DBPROCESS * dbprocess);
+ LOGINREC *dblogin(void);
+ void dbloginfree(LOGINREC * login);
+-RETCODE dbmny4add(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * sum);
++
+ int dbmny4cmp(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2);
+-RETCODE dbmny4copy(DBPROCESS * dbprocess, DBMONEY4 * m1, DBMONEY4 * m2);
+-RETCODE dbmny4divide(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * quotient);
+-RETCODE dbmny4minus(DBPROCESS * dbproc, DBMONEY4 * src, DBMONEY4 * dest);
+-RETCODE dbmny4mul(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * prod);
+-RETCODE dbmny4sub(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * diff);
+-RETCODE dbmny4zero(DBPROCESS * dbproc, DBMONEY4 * dest);
+-RETCODE dbmnyadd(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * sum);
+ int dbmnycmp(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2);
+-RETCODE dbmnycopy(DBPROCESS * dbproc, DBMONEY * src, DBMONEY * dest);
++
++RETCODE dbmny4add(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * sum);
+ RETCODE dbmnydec(DBPROCESS * dbproc, DBMONEY * mnyptr);
+-RETCODE dbmnydivide(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * quotient);
+-RETCODE dbmnydown(DBPROCESS * dbproc, DBMONEY * mnyptr, int divisor, int *remainder);
+ RETCODE dbmnyinc(DBPROCESS * dbproc, DBMONEY * mnyptr);
+-RETCODE dbmnyinit(DBPROCESS * dbproc, DBMONEY * mnyptr, int trim, DBBOOL * negative);
+-RETCODE dbmnymaxneg(DBPROCESS * dbproc, DBMONEY * dest);
+-RETCODE dbmnyndigit(DBPROCESS * dbproc, DBMONEY * mnyptr, DBCHAR * value, DBBOOL * zero);
+ RETCODE dbmnymaxpos(DBPROCESS * dbproc, DBMONEY * dest);
++RETCODE dbmnymaxneg(DBPROCESS * dbproc, DBMONEY * dest);
++RETCODE dbmny4minus(DBPROCESS * dbproc, DBMONEY4 * src, DBMONEY4 * dest);
+ RETCODE dbmnyminus(DBPROCESS * dbproc, DBMONEY * src, DBMONEY * dest);
+-RETCODE dbmnymul(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * prod);
+-RETCODE dbmnydigit(DBPROCESS * dbprocess, DBMONEY * m1, DBCHAR * value, DBBOOL * zero);
+-RETCODE dbmnyscale(DBPROCESS * dbproc, DBMONEY * dest, int multiplier, int addend);
++RETCODE dbmny4sub(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * diff);
+ RETCODE dbmnysub(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * diff);
++
++RETCODE dbmny4copy(DBPROCESS * dbprocess, DBMONEY4 * m1, DBMONEY4 * m2);
++RETCODE dbmnycopy(DBPROCESS * dbproc, DBMONEY * src, DBMONEY * dest);
++
++RETCODE dbmny4zero(DBPROCESS * dbproc, DBMONEY4 * dest);
+ RETCODE dbmnyzero(DBPROCESS * dbproc, DBMONEY * dest);
++
+ const char *dbmonthname(DBPROCESS * dbproc, char *language, int monthnum, DBBOOL shortform);
+ RETCODE dbmorecmds(DBPROCESS * dbproc);
+ 
+ #define DBMORECMDS(x) dbmorecmds((x))
+-RETCODE dbmoretext(DBPROCESS * dbproc, DBINT size, BYTE * text);
++RETCODE dbmoretext(DBPROCESS * dbproc, DBINT size, const BYTE text[]);
+ MHANDLEFUNC dbmsghandle(MHANDLEFUNC handler);
+ char *dbname(DBPROCESS * dbproc);
+ RETCODE dbnextrow(DBPROCESS * dbproc);
+-RETCODE dbnpcreate(DBPROCESS * dbprocess);
+-RETCODE dbnpdefine(DBPROCESS * dbprocess, DBCHAR * procedure_name, DBSMALLINT namelen);
+ RETCODE dbnullbind(DBPROCESS * dbproc, int column, DBINT * indicator);
+ int dbnumalts(DBPROCESS * dbproc, int computeid);
+ int dbnumcols(DBPROCESS * dbproc);
+ int dbnumcompute(DBPROCESS * dbprocess);
+-int DBNUMORDERS(DBPROCESS * dbprocess);
+ int dbnumrets(DBPROCESS * dbproc);
+ DBPROCESS *tdsdbopen(LOGINREC * login, const char *server, int msdblib);
+ DBPROCESS *dbopen(LOGINREC * login, const char *server);
+@@ -625,26 +702,13 @@ DBPROCESS *dbopen(LOGINREC * login, const char *server);
+ #define PHP_SYBASE_DBOPEN dbopen
+ #endif
+ 
+-int dbordercol(DBPROCESS * dbprocess, int order);
+ RETCODE dbpoll(DBPROCESS * dbproc, long milliseconds, DBPROCESS ** ready_dbproc, int *return_reason);
+ void dbprhead(DBPROCESS * dbproc);
+ RETCODE dbprrow(DBPROCESS * dbproc);
+ const char *dbprtype(int token);
+-char *dbqual(DBPROCESS * dbprocess, int tabnum, char *tabname);
+ DBBOOL DRBUF(DBPROCESS * dbprocess);
+-DBINT dbreadpage(DBPROCESS * dbprocess, char *p_dbname, DBINT pageno, BYTE * buf);
+ STATUS dbreadtext(DBPROCESS * dbproc, void *buf, DBINT bufsize);
+-void dbrecftos(char *filename);
+-RETCODE dbrecvpassthru(DBPROCESS * dbprocess, DBVOIDPTR * bufp);
+-RETCODE dbregdrop(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen);
+-RETCODE dbregexec(DBPROCESS * dbproc, DBUSMALLINT options);
+-RETCODE dbreghandle(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen, INTFUNCPTR handler);
+-RETCODE dbreginit(DBPROCESS * dbproc, DBCHAR * procedure_name, DBSMALLINT namelen);
+-RETCODE dbreglist(DBPROCESS * dbproc);
+-RETCODE dbregnowatch(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen);
+-RETCODE dbregparam(DBPROCESS * dbproc, char *param_name, int type, DBINT datalen, BYTE * data);
+-RETCODE dbregwatch(DBPROCESS * dbprocess, DBCHAR * procnm, DBSMALLINT namelen, DBUSMALLINT options);
+-RETCODE dbregwatchlist(DBPROCESS * dbprocess);
++void dbrecftos(const char filename[]);
+ RETCODE dbresults(DBPROCESS * dbproc);
+ RETCODE dbresults_r(DBPROCESS * dbproc, int recursive);
+ BYTE *dbretdata(DBPROCESS * dbproc, int retnum);
+@@ -658,23 +722,18 @@ RETCODE dbrows(DBPROCESS * dbproc);
+ STATUS dbrowtype(DBPROCESS * dbprocess);
+ 
+ #define DBROWTYPE(x) dbrowtype((x))
+-RETCODE dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options);
+-RETCODE dbrpcparam(DBPROCESS * dbproc, char *paramname, BYTE status, int type, DBINT maxlen, DBINT datalen, BYTE * value);
++RETCODE dbrpcinit(DBPROCESS * dbproc, const char rpcname[], DBSMALLINT options);
++RETCODE dbrpcparam(DBPROCESS * dbproc, const char paramname[], BYTE status, int type, DBINT maxlen, DBINT datalen, BYTE * value);
+ RETCODE dbrpcsend(DBPROCESS * dbproc);
+-void dbrpwclr(LOGINREC * login);
+-RETCODE dbrpwset(LOGINREC * login, char *srvname, char *password, int pwlen);
+ RETCODE dbsafestr(DBPROCESS * dbproc, const char *src, DBINT srclen, char *dest, DBINT destlen, int quotetype);
+ RETCODE *dbsechandle(DBINT type, INTFUNCPTR handler);
+-RETCODE dbsendpassthru(DBPROCESS * dbprocess, DBVOIDPTR bufp);
+ char *dbservcharset(DBPROCESS * dbprocess);
+ void dbsetavail(DBPROCESS * dbprocess);
+ void dbsetbusy(DBPROCESS * dbprocess, DB_DBBUSY_FUNC busyfunc);
+ RETCODE dbsetdefcharset(char *charset);
+-RETCODE dbsetdeflang(char *language);
+ void dbsetidle(DBPROCESS * dbprocess, DB_DBIDLE_FUNC idlefunc);
+ void dbsetifile(char *filename);
+ void dbsetinterrupt(DBPROCESS * dbproc, DB_DBCHKINTR_FUNC chkintr, DB_DBHNDLINTR_FUNC hndlintr);
+-RETCODE dbsetloginfo(LOGINREC * loginrec, DBLOGINFO * loginfo);
+ RETCODE dbsetlogintime(int seconds);
+ RETCODE dbsetmaxprocs(int maxprocs);
+ RETCODE dbsetnull(DBPROCESS * dbprocess, int bindtype, int bindlen, BYTE * bindval);
+@@ -693,14 +752,8 @@ RETCODE dbsqlexec(DBPROCESS * dbproc);
+ RETCODE dbsqlok(DBPROCESS * dbproc);
+ RETCODE dbsqlsend(DBPROCESS * dbproc);
+ int dbstrbuild(DBPROCESS * dbproc, char *charbuf, int bufsize, char *text, char *formats, ...);
+-int dbstrcmp(DBPROCESS * dbprocess, char *s1, int l1, char *s2, int l2, DBSORTORDER * sort);
+ RETCODE dbstrcpy(DBPROCESS * dbproc, int start, int numbytes, char *dest);
+ int dbstrlen(DBPROCESS * dbproc);
+-int dbstrsort(DBPROCESS * dbprocess, char *s1, int l1, char *s2, int l2, DBSORTORDER * sort);
+-DBBOOL dbtabbrowse(DBPROCESS * dbprocess, int tabnum);
+-int dbtabcount(DBPROCESS * dbprocess);
+-char *dbtabname(DBPROCESS * dbprocess, int tabnum);
+-char *dbtabsoruce(DBPROCESS * dbprocess, int colnum, int *tabnum);
+ DBINT dbvarylen(DBPROCESS * dbproc, int column);
+ 
+ #define SYBEICONVIU	 2400	/* Some character(s) could not be converted into client's character set. */
+@@ -1016,9 +1069,6 @@ int dbtds(DBPROCESS * dbprocess);
+ 
+ #define DBTDS(a)                dbtds(a)
+ DBINT dbtextsize(DBPROCESS * dbprocess);
+-int dbtsnewlen(DBPROCESS * dbprocess);
+-DBBINARY *dbtsnewval(DBPROCESS * dbprocess);
+-RETCODE dbtsput(DBPROCESS * dbprocess, DBBINARY * newts, int newtslen, int tabnum, char *tabname);
+ DBBINARY *dbtxptr(DBPROCESS * dbproc, int column);
+ DBBINARY *dbtxtimestamp(DBPROCESS * dbproc, int column);
+ DBBINARY *dbtxtsnewval(DBPROCESS * dbprocess);
+@@ -1026,16 +1076,12 @@ RETCODE dbtxtsput(DBPROCESS * dbprocess, DBBINARY newtxts, int colnum);
+ RETCODE dbuse(DBPROCESS * dbproc, const char *name);
+ const char *dbversion(void);
+ DBBOOL dbwillconvert(int srctype, int desttype);
+-RETCODE dbwritepage(DBPROCESS * dbprocess, char *p_dbname, DBINT pageno, DBINT size, BYTE * buf);
+ RETCODE dbwritetext(DBPROCESS * dbproc, char *objname, DBBINARY * textptr, DBTINYINT textptrlen, DBBINARY * timestamp,
+ 		    DBBOOL log, DBINT size, BYTE * text);
+-int dbxlate(DBPROCESS * dbprocess, char *src, int srclen, char *dest, int destlen, DBXLATE * xlt, int *srcbytes_used,
+-	    DBBOOL srcend, int status);
+ 
+ /* LOGINREC manipulation */
+ RETCODE dbsetlname(LOGINREC * login, const char *value, int which);
+ RETCODE dbsetlbool(LOGINREC * login, int value, int which);
+-RETCODE dbsetlshort(LOGINREC * login, int value, int which);
+ RETCODE dbsetllong(LOGINREC * login, long value, int which);
+ RETCODE dbsetlversion (LOGINREC * login, BYTE version);
+ 
+@@ -1062,7 +1108,6 @@ RETCODE dbsetlversion (LOGINREC * login, BYTE version);
+ #define DBSETNOSHORT		8	/* not implemented */
+ #define DBSETLNOSHORT(x,y)	dbsetlbool((x), (y), DBSETNOSHORT)
+ #define DBSETHIER		9	/* not implemented */
+-#define DBSETLHIER(x,y)		dbsetlshort((x), (y), DBSETHIER)
+ #define DBSETCHARSET		10
+ #define DBSETLCHARSET(x,y)	dbsetlname((x), (y), DBSETCHARSET)
+ #define DBSETPACKET		11
+@@ -1092,21 +1137,9 @@ RETCODE bcp_control(DBPROCESS * dbproc, int field, DBINT value);
+ int bcp_getbatchsize(DBPROCESS * dbproc); /* FreeTDS only */
+ RETCODE bcp_exec(DBPROCESS * dbproc, DBINT * rows_copied);
+ DBBOOL bcp_getl(LOGINREC * login);
+-RETCODE bcp_moretext(DBPROCESS * dbproc, DBINT size, BYTE * text);
+ RETCODE bcp_options(DBPROCESS * dbproc, int option, BYTE * value, int valuelen);
+-RETCODE bcp_readfmt(DBPROCESS * dbproc, char *filename);
++RETCODE bcp_readfmt(DBPROCESS * dbproc, const char filename[]);
+ RETCODE bcp_sendrow(DBPROCESS * dbproc);
+-RETCODE bcp_writefmt(DBPROCESS * dbproc, char *filename);
+-
+-void build_xact_string(char *xact_name, char *service_name, DBINT commid, char *result);
+-RETCODE remove_xact(DBPROCESS * connect, DBINT commid, int n);
+-RETCODE abort_xact(DBPROCESS * connect, DBINT commid);
+-void close_commit(DBPROCESS * connect);
+-RETCODE commit_xact(DBPROCESS * connect, DBINT commid);
+-DBPROCESS *open_commit(LOGINREC * login, char *servername);
+-RETCODE scan_xact(DBPROCESS * connect, DBINT commid);
+-DBINT start_xact(DBPROCESS * connect, char *application_name, char *xact_name, int site_count);
+-DBINT stat_xact(DBPROCESS * connect, DBINT commid);
+ 
+ #ifdef __cplusplus
+ #if 0
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 105b1ab..78a8141 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.179 2009/01/16 20:27:57 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.180 2009/01/31 19:13:20 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -1211,8 +1211,8 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 			/* tdsdump_log(TDS_DBG_FUNC, "collen is %d after tds_iconv_fread()\n", collen); */
+ 
+ 			if (file_bytes_left != 0) {
+-				tdsdump_log(TDS_DBG_FUNC, "col %d: %d of %d bytes unread\nfile_bytes_left != 0!\n", 
+-							(i+1), file_bytes_left, collen);
++				tdsdump_log(TDS_DBG_FUNC, "col %d: %ld of %d bytes unread\nfile_bytes_left != 0!\n", 
++							(i+1), (long)file_bytes_left, collen);
+ 				*row_error = TRUE;
+ 				free(coldata);
+ 				dbperror(dbproc, SYBEBCOR, 0);
+@@ -1804,7 +1804,7 @@ _bcp_fgets(char *buffer, int size, FILE *f)
+  * \sa 	bcp_colfmt(), bcp_colfmt_ps(), bcp_columns(), bcp_writefmt()
+  */
+ RETCODE
+-bcp_readfmt(DBPROCESS * dbproc, char *filename)
++bcp_readfmt(DBPROCESS * dbproc, const char filename[])
+ {
+ 	BCP_HOSTCOLINFO *hostcol;
+ 	FILE *ffile;
+@@ -2066,6 +2066,7 @@ _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci)
+ 		return (FALSE);
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /** 
+  * \ingroup dblib_bcp
+  * \brief Write a format definition file. Not Implemented. 
+@@ -2084,7 +2085,7 @@ _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci)
+  * \sa 	bcp_colfmt(), bcp_colfmt_ps(), bcp_columns(), bcp_readfmt()
+  */
+ RETCODE
+-bcp_writefmt(DBPROCESS * dbproc, char *filename)
++bcp_writefmt(DBPROCESS * dbproc, const char filename[])
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED: bcp_writefmt(%p, %s)\n", dbproc, filename? filename:"NULL");
+ 	CHECK_DBPROC();
+@@ -2132,6 +2133,7 @@ bcp_moretext(DBPROCESS * dbproc, DBINT size, BYTE * text)
+ #endif
+ 	return FAIL;
+ }
++#endif
+ 
+ /** 
+  * \ingroup dblib_bcp
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 898f7a6..a846159 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.339 2009/01/23 10:37:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.340 2009/01/31 19:13:20 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -813,6 +813,7 @@ dbsetllong(LOGINREC * login, long value, int which)
+ 	}
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /** \internal
+  * \ingroup dblib_internal
+  * \brief Set an integer value in a \c LOGINREC structure.  
+@@ -837,6 +838,7 @@ dbsetlshort(LOGINREC * login, int value, int which)
+ 		break;
+ 	}
+ }
++#endif
+ 
+ /** \internal
+  * \ingroup dblib_internal
+@@ -1239,7 +1241,7 @@ dbfcmd(DBPROCESS * dbproc, const char *fmt, ...)
+  * \sa dbfcmd(), dbfreebuf(), dbgetchar(), dbopen(), dbstrcpy(), dbstrlen().
+  */
+ RETCODE
+-dbcmd(DBPROCESS * dbproc, const char *cmdstring)
++dbcmd(DBPROCESS * dbproc, const char cmdstring[])
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcmd(%p, %s)\n", dbproc, cmdstring);
+ 	CHECK_DBPROC();
+@@ -3751,6 +3753,7 @@ dbrows(DBPROCESS * dbproc)
+ 	return (tds->res_info && tds->res_info->rows_exist)? SUCCEED : FAIL;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_core
+  * \brief Set the default character set for an application.
+@@ -3767,6 +3770,7 @@ dbsetdeflang(char *language)
+ 	CHECK_PARAMETER_NOPROC(language, SYBENULP);
+ 	return SUCCEED;
+ }
++#endif
+ 
+ /**
+  * \ingroup dblib_core
+@@ -4851,6 +4855,7 @@ dbmsghandle(MHANDLEFUNC handler)
+ 	return retFun;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_money
+  * \brief Add two DBMONEY values.
+@@ -4955,6 +4960,7 @@ dbmnydivide(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2, DBMONEY * quotient)
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbmnydivide()\n");
+ 	return SUCCEED;
+ }
++#endif
+ 
+ /**
+  * \ingroup dblib_money
+@@ -4991,6 +4997,7 @@ dbmnycmp(DBPROCESS * dbproc, DBMONEY * m1, DBMONEY * m2)
+ 	return 0;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_money
+  * \brief Multiply a DBMONEY value by a positive integer, and add an amount. 
+@@ -5015,7 +5022,7 @@ dbmnyscale(DBPROCESS * dbproc, DBMONEY * amount, int multiplier, int addend)
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbmnyscale()\n");
+ 	return SUCCEED;
+ }
+-
++#endif
+ 
+ /**
+  * \ingroup dblib_money
+@@ -5083,6 +5090,7 @@ dbmnymaxneg(DBPROCESS * dbproc, DBMONEY * amount)
+ 	return SUCCEED;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_money
+  * \brief Get the least significant digit of a DBMONEY value, represented as a character.
+@@ -5159,7 +5167,7 @@ dbmnydown(DBPROCESS * dbproc, DBMONEY * amount, int divisor, int *remainder)
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbmnydown()\n");
+ 	return SUCCEED;
+ }
+-
++#endif
+ 
+ /**
+  * \ingroup dblib_money
+@@ -5358,6 +5366,7 @@ dbmny4sub(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * diff)
+ 	return SUCCEED;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_money
+  * \brief Multiply two DBMONEY4 values.
+@@ -5413,6 +5422,7 @@ dbmny4divide(DBPROCESS * dbproc, DBMONEY4 * m1, DBMONEY4 * m2, DBMONEY4 * quotie
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbmny4divide()\n");
+ 	return FAIL;
+ }
++#endif
+ 
+ /**
+  * \ingroup dblib_money
+@@ -5549,6 +5559,7 @@ dbdatecrack(DBPROCESS * dbproc, DBDATEREC * di, DBDATETIME * datetime)
+ 	return SUCCEED;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_core
+  * \brief Clear remote passwords from the LOGINREC structure.
+@@ -5584,6 +5595,7 @@ dbrpwset(LOGINREC * login, char *srvname, char *password, int pwlen)
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbrpwset()\n");
+ 	return SUCCEED;
+ }
++#endif
+ 
+ /**
+  * \ingroup dblib_core
+@@ -5775,7 +5787,7 @@ dbfreebuf(DBPROCESS * dbproc)
+  * \sa dbisopt(), dbsetopt().
+  */
+ RETCODE
+-dbclropt(DBPROCESS * dbproc, int option, char *param)
++dbclropt(DBPROCESS * dbproc, int option, const char param[])
+ {
+ 	char *cmd;
+ 
+@@ -5828,7 +5840,7 @@ dbclropt(DBPROCESS * dbproc, int option, char *param)
+  * \sa dbclropt(), dbsetopt().
+  */
+ DBBOOL
+-dbisopt(DBPROCESS * dbproc, int option, char *param)
++dbisopt(DBPROCESS * dbproc, int option, const char param[])
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbisopt(%p, %d, %s)\n", dbproc, option, param);
+ 	CHECK_PARAMETER(dbproc, SYBENULL, FALSE);
+@@ -6401,7 +6413,7 @@ dbreadtext(DBPROCESS * dbproc, void *buf, DBINT bufsize)
+  * \todo Check return value of called functions and return \c FAIL if appropriate. 
+  */
+ RETCODE
+-dbmoretext(DBPROCESS * dbproc, DBINT size, BYTE * text)
++dbmoretext(DBPROCESS * dbproc, DBINT size, const BYTE text[])
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbmoretext(%p, %d, %p)\n", dbproc, size, text);
+ 	CHECK_DBPROC();
+@@ -6435,7 +6447,7 @@ dbmoretext(DBPROCESS * dbproc, DBINT size, BYTE * text)
+  * \sa dbopen(), TDSDUMP environment variable(). 
+  */
+ void
+-dbrecftos(char *filename)
++dbrecftos(const char filename[])
+ {
+ 	char *f;
+ 
+@@ -6515,6 +6527,7 @@ dbversion()
+ 	return rcsid_var;
+ }
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ /**
+  * \ingroup dblib_core
+  * \brief Set the default character set.  
+@@ -6615,6 +6628,7 @@ dbregexec(DBPROCESS * dbproc, DBUSMALLINT options)
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED dbregexec()\n");
+ 	return SUCCEED;
+ }
++#endif
+ 
+ 
+ /**
+diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c
+index 8483f0c..7b68281 100644
+--- a/src/dblib/rpc.c
++++ b/src/dblib/rpc.c
+@@ -54,7 +54,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: rpc.c,v 1.66 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: rpc.c,v 1.67 2009/01/31 19:13:20 jklowden Exp $");
+ 
+ static void rpc_clear(DBREMOTE_PROC * rpc);
+ static void param_clear(DBREMOTE_PROC_PARAM * pparam);
+@@ -76,7 +76,7 @@ static TDSPARAMINFO *param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc);
+  * \sa dbrpcparam(), dbrpcsend()
+  */
+ RETCODE
+-dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options)
++dbrpcinit(DBPROCESS * dbproc, const char rpcname[], DBSMALLINT options)
+ {
+ 	DBREMOTE_PROC **rpc;
+ 	int dbrpcrecompile = 0;
+@@ -161,7 +161,7 @@ dbrpcinit(DBPROCESS * dbproc, char *rpcname, DBSMALLINT options)
+  * \sa dbrpcinit(), dbrpcsend()
+  */
+ RETCODE
+-dbrpcparam(DBPROCESS * dbproc, char *paramname, BYTE status, int type, DBINT maxlen, DBINT datalen, BYTE * value)
++dbrpcparam(DBPROCESS * dbproc, const char paramname[], BYTE status, int type, DBINT maxlen, DBINT datalen, BYTE * value)
+ {
+ 	char *name = NULL;
+ 	DBREMOTE_PROC *rpc;
+diff --git a/src/dblib/xact.c b/src/dblib/xact.c
+index 6553d68..f46bc7c 100644
+--- a/src/dblib/xact.c
++++ b/src/dblib/xact.c
+@@ -37,9 +37,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: xact.c,v 1.12 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: xact.c,v 1.13 2009/01/31 19:13:20 jklowden Exp $");
+ 
+ 
++#if defined(DBLIB_UNIMPLEMENTED)
+ void
+ build_xact_string(char *xact_name, char *service_name, DBINT commid, char *result)
+ {
+@@ -100,3 +101,4 @@ stat_xact(DBPROCESS * connect, DBINT commid)
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED stat_xact()\n");
+ 	return 0;
+ }
++#endif
+
+commit 9abee17017a485455a2e5599e5332e5ff4e96be8
+Author: jklowden <jklowden>
+Date:   Sun Feb 1 22:29:38 2009 +0000
+
+    read unit test SQL from external file.
+
+diff --git a/ChangeLog b/ChangeLog
+index 527f788..1e7ee47 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,34 @@
++Sun Feb  1 17:15:49 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/common.h src/dblib/unittests/common.c
++	* src/dblib/unittests/bcp.c src/dblib/unittests/dbmorecmds.c
++	* src/dblib/unittests/done_handling.c src/dblib/unittests/rpc.c
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0002.c
++	* src/dblib/unittests/t0003.c src/dblib/unittests/t0004.c
++	* src/dblib/unittests/t0005.c src/dblib/unittests/t0006.c
++	* src/dblib/unittests/t0007.c src/dblib/unittests/t0008.c
++	* src/dblib/unittests/t0009.c src/dblib/unittests/t0011.c
++	* src/dblib/unittests/t0012.c src/dblib/unittests/t0013.c
++	* src/dblib/unittests/t0014.c src/dblib/unittests/t0015.c
++	* src/dblib/unittests/t0016.c src/dblib/unittests/t0017.c
++	* src/dblib/unittests/t0018.c src/dblib/unittests/t0020.c
++	* src/dblib/unittests/t0021.c src/dblib/unittests/t0022.c
++	* src/dblib/unittests/t0023.c
++	* src/dblib/unittests/text_buffer.c src/dblib/unittests/timeout.c
++	* src/dblib/unittests/bcp.sql src/dblib/unittests/dbmorecmds.sql
++	* src/dblib/unittests/done_handling.sql src/dblib/unittests/rpc.sql
++	* src/dblib/unittests/t0001.sql src/dblib/unittests/t0002.sql
++	* src/dblib/unittests/t0003.sql src/dblib/unittests/t0004.sql
++	* src/dblib/unittests/t0005.sql src/dblib/unittests/t0006.sql
++	* src/dblib/unittests/t0007.sql src/dblib/unittests/t0009.sql
++	* src/dblib/unittests/t0011.sql src/dblib/unittests/t0012.sql
++	* src/dblib/unittests/t0013.sql src/dblib/unittests/t0014.sql
++	* src/dblib/unittests/t0015.sql src/dblib/unittests/t0016.sql
++	* src/dblib/unittests/t0017.sql src/dblib/unittests/t0018.sql
++	* src/dblib/unittests/t0020.sql src/dblib/unittests/t0022.sql
++	* src/dblib/unittests/t0023.sql
++	* src/dblib/unittests/text_buffer.sql src/dblib/unittests/timeout.sql
++	- read unit test SQL from external file. 
++
+ Sat Jan 31 13:15:26 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* doc/api_status.txt
+ 	* include/sybdb.h
+@@ -1237,4 +1268,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2717 2009/01/31 19:13:19 jklowden Exp $
++$Id: ChangeLog,v 1.2718 2009/02/01 22:29:38 jklowden Exp $
+diff --git a/src/dblib/unittests/bcp.c b/src/dblib/unittests/bcp.c
+index 511d42d..d777aa3 100644
+--- a/src/dblib/unittests/bcp.c
++++ b/src/dblib/unittests/bcp.c
+@@ -13,7 +13,7 @@
+ 
+ #include "bcp.h"
+ 
+-static char software_version[] = "$Id: bcp.c,v 1.16 2008/12/19 10:38:56 freddy77 Exp $";
++static char software_version[] = "$Id: bcp.c,v 1.17 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[512];
+@@ -46,9 +46,7 @@ init(DBPROCESS * dbproc, const char *name)
+ 	RETCODE rc;
+ 
+ 	fprintf(stdout, "Dropping %s.%s..%s\n", SERVER, DATABASE, name);
+-	add_bread_crumb();
+-	sprintf(cmd, "if exists (select 1 from sysobjects where type = 'U' and name = '%s') drop table %s", name, name);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -60,14 +58,9 @@ init(DBPROCESS * dbproc, const char *name)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "Creating %s.%s..%s\n", SERVER, DATABASE, name);
++	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc, INPUT);
+ 
+-	dbcmd(dbproc, create_table_sql);
+-#if 1
+-	dbfcmd(dbproc, 	"select colid, cast(c.name as varchar(30)) as name, c.length "
+-			", '  '+ substring('NY', convert(bit,(c.status & 8))+1,1) as Nulls " 
+-			"from syscolumns as c left join systypes as t on c.usertype = t.usertype "
+-			"where c.id = object_id('%s') order by colid", name );
+-#endif
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		res = 1;
+@@ -276,23 +269,9 @@ main(int argc, char **argv)
+ 	printf("done\n");
+ 
+ 	add_bread_crumb();
+-#if 0
+-	fprintf(stdout, "select * from %s\n", table_name);
+-	dbfcmd(dbproc, "select * from %s\n", table_name);
+-#endif
++
+ #if 1
+-	dbfcmd(dbproc, 	"select   'nullable_char' as col, count(*) nrows"
+-				", datalength(nullable_char) as len, nullable_char as value "
+-			"from %s group by nullable_char\n", table_name);
+-	dbfcmd(dbproc, 	"UNION\n"
+-			"select   'nullable_varchar' as col, count(*) nrows"
+-				", datalength(nullable_varchar) as len, nullable_varchar as value "
+-			"from %s group by nullable_varchar\n", table_name);
+-	dbfcmd(dbproc, 	"UNION\n"
+-			"select   'nullable_int' as col, count(*) nrows"
+-				", datalength(nullable_int) as len, cast(nullable_int as varchar(6))as value "
+-			"from %s group by nullable_int\n", table_name);
+-	dbfcmd(dbproc, "order by col, len, nrows\n");
++	sql_cmd(dbproc, INPUT);
+ 
+ 	dbsqlexec(dbproc);
+ 	while ((i=dbresults(dbproc)) == SUCCEED) {
+@@ -308,8 +287,7 @@ main(int argc, char **argv)
+ 	} else {
+ 		fprintf(stdout, "Dropping table %s\n", table_name);
+ 		add_bread_crumb();
+-		sprintf(cmd, "drop table %s", table_name);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		add_bread_crumb();
+ 		dbsqlexec(dbproc);
+ 		add_bread_crumb();
+@@ -323,7 +301,7 @@ main(int argc, char **argv)
+ 
+ 	failed = 0;
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/bcp.sql b/src/dblib/unittests/bcp.sql
+new file mode 100644
+index 0000000..3bb08b0
+--- /dev/null
++++ b/src/dblib/unittests/bcp.sql
+@@ -0,0 +1,154 @@
++if exists (select 1 from sysobjects where type = 'U' and name = 'all_types_bcp_unittest') drop table all_types_bcp_unittest
++go
++CREATE TABLE all_types_bcp_unittest (
++	  not_null_bit			bit NOT NULL
++
++	, not_null_char			char(10) NOT NULL
++	, not_null_varchar		varchar(10) NOT NULL
++
++	, not_null_datetime		datetime NOT NULL
++	, not_null_smalldatetime	smalldatetime NOT NULL
++
++	, not_null_money		money NOT NULL
++	, not_null_smallmoney		smallmoney NOT NULL
++
++	, not_null_float		float NOT NULL
++	, not_null_real			real NOT NULL
++
++	, not_null_decimal		decimal(5,2) NOT NULL
++	, not_null_numeric		numeric(5,2) NOT NULL
++
++	, not_null_int			int NOT NULL
++	, not_null_smallint		smallint NOT NULL
++	, not_null_tinyint		tinyint NOT NULL
++
++	, nullable_char			char(10)  NULL
++	, nullable_varchar		varchar(10)  NULL
++
++	, nullable_datetime		datetime  NULL
++	, nullable_smalldatetime	smalldatetime  NULL
++
++	, nullable_money		money  NULL
++	, nullable_smallmoney		smallmoney  NULL
++
++	, nullable_float		float  NULL
++	, nullable_real			real  NULL
++
++	, nullable_decimal		decimal(5,2)  NULL
++	, nullable_numeric		numeric(5,2)  NULL
++
++	, nullable_int			int  NULL
++	, nullable_smallint		smallint  NULL
++	, nullable_tinyint		tinyint  NULL
++
++	/* Excludes: 
++	 * binary
++	 * image
++	 * uniqueidentifier
++	 * varbinary
++	 * text
++	 * timestamp
++	 * nchar
++	 * ntext
++	 * nvarchar
++	 */
++)
++
++INSERT all_types_bcp_unittest   
++VALUES ( 1 -- not_null_bit
++
++	, 'a char' -- not_null_char
++	, 'a varchar' -- not_null_varchar
++
++	, 'Dec 17 2003  3:44PM' -- not_null_datetime
++	, 'Dec 17 2003  3:44PM' -- not_null_smalldatetime
++
++	, 12.34 -- not_null_money
++	, 12.34 -- not_null_smallmoney
++
++	, 12.34 -- not_null_float
++	, 12.34 -- not_null_real
++
++	, 12.34 -- not_null_decimal
++	, 12.34 -- not_null_numeric
++
++	, 1234 -- not_null_int
++	, 1234 -- not_null_smallint
++	, 123  -- not_null_tinyint
++
++	, 'a char' -- nullable_char
++	, 'a varchar' -- nullable_varchar
++
++	, 'Dec 17 2003  3:44PM' -- nullable_datetime
++	, 'Dec 17 2003  3:44PM' -- nullable_smalldatetime
++
++	, 12.34 -- nullable_money
++	, 12.34 -- nullable_smallmoney
++
++	, 12.34 -- nullable_float
++	, 12.34 -- nullable_real
++
++	, 12.34 -- nullable_decimal
++	, 12.34 -- nullable_numeric
++
++	, 1234 -- nullable_int
++	, 1234 -- nullable_smallint
++	, 123  -- nullable_tinyint
++)
++INSERT all_types_bcp_unittest
++				( not_null_bit			
++
++				, not_null_char			
++				, not_null_varchar		
++
++				, not_null_datetime		
++				, not_null_smalldatetime	
++
++				, not_null_money		
++				, not_null_smallmoney		
++
++				, not_null_float		
++				, not_null_real			
++
++				, not_null_decimal		
++				, not_null_numeric		
++
++				, not_null_int			
++				, not_null_smallint		
++				, not_null_tinyint		
++				) 
++VALUES (
++	  1 -- not_null_bit
++
++	, 'a char' -- not_null_char
++	, 'a varchar' -- not_null_varchar
++
++	, 'Dec 17 2003  3:44PM' -- not_null_datetime
++	, 'Dec 17 2003  3:44PM' -- not_null_smalldatetime
++
++	, 12.34 -- not_null_money
++	, 12.34 -- not_null_smallmoney
++
++	, 12.34 -- not_null_float
++	, 12.34 -- not_null_real
++
++	, 12.34 -- not_null_decimal
++	, 12.34 -- not_null_numeric
++
++	, 1234 -- not_null_int
++	, 1234 -- not_null_smallint
++	, 123  -- not_null_tinyint
++)
++go
++select colid, cast(c.name as varchar(30)) as name, c.length , '  '+ substring('NY', convert(bit,(c.status & 8))+1,1) as Nulls from syscolumns as c left join systypes as t on c.usertype = t.usertype where c.id = object_id('all_types_bcp_unittest') order by colid
++go
++select   'nullable_char' as col, count(*) nrows, datalength(nullable_char) as len, nullable_char as value from all_types_bcp_unittest group by nullable_char
++UNION
++select   'nullable_varchar' as col, count(*) nrows, datalength(nullable_varchar) as len, nullable_varchar as value from all_types_bcp_unittest group by nullable_varchar
++UNION
++select   'nullable_int' as col, count(*) nrows, datalength(nullable_int) as len, cast(nullable_int as varchar(6))as value from all_types_bcp_unittest group by nullable_int
++order by col, len, nrows
++
++go
++drop table all_types_bcp_unittest
++go
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 1a7d5de..a087112 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -16,7 +16,9 @@
+ #include "replacements.h"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.25 2008/11/25 22:58:29 jklowden Exp $";
++#include <err.h>
++
++static char software_version[] = "$Id: common.c,v 1.26 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -32,10 +34,18 @@ static memcheck_t *breadcrumbs = NULL;
+ static int num_breadcrumbs = 0;
+ static const unsigned int BREADCRUMB = 0xABCD7890;
+ 
++#if !defined(PATH_MAX)
++#define PATH_MAX 256
++#endif
++
+ char USER[512];
+ char SERVER[512];
+ char PASSWORD[512];
+ char DATABASE[512];
++
++static char sql_file[PATH_MAX];
++FILE* INPUT;
++
+ static char *DIRNAME = NULL;
+ static const char *BASENAME = NULL;
+ 
+@@ -80,23 +90,17 @@ tds_dirname(char* path)
+ 
+ #endif
+ 
+-#ifndef MAXPATHLEN
+-#define MAXPATHLEN 512
+-#endif
+-
+ int
+ read_login_info(int argc, char **argv)
+ {
+-	extern char *optarg;
+-	extern int optind;
+-	
++	size_t len;
+ 	FILE *in = NULL;
+ #if !defined(__MINGW32__) && !defined(_MSC_VER)
+ 	int ch;
+ #endif
+ 	char line[512];
+ 	char *s1, *s2;
+-	char filename[MAXPATHLEN];
++	char filename[PATH_MAX];
+ 	static const char *PWD = "../../../PWD";
+ 	struct { char *username, *password, *servername, *database; char fverbose; } options;
+ 	
+@@ -200,9 +204,47 @@ read_login_info(int argc, char **argv)
+ 	}
+ 	
+ 	printf("found %s.%s for %s in \"%s\"\n", SERVER, DATABASE, USER, filename);
++	
++#if 0
++	dbrecftos(BASENAME);
++#endif
++	len = snprintf(sql_file, sizeof(sql_file), "%s.sql", BASENAME);
++	assert(len <= sizeof(sql_file));
++
++	if ((INPUT = fopen(sql_file, "r")) == NULL) {
++		fflush(stdout);
++		warnx("could not open SQL input file \"%s\"\n", sql_file);
++	}
++	
++	printf("SQL text will be read from %s\n", sql_file);
++
+ 	return 0;
+ }
+ 
++/*
++ * Fill the command buffer from a file while echoing it to standard output.
++ */
++RETCODE 
++sql_cmd(DBPROCESS *dbproc, FILE *stream)
++{
++	char line[2048], *p = line;
++	int i = 0;
++	RETCODE erc=SUCCEED;
++	
++	while ((p = fgets(line, (int)sizeof(line), stream)) != NULL && strcasecmp("go\n", p) != 0) {
++		printf("\t%3d: %s", ++i, p);
++		if ((erc = dbcmd(dbproc, p)) != SUCCEED) {
++			errx(1, "%s: error: could write \"%s\" to dbcmd()\n", BASENAME, p);
++		}
++	}
++
++	if (ferror(stream)) {
++		errx(1, "%s: error: could not read SQL input file \"%s\"\n", BASENAME, sql_file);
++	}
++
++	return erc;
++}
++
+ void
+ check_crumbs(void)
+ {
+@@ -306,6 +348,7 @@ syb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, cha
+ 	 * If the severity is something other than 0 or the msg number is
+ 	 * 0 (user informational messages).
+ 	 */
++	fflush(stdout);
+ 	if (severity >= 0 || msgno == 0) {
+ 		/*
+ 		 * If the message was something other than informational, and
+@@ -364,6 +407,7 @@ syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *db
+ 		}
+ 	}
+ 
++	fflush(stdout);
+ 	fprintf(stderr,
+ 		"DB-LIBRARY error (dberr %d (severity %d): \"%s\"; oserr %d: \"%s\")\n",
+ 		dberr, severity, dberrstr ? dberrstr : "(null)", oserr, oserrstr ? oserrstr : "(null)");
+diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h
+index 67b72db..0f5d023 100644
+--- a/src/dblib/unittests/common.h
++++ b/src/dblib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.15 2008/11/25 22:58:29 jklowden Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.16 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #if HAVE_CONFIG_H
+@@ -76,6 +76,7 @@ extern char PASSWORD[512];
+ extern char USER[512];
+ extern char SERVER[512];
+ extern char DATABASE[512];
++extern FILE* INPUT;
+ 
+ void set_malloc_options(void);
+ int read_login_info(int argc, char **argv);
+@@ -86,6 +87,8 @@ int syb_msg_handler(DBPROCESS * dbproc,
+ 		    DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line);
+ int syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ 
++RETCODE sql_cmd(DBPROCESS *dbproc, FILE *stream);
++
+ #define int2ptr(i) ((void*)(((char*)0)+(i)))
+ #define ptr2int(p) ((int)(((char*)(p))-((char*)0)))
+ 
+diff --git a/src/dblib/unittests/dbmorecmds.c b/src/dblib/unittests/dbmorecmds.c
+index c5b76f2..a01522b 100644
+--- a/src/dblib/unittests/dbmorecmds.c
++++ b/src/dblib/unittests/dbmorecmds.c
+@@ -5,12 +5,11 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: dbmorecmds.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: dbmorecmds.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version,	no_unused_var_warn };
+ 
+ int failed = 0;
+-const static char query[] = "select count(*) from sysusers\n"
+-			    "select name from sysobjects compute count(name)\n";
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -65,7 +64,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0024 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -73,19 +72,15 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-		char cmd[1024];
+-
+-		sprintf(cmd, "insert into #dblib0024 values (%d, 'row %03d')", i, i);
+-		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	fprintf(stdout, "select 1\n");
+-	dbcmd(dbproc, "select count(*) from #dblib0024 -- order by i");
++	fprintf(stdout, "select one resultset\n");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -108,8 +103,8 @@ main(int argc, char **argv)
+ 
+ 	dbcancel(dbproc);
+ 
+-	fprintf(stdout, query);
+-	dbcmd(dbproc, query);
++	fprintf(stdout, "select two resultsets\n");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 	nresults = 0;
+@@ -136,7 +131,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/dbmorecmds.sql b/src/dblib/unittests/dbmorecmds.sql
+new file mode 100644
+index 0000000..be381b3
+--- /dev/null
++++ b/src/dblib/unittests/dbmorecmds.sql
+@@ -0,0 +1,27 @@
++create table #dblib0024 (i int not null, s char(10) not null)
++go
++insert into #dblib0024 values (0, 'row 000')
++go
++insert into #dblib0024 values (1, 'row 001')
++go
++insert into #dblib0024 values (2, 'row 002')
++go
++insert into #dblib0024 values (3, 'row 003')
++go
++insert into #dblib0024 values (4, 'row 004')
++go
++insert into #dblib0024 values (5, 'row 005')
++go
++insert into #dblib0024 values (6, 'row 006')
++go
++insert into #dblib0024 values (7, 'row 007')
++go
++insert into #dblib0024 values (8, 'row 008')
++go
++insert into #dblib0024 values (9, 'row 009')
++go
++select count(*) from #dblib0024 -- order by i
++go
++select count(*) from sysusers
++select name from sysobjects compute count(name)
++go
+diff --git a/src/dblib/unittests/done_handling.c b/src/dblib/unittests/done_handling.c
+index 53dc3fc..c2e5cc0 100644
+--- a/src/dblib/unittests/done_handling.c
++++ b/src/dblib/unittests/done_handling.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: done_handling.c,v 1.7 2007/12/28 23:00:42 jklowden Exp $";
++static char software_version[] = "$Id: done_handling.c,v 1.8 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -28,21 +28,58 @@ static DBPROCESS *dbproc;
+ static int silent = 0;
+ static int check_idle = 0;
+ 
+-static void
+-query(const char *query)
++/* print functions adapted from src/dblib/dblib.c */
++static const char *
++prdbretcode(int retcode)
++{
++	static char unknown[24];
++	switch(retcode) {
++	case REG_ROW:		return "REG_ROW/MORE_ROWS";
++	case NO_MORE_ROWS:	return "NO_MORE_ROWS";
++	case BUF_FULL:		return "BUF_FULL";
++	case NO_MORE_RESULTS:	return "NO_MORE_RESULTS";
++	case SUCCEED:		return "SUCCEED";
++	case FAIL:		return "FAIL";
++	default:
++		sprintf(unknown, "oops: %u ??", retcode);
++	}
++	return unknown;
++}
++
++static const char *
++prretcode(int retcode)
++{
++	static char unknown[24];
++	switch(retcode) {
++	case SUCCEED:		return "SUCCEED";
++	case FAIL:		return "FAIL";
++	case NO_MORE_RESULTS:	return "NO_MORE_RESULTS";
++	default:
++		sprintf(unknown, "oops: %u ??", retcode);
++	}
++	return unknown;
++}
++
++static RETCODE
++query(const char comment[])
+ {
+-	printf("query: %s\n", query);
+-	dbcmd(dbproc, (char *) query);
++	RETCODE erc;
++	
++	if (comment)
++		printf("%s\n", comment);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+-	while (dbresults(dbproc) == SUCCEED) {
++	while ((erc = dbresults(dbproc)) == SUCCEED) {
+ 		/* nop */
+ 	}
+ }
+ 
++typedef const char* (*prfunc)(int);
++
+ static void
+-check_state(void)
++check_state(const char name[], prfunc print, int erc)
+ {
+-	printf("State ");
++	printf("State %-15s %-20s ", name, print(erc));
+ 	if (dbnumcols(dbproc) > 0)
+ 		printf("COLS(%d) ", dbnumcols(dbproc));
+ 	/* row count */
+@@ -73,64 +110,48 @@ check_state(void)
+ }
+ 
+ static void
+-do_test(const char *query)
++do_test(const char comment[])
+ {
+ 	int ret;
++	prfunc print_with = NULL;
+ 
+-	printf("test query %s\n", query);
+-	dbcmd(dbproc, (char *) query);
+-
+-	printf("sqlexec ");
+-	dbsqlexec(dbproc);
+-
+-	check_state();
+-
+-	printf("nextrow ");
+-	dbnextrow(dbproc);
++	if (comment)
++		printf("%s\n", comment);
++	sql_cmd(dbproc, INPUT);
+ 
+-	check_state();
++	check_state("sqlexec ", prretcode, dbsqlexec(dbproc));
+ 
+-	printf("nextrow ");
+-	dbnextrow(dbproc);
+-
+-	check_state();
+-
+-	printf("results ");
+-	dbresults(dbproc);
+-
+-	check_state();
+-
+-	printf("nextrow ");
+-	dbnextrow(dbproc);
+-
+-	check_state();
+-
+-	printf("nextrow ");
+-	dbnextrow(dbproc);
+-
+-	check_state();
++	check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
++	check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
++	check_state("results ", prretcode,   dbresults(dbproc));
++	check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
++	check_state("nextrow ", prdbretcode, dbnextrow(dbproc));
+ 
+ 	check_idle = 0;
+ 	for (;;) {
+-		printf("results \n");
+ 		ret = dbresults(dbproc);
+-		check_state();
+-		if (ret != SUCCEED)
++		check_state("results ", prretcode, ret);
++		if (ret != SUCCEED) {
++			print_with = prretcode;
+ 			break;
++		}
+ 
+ 		do {
+-			printf("nextrow ");
+ 			ret = dbnextrow(dbproc);
+-			check_state();
+-		} while (ret == SUCCEED);
++			check_state("nextrow ", prdbretcode, ret);
++		} while (ret == REG_ROW);
++		print_with = prdbretcode;
+ 	}
+-	check_state();
++	check_state("more results?", print_with, ret);
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
++	const static int invalid_column_name = 207;
++	RETCODE erc;
+ 	LOGINREC *login;	/* Our login information. */
++	int i;
+ 
+ 	setbuf(stdout, NULL);
+ 	read_login_info(argc, argv);
+@@ -141,6 +162,16 @@ main(int argc, char *argv[])
+ 	dberrhandle(err_handler);
+ 	dbmsghandle(msg_handler);
+ 
++#if 0
++	/* 
++	 * FIXME: Should be able to use the common err/msg handlers, but something about
++	 * the IDLE checking causes them to fail.  Not sure about purpose of IDLE checking.
++	 * -- jkl January 2009
++	 */
++	dberrhandle(syb_err_handler);
++	dbmsghandle(syb_msg_handler);
++#endif
++
+ 	login = dblogin();
+ 	DBSETLUSER(login, USER);
+ 	DBSETLPWD(login, PASSWORD);
+@@ -153,35 +184,33 @@ main(int argc, char *argv[])
+ 	if (strlen(DATABASE))
+ 		dbuse(dbproc, DATABASE);
+ 
+-	query("create table #dummy (s char(10))");
+-	query("insert into #dummy values('xxx')");
+-	query("if object_id('done_test') is not NULL drop proc done_test");
+-	query("create proc done_test @a varchar(10) output as select * from #dummy");
+-	query("if object_id('done_test2') is not NULL drop proc done_test2");
+-	query("create proc done_test2 as select * from #dummy where s = 'aaa' select * from #dummy");
+-
++	for (i=0; i < 6; i++) {
++		erc = query(NULL);
++	}
++#if 0	
++	check_state("setup done ", prretcode, erc);
++	
++	printf("wasting results\n");
++	while ((erc = dbresults(dbproc)) == SUCCEED) {
++		while (dbnextrow(dbproc) == REG_ROW); /* no-op */
++	}	
++#endif
+ 	check_idle = 1;
+ 
+-	/* normal row */
+-	do_test("select * from #dummy");
+-	/* normal row with no count */
+-	query("set nocount on");
+-	do_test("select * from #dummy");
+-	query("set nocount off");
+-	/* normal row without rows */
+-	do_test("select * from #dummy where 0=1");
+-	/* error query */
+-	do_test("select dklghdlgkh from #dummy");
+-	/* store procedure call with output parameters */
+-	do_test("declare @s varchar(10) exec done_test @s output");
+-
+-	do_test("declare @i int");
+-
+-	do_test("exec done_test2");
+-	do_test("declare @i int");
+-
+-	query("drop proc done_test");
+-	query("drop proc done_test2");
++	do_test("normal row with rowcount on");
++	query("turn rowcount off");
++	do_test("normal row with rowcount off");
++	query("turn rowcount back on");
++	do_test("normal row without rows");
++	dbsetuserdata(dbproc, &invalid_column_name);
++	do_test("error query");
++	do_test("stored procedure call with output parameters");
++
++	do_test("execute done2");
++
++	query("drop done_test");
++
++	query("drop done_test2");
+ 
+ 	dbexit();
+ 	return 0;
+diff --git a/src/dblib/unittests/done_handling.sql b/src/dblib/unittests/done_handling.sql
+new file mode 100644
+index 0000000..525a513
+--- /dev/null
++++ b/src/dblib/unittests/done_handling.sql
+@@ -0,0 +1,38 @@
++create table #dummy (s char(10))
++go
++insert into #dummy values('xxx')
++go
++if object_id('done_test') is not NULL drop proc done_test
++go
++create proc done_test @a varchar(10) output 
++as 
++	select * from #dummy
++go
++if object_id('done_test2') is not NULL drop proc done_test2
++go
++create proc done_test2 
++as 
++	select * from #dummy where s = 'aaa' 
++	select * from #dummy
++go
++select * from #dummy	/* normal row */
++go
++set nocount on
++go
++select * from #dummy	/* normal row with no count */
++go
++set nocount off
++go
++select * from #dummy where 0=1	/* normal row without rows */
++go
++select dklghdlgkh from #dummy	/* error query */
++go
++/* stored procedure call with output parameters */
++declare @s varchar(10) exec done_test @s output	
++go
++exec done_test2
++go
++drop proc done_test
++go
++drop proc done_test2
++go
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index bd14096..5c54197 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.35 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.36 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[4096];
+@@ -48,8 +48,7 @@ init_proc(DBPROCESS * dbproc, const char *name)
+ 	if (name[0] != '#') {
+ 		fprintf(stdout, "Dropping procedure %s\n", name);
+ 		add_bread_crumb();
+-		sprintf(cmd, "DROP PROCEDURE %s", name);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		add_bread_crumb();
+ 		dbsqlexec(dbproc);
+ 		add_bread_crumb();
+@@ -60,8 +59,7 @@ init_proc(DBPROCESS * dbproc, const char *name)
+ 	}
+ 
+ 	fprintf(stdout, "Creating procedure %s\n", name);
+-	sprintf(cmd, procedure_sql, name);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	if ((ret = dbsqlexec(dbproc)) == FAIL) {
+ 		add_bread_crumb();
+ 		if (name[0] == '#')
+@@ -414,8 +412,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping procedure\n");
+ 	add_bread_crumb();
+-	sprintf(cmd, "DROP PROCEDURE %s", proc_name);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -426,7 +423,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 
+ 	free(save_param.name);
+diff --git a/src/dblib/unittests/rpc.sql b/src/dblib/unittests/rpc.sql
+new file mode 100644
+index 0000000..7b35e76
+--- /dev/null
++++ b/src/dblib/unittests/rpc.sql
+@@ -0,0 +1,44 @@
++CREATE PROCEDURE #t0022 
++  @null_input varchar(30) OUTPUT 
++, @first_type varchar(30) OUTPUT 
++, @nullout int OUTPUT
++, @nrows int OUTPUT 
++, @c varchar(20)
++, @nv nvarchar(20) = N'hello'
++AS 
++BEGIN 
++select @null_input = max(convert(varchar(30), name)) from systypes 
++select @first_type = min(convert(varchar(30), name)) from systypes 
++select name from sysobjects where 0=1
++select distinct convert(varchar(30), name) as 'type'  from systypes 
++where name in ('int', 'char', 'text') 
++select @nrows = @@rowcount 
++select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' 
++return 42 
++END 
++
++go
++DROP PROCEDURE t0022
++go
++CREATE PROCEDURE t0022 
++  @null_input varchar(30) OUTPUT 
++, @first_type varchar(30) OUTPUT 
++, @nullout int OUTPUT
++, @nrows int OUTPUT 
++, @c varchar(20)
++, @nv nvarchar(20) = N'hello'
++AS 
++BEGIN 
++select @null_input = max(convert(varchar(30), name)) from systypes 
++select @first_type = min(convert(varchar(30), name)) from systypes 
++select name from sysobjects where 0=1
++select distinct convert(varchar(30), name) as 'type'  from systypes 
++where name in ('int', 'char', 'text') 
++select @nrows = @@rowcount 
++select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' 
++return 42 
++END 
++
++go
++DROP PROCEDURE t0022
++go
+diff --git a/src/dblib/unittests/t0001.c b/src/dblib/unittests/t0001.c
+index 9d592b5..56ae4d8 100644
+--- a/src/dblib/unittests/t0001.c
++++ b/src/dblib/unittests/t0001.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.27 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -82,36 +82,20 @@ main(int argc, char **argv)
+ #ifdef DBQUOTEDIDENT
+ 	fprintf(stdout, "QUOTED_IDENTIFIER is %s\n", (dbisopt(dbproc, DBQUOTEDIDENT, NULL))? "ON":"OFF");
+ #endif
+-	
+-	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0001 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+-	fprintf(stdout, "insert\n");
+-	for (i = 0; i < rows_to_add; i++) {
+-		char cmd[1024];
+-
+-#ifdef DBQUOTEDIDENT
+-		if(dbisopt(dbproc, DBQUOTEDIDENT, NULL)) 
+-			sprintf(cmd, "insert into #dblib0001 values (%d, 'row %03d')", i, i);
+-		else
+-			sprintf(cmd, "insert into #dblib0001 values (%d, \"row %03d\")", i, i);
+-#else
+-		sprintf(cmd, "insert into #dblib0001 values (%d, 'row %03d')", i, i);
+-#endif
+-		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++	for (i = 0; i < rows_to_add && sql_cmd(dbproc, INPUT) == SUCCEED; i++) {
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) == SUCCEED) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	fprintf(stdout, "select\n");
+-	dbcmd(dbproc, "select * from #dblib0001 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -119,7 +103,7 @@ main(int argc, char **argv)
+ 	if (dbresults(dbproc) != SUCCEED) {
+ 		add_bread_crumb();
+ 		failed = 1;
+-		fprintf(stdout, "Was expecting a result set.\n");
++		fprintf(stderr, "error: expected a result set, none returned.\n");
+ 		exit(1);
+ 	}
+ 	add_bread_crumb();
+@@ -186,7 +170,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0001.sql b/src/dblib/unittests/t0001.sql
+new file mode 100644
+index 0000000..c872736
+--- /dev/null
++++ b/src/dblib/unittests/t0001.sql
+@@ -0,0 +1,105 @@
++create table #dblib0001 (i int not null, s char(10) not null)
++go
++insert into #dblib0001 values (0, "row 000")
++go
++insert into #dblib0001 values (1, "row 001")
++go
++insert into #dblib0001 values (2, "row 002")
++go
++insert into #dblib0001 values (3, "row 003")
++go
++insert into #dblib0001 values (4, "row 004")
++go
++insert into #dblib0001 values (5, "row 005")
++go
++insert into #dblib0001 values (6, "row 006")
++go
++insert into #dblib0001 values (7, "row 007")
++go
++insert into #dblib0001 values (8, "row 008")
++go
++insert into #dblib0001 values (9, "row 009")
++go
++insert into #dblib0001 values (10, "row 010")
++go
++insert into #dblib0001 values (11, "row 011")
++go
++insert into #dblib0001 values (12, "row 012")
++go
++insert into #dblib0001 values (13, "row 013")
++go
++insert into #dblib0001 values (14, "row 014")
++go
++insert into #dblib0001 values (15, "row 015")
++go
++insert into #dblib0001 values (16, "row 016")
++go
++insert into #dblib0001 values (17, "row 017")
++go
++insert into #dblib0001 values (18, "row 018")
++go
++insert into #dblib0001 values (19, "row 019")
++go
++insert into #dblib0001 values (20, "row 020")
++go
++insert into #dblib0001 values (21, "row 021")
++go
++insert into #dblib0001 values (22, "row 022")
++go
++insert into #dblib0001 values (23, "row 023")
++go
++insert into #dblib0001 values (24, "row 024")
++go
++insert into #dblib0001 values (25, "row 025")
++go
++insert into #dblib0001 values (26, "row 026")
++go
++insert into #dblib0001 values (27, "row 027")
++go
++insert into #dblib0001 values (28, "row 028")
++go
++insert into #dblib0001 values (29, "row 029")
++go
++insert into #dblib0001 values (30, "row 030")
++go
++insert into #dblib0001 values (31, "row 031")
++go
++insert into #dblib0001 values (32, "row 032")
++go
++insert into #dblib0001 values (33, "row 033")
++go
++insert into #dblib0001 values (34, "row 034")
++go
++insert into #dblib0001 values (35, "row 035")
++go
++insert into #dblib0001 values (36, "row 036")
++go
++insert into #dblib0001 values (37, "row 037")
++go
++insert into #dblib0001 values (38, "row 038")
++go
++insert into #dblib0001 values (39, "row 039")
++go
++insert into #dblib0001 values (40, "row 040")
++go
++insert into #dblib0001 values (41, "row 041")
++go
++insert into #dblib0001 values (42, "row 042")
++go
++insert into #dblib0001 values (43, "row 043")
++go
++insert into #dblib0001 values (44, "row 044")
++go
++insert into #dblib0001 values (45, "row 045")
++go
++insert into #dblib0001 values (46, "row 046")
++go
++insert into #dblib0001 values (47, "row 047")
++go
++insert into #dblib0001 values (48, "row 048")
++go
++insert into #dblib0001 values (49, "row 049")
++go
++select * from #dblib0001 order by i
++go
++/* dbclose() at Sat Jan 31 21:36:54 2009 */
+diff --git a/src/dblib/unittests/t0002.c b/src/dblib/unittests/t0002.c
+index e5a3474..7f65bc1 100644
+--- a/src/dblib/unittests/t0002.c
++++ b/src/dblib/unittests/t0002.c
+@@ -10,7 +10,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.22 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.23 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -47,11 +47,6 @@ main(int argc, char **argv)
+ 
+ 	const int buffer_count = 10;
+ 	const int rows_to_add = 50;
+-	const char tablename[] = "#dblib0002";
+-	const char drop_if_exists[] = "if exists ( select 1 "
+-						  "from tempdb..sysobjects "
+-						  "where id = object_id('tempdb..%s') )\n"
+-				      "\tdrop table %s\n";
+ 
+ 	set_malloc_options();
+ 
+@@ -94,8 +89,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	add_bread_crumb();
+-	fprintf(stdout, drop_if_exists, tablename, tablename);
+-	dbfcmd(dbproc,  drop_if_exists, tablename, tablename);
++	sql_cmd(dbproc,  INPUT); /* drop table if exists */
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -108,32 +102,24 @@ main(int argc, char **argv)
+ 	}
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "create table %s (i int not null, s char(10) not null)\n", tablename);
+-	dbfcmd(dbproc,  "create table %s (i int not null, s char(10) not null)", tablename);
++	sql_cmd(dbproc,  INPUT); /* create table */
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+-	fprintf(stdout, "insert into %s [%d rows]\n", tablename, rows_to_add);
+ 	for (i = 1; i <= rows_to_add; i++) {
+-	char cmd[1024];
+-
+-		sprintf(cmd, "insert into %s values (%d, 'row %03d')", tablename, i, i);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	fprintf(stdout, "select * from %s order by i\n", tablename);
+-	dbfcmd(dbproc,  "select * from %s order by i\n", tablename);
+-	dbfcmd(dbproc,  "select * from %s order by i\n", tablename);	/* two result sets */
++	sql_cmd(dbproc, INPUT);	/* two result sets */
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+-
+ 	for (iresults=1; iresults <= 2; iresults++ ) {
+ 		fprintf(stdout, "fetching resultset %i\n", iresults);
+ 		if (dbresults(dbproc) != SUCCEED) {
+@@ -257,7 +243,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0002.sql b/src/dblib/unittests/t0002.sql
+new file mode 100644
+index 0000000..1c96f38
+--- /dev/null
++++ b/src/dblib/unittests/t0002.sql
+@@ -0,0 +1,109 @@
++if exists ( select 1 from tempdb..sysobjects where id = object_id('tempdb..#dblib0002') )
++	drop table #dblib0002
++
++go
++create table #dblib0002 (i int not null, s char(10) not null)
++go
++insert into #dblib0002 values (1, 'row 001')
++go
++insert into #dblib0002 values (2, 'row 002')
++go
++insert into #dblib0002 values (3, 'row 003')
++go
++insert into #dblib0002 values (4, 'row 004')
++go
++insert into #dblib0002 values (5, 'row 005')
++go
++insert into #dblib0002 values (6, 'row 006')
++go
++insert into #dblib0002 values (7, 'row 007')
++go
++insert into #dblib0002 values (8, 'row 008')
++go
++insert into #dblib0002 values (9, 'row 009')
++go
++insert into #dblib0002 values (10, 'row 010')
++go
++insert into #dblib0002 values (11, 'row 011')
++go
++insert into #dblib0002 values (12, 'row 012')
++go
++insert into #dblib0002 values (13, 'row 013')
++go
++insert into #dblib0002 values (14, 'row 014')
++go
++insert into #dblib0002 values (15, 'row 015')
++go
++insert into #dblib0002 values (16, 'row 016')
++go
++insert into #dblib0002 values (17, 'row 017')
++go
++insert into #dblib0002 values (18, 'row 018')
++go
++insert into #dblib0002 values (19, 'row 019')
++go
++insert into #dblib0002 values (20, 'row 020')
++go
++insert into #dblib0002 values (21, 'row 021')
++go
++insert into #dblib0002 values (22, 'row 022')
++go
++insert into #dblib0002 values (23, 'row 023')
++go
++insert into #dblib0002 values (24, 'row 024')
++go
++insert into #dblib0002 values (25, 'row 025')
++go
++insert into #dblib0002 values (26, 'row 026')
++go
++insert into #dblib0002 values (27, 'row 027')
++go
++insert into #dblib0002 values (28, 'row 028')
++go
++insert into #dblib0002 values (29, 'row 029')
++go
++insert into #dblib0002 values (30, 'row 030')
++go
++insert into #dblib0002 values (31, 'row 031')
++go
++insert into #dblib0002 values (32, 'row 032')
++go
++insert into #dblib0002 values (33, 'row 033')
++go
++insert into #dblib0002 values (34, 'row 034')
++go
++insert into #dblib0002 values (35, 'row 035')
++go
++insert into #dblib0002 values (36, 'row 036')
++go
++insert into #dblib0002 values (37, 'row 037')
++go
++insert into #dblib0002 values (38, 'row 038')
++go
++insert into #dblib0002 values (39, 'row 039')
++go
++insert into #dblib0002 values (40, 'row 040')
++go
++insert into #dblib0002 values (41, 'row 041')
++go
++insert into #dblib0002 values (42, 'row 042')
++go
++insert into #dblib0002 values (43, 'row 043')
++go
++insert into #dblib0002 values (44, 'row 044')
++go
++insert into #dblib0002 values (45, 'row 045')
++go
++insert into #dblib0002 values (46, 'row 046')
++go
++insert into #dblib0002 values (47, 'row 047')
++go
++insert into #dblib0002 values (48, 'row 048')
++go
++insert into #dblib0002 values (49, 'row 049')
++go
++insert into #dblib0002 values (50, 'row 050')
++go
++select * from #dblib0002 order by i
++select * from #dblib0002 order by i
++go
+diff --git a/src/dblib/unittests/t0003.c b/src/dblib/unittests/t0003.c
+index 98b444d..4d9dcc5 100644
+--- a/src/dblib/unittests/t0003.c
++++ b/src/dblib/unittests/t0003.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.14 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.15 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -65,7 +65,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0003 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -73,10 +73,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-	char cmd[1024];
+-
+-		sprintf(cmd, "insert into #dblib0003 values (%d, 'row %03d')", i, i);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -84,7 +81,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	dbcmd(dbproc, "select * from #dblib0003 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -156,7 +153,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0003.sql b/src/dblib/unittests/t0003.sql
+new file mode 100644
+index 0000000..91fdb6a
+--- /dev/null
++++ b/src/dblib/unittests/t0003.sql
+@@ -0,0 +1,102 @@
++create table #dblib0003 (i int not null, s char(10) not null)
++go
++insert into #dblib0003 values (1, 'row 001')
++go
++insert into #dblib0003 values (2, 'row 002')
++go
++insert into #dblib0003 values (3, 'row 003')
++go
++insert into #dblib0003 values (4, 'row 004')
++go
++insert into #dblib0003 values (5, 'row 005')
++go
++insert into #dblib0003 values (6, 'row 006')
++go
++insert into #dblib0003 values (7, 'row 007')
++go
++insert into #dblib0003 values (8, 'row 008')
++go
++insert into #dblib0003 values (9, 'row 009')
++go
++insert into #dblib0003 values (10, 'row 010')
++go
++insert into #dblib0003 values (11, 'row 011')
++go
++insert into #dblib0003 values (12, 'row 012')
++go
++insert into #dblib0003 values (13, 'row 013')
++go
++insert into #dblib0003 values (14, 'row 014')
++go
++insert into #dblib0003 values (15, 'row 015')
++go
++insert into #dblib0003 values (16, 'row 016')
++go
++insert into #dblib0003 values (17, 'row 017')
++go
++insert into #dblib0003 values (18, 'row 018')
++go
++insert into #dblib0003 values (19, 'row 019')
++go
++insert into #dblib0003 values (20, 'row 020')
++go
++insert into #dblib0003 values (21, 'row 021')
++go
++insert into #dblib0003 values (22, 'row 022')
++go
++insert into #dblib0003 values (23, 'row 023')
++go
++insert into #dblib0003 values (24, 'row 024')
++go
++insert into #dblib0003 values (25, 'row 025')
++go
++insert into #dblib0003 values (26, 'row 026')
++go
++insert into #dblib0003 values (27, 'row 027')
++go
++insert into #dblib0003 values (28, 'row 028')
++go
++insert into #dblib0003 values (29, 'row 029')
++go
++insert into #dblib0003 values (30, 'row 030')
++go
++insert into #dblib0003 values (31, 'row 031')
++go
++insert into #dblib0003 values (32, 'row 032')
++go
++insert into #dblib0003 values (33, 'row 033')
++go
++insert into #dblib0003 values (34, 'row 034')
++go
++insert into #dblib0003 values (35, 'row 035')
++go
++insert into #dblib0003 values (36, 'row 036')
++go
++insert into #dblib0003 values (37, 'row 037')
++go
++insert into #dblib0003 values (38, 'row 038')
++go
++insert into #dblib0003 values (39, 'row 039')
++go
++insert into #dblib0003 values (40, 'row 040')
++go
++insert into #dblib0003 values (41, 'row 041')
++go
++insert into #dblib0003 values (42, 'row 042')
++go
++insert into #dblib0003 values (43, 'row 043')
++go
++insert into #dblib0003 values (44, 'row 044')
++go
++insert into #dblib0003 values (45, 'row 045')
++go
++insert into #dblib0003 values (46, 'row 046')
++go
++insert into #dblib0003 values (47, 'row 047')
++go
++insert into #dblib0003 values (48, 'row 048')
++go
++insert into #dblib0003 values (49, 'row 049')
++go
++select * from #dblib0003 order by i
++go
+diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c
+index ea06e9e..48aa4a1 100644
+--- a/src/dblib/unittests/t0004.c
++++ b/src/dblib/unittests/t0004.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.17 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.18 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -14,7 +14,6 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int
+ main(int argc, char **argv)
+ {
+-	char cmd[1024];
+ 	const int rows_to_add = 50;
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+@@ -57,7 +56,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0004 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -65,18 +64,14 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sprintf(cmd, "insert into #dblib0004 values (%d, 'row %04d')", i, i);
+-		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	sprintf(cmd, "select * from #dblib0004 where i<=25 order by i");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT); /* select */
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -138,9 +133,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "second select\n");
+ 
+-	sprintf(cmd, "select * from #dblib0004 where i>950 order by i");
+-	fprintf(stdout, "%s\n", cmd);
+-	if (SUCCEED != dbcmd(dbproc, cmd)) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -155,7 +148,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0004.sql b/src/dblib/unittests/t0004.sql
+new file mode 100644
+index 0000000..22c13c8
+--- /dev/null
++++ b/src/dblib/unittests/t0004.sql
+@@ -0,0 +1,108 @@
++create table #dblib0004 (i int not null, s char(10) not null)
++go
++insert into #dblib0004 values (1, 'row 0001')
++go
++insert into #dblib0004 values (2, 'row 0002')
++go
++insert into #dblib0004 values (3, 'row 0003')
++go
++insert into #dblib0004 values (4, 'row 0004')
++go
++insert into #dblib0004 values (5, 'row 0005')
++go
++insert into #dblib0004 values (6, 'row 0006')
++go
++insert into #dblib0004 values (7, 'row 0007')
++go
++insert into #dblib0004 values (8, 'row 0008')
++go
++insert into #dblib0004 values (9, 'row 0009')
++go
++insert into #dblib0004 values (10, 'row 0010')
++go
++insert into #dblib0004 values (11, 'row 0011')
++go
++insert into #dblib0004 values (12, 'row 0012')
++go
++insert into #dblib0004 values (13, 'row 0013')
++go
++insert into #dblib0004 values (14, 'row 0014')
++go
++insert into #dblib0004 values (15, 'row 0015')
++go
++insert into #dblib0004 values (16, 'row 0016')
++go
++insert into #dblib0004 values (17, 'row 0017')
++go
++insert into #dblib0004 values (18, 'row 0018')
++go
++insert into #dblib0004 values (19, 'row 0019')
++go
++insert into #dblib0004 values (20, 'row 0020')
++go
++insert into #dblib0004 values (21, 'row 0021')
++go
++insert into #dblib0004 values (22, 'row 0022')
++go
++insert into #dblib0004 values (23, 'row 0023')
++go
++insert into #dblib0004 values (24, 'row 0024')
++go
++insert into #dblib0004 values (25, 'row 0025')
++go
++insert into #dblib0004 values (26, 'row 0026')
++go
++insert into #dblib0004 values (27, 'row 0027')
++go
++insert into #dblib0004 values (28, 'row 0028')
++go
++insert into #dblib0004 values (29, 'row 0029')
++go
++insert into #dblib0004 values (30, 'row 0030')
++go
++insert into #dblib0004 values (31, 'row 0031')
++go
++insert into #dblib0004 values (32, 'row 0032')
++go
++insert into #dblib0004 values (33, 'row 0033')
++go
++insert into #dblib0004 values (34, 'row 0034')
++go
++insert into #dblib0004 values (35, 'row 0035')
++go
++insert into #dblib0004 values (36, 'row 0036')
++go
++insert into #dblib0004 values (37, 'row 0037')
++go
++insert into #dblib0004 values (38, 'row 0038')
++go
++insert into #dblib0004 values (39, 'row 0039')
++go
++insert into #dblib0004 values (40, 'row 0040')
++go
++insert into #dblib0004 values (41, 'row 0041')
++go
++insert into #dblib0004 values (42, 'row 0042')
++go
++insert into #dblib0004 values (43, 'row 0043')
++go
++insert into #dblib0004 values (44, 'row 0044')
++go
++insert into #dblib0004 values (45, 'row 0045')
++go
++insert into #dblib0004 values (46, 'row 0046')
++go
++insert into #dblib0004 values (47, 'row 0047')
++go
++insert into #dblib0004 values (48, 'row 0048')
++go
++insert into #dblib0004 values (49, 'row 0049')
++go
++select * from #dblib0004 where i<=25 order by i
++go
++/* The following statement fails intentionally: 
++ * the unit test is checking that db-lib returns FAIL
++ * when results have not been fully processed. 
++ */
++select * from #dblib0004 where i<=25 order by i
++go
+diff --git a/src/dblib/unittests/t0005.c b/src/dblib/unittests/t0005.c
+index 8c24410..ff5b5ad 100644
+--- a/src/dblib/unittests/t0005.c
++++ b/src/dblib/unittests/t0005.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0005.c,v 1.24 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0005.c,v 1.25 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -17,7 +17,6 @@ main(int argc, char **argv)
+ 	int i;
+ 	char teststr[1024];
+ 	DBINT testint;
+-	char cmd[1024];
+ 	int failed = 0;
+ 	int expected_error;
+ 
+@@ -56,7 +55,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	if (SUCCEED != dbcmd(dbproc, "create table #dblib0005 " "(i int not null, s char(10) not null)")) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -72,8 +71,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sprintf(cmd, "insert into #dblib0005 values (%d, 'row %04d')", i, i);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -81,9 +79,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 
+-	sprintf(cmd, "select * from #dblib0005 where i < 5 order by i");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -140,13 +136,10 @@ main(int argc, char **argv)
+ 	fprintf(stdout, "This query should succeeded as we have fetched the exact\n"
+ 			"number of rows in the result set\n");
+ 
+-	sprintf(cmd, "select * from #dblib0005 where i < 6 order by i");
+-	fprintf(stdout, "%s\n", cmd);
+-	
+ 	expected_error = 20019;
+ 	dbsetuserdata(dbproc, (BYTE*) &expected_error);
+ 
+-	if (SUCCEED != dbcmd(dbproc, cmd)) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -205,12 +198,9 @@ main(int argc, char **argv)
+ 		printf("Read a row of data -> %d %s\n", (int) testint, teststr);
+ 	}
+ 
+-	fprintf(stdout, "This query should fail as we have not fetched all the\n");
+-	fprintf(stdout, "rows in the result set\n");
++	fprintf(stdout, "Testing anticipated failure\n");
+ 
+-	sprintf(cmd, "select * from #dblib0005 where i > 950 order by i");
+-	fprintf(stdout, "%s\n", cmd);
+-	if (SUCCEED != dbcmd(dbproc, cmd)) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -225,8 +215,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping proc\n");
+ 	add_bread_crumb();
+-	sprintf(cmd, "if object_id('t0005_proc') is not null drop procedure t0005_proc");
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -236,12 +225,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating proc\n");
+-	sprintf(cmd, "create proc t0005_proc (@b int out) as\nbegin\n"
+-		"select * from #dblib0005 where i < 6 order by i\n" "select @b = 42\n" "end\n");
+-
+-	fprintf(stdout, "%s\n", cmd);
+-
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		fprintf(stderr, "%s:%d: failed to create procedure\n", __FILE__, __LINE__);
+@@ -252,10 +236,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "calling proc\n");
+-	sprintf(cmd, "declare @myout int exec t0005_proc @b = @myout output");
+-	fprintf(stdout, "%s\n", cmd);
+-
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		fprintf(stderr, "%s:%d: failed to call procedure\n", __FILE__, __LINE__);
+@@ -309,12 +290,11 @@ main(int argc, char **argv)
+ 	}
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "This next command should succeed as we have fetched the exact\n"
+-			"number of rows in the result set\n");
++	fprintf(stdout, "Calling dbsqlexec before dbnextrow returns NO_MORE_ROWS\n");
++	fprintf(stdout, "The following command should succeed because\n"
++			"we have fetched the exact number of rows in the result set\n");
+ 
+-	sprintf(cmd, "select getdate()");
+-	fprintf(stdout, "%s\n", cmd);
+-	if (SUCCEED != dbcmd(dbproc, cmd)) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -326,7 +306,7 @@ main(int argc, char **argv)
+ 
+ 	dbcancel(dbproc);
+ 
+-	dbcmd(dbproc, "drop procedure t0005_proc");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -335,7 +315,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0005.sql b/src/dblib/unittests/t0005.sql
+new file mode 100644
+index 0000000..58a3896
+--- /dev/null
++++ b/src/dblib/unittests/t0005.sql
+@@ -0,0 +1,125 @@
++create table #dblib0005 (i int not null, s char(10) not null)
++go
++insert into #dblib0005 values (1, 'row 0001')
++go
++insert into #dblib0005 values (2, 'row 0002')
++go
++insert into #dblib0005 values (3, 'row 0003')
++go
++insert into #dblib0005 values (4, 'row 0004')
++go
++insert into #dblib0005 values (5, 'row 0005')
++go
++insert into #dblib0005 values (6, 'row 0006')
++go
++insert into #dblib0005 values (7, 'row 0007')
++go
++insert into #dblib0005 values (8, 'row 0008')
++go
++insert into #dblib0005 values (9, 'row 0009')
++go
++insert into #dblib0005 values (10, 'row 0010')
++go
++insert into #dblib0005 values (11, 'row 0011')
++go
++insert into #dblib0005 values (12, 'row 0012')
++go
++insert into #dblib0005 values (13, 'row 0013')
++go
++insert into #dblib0005 values (14, 'row 0014')
++go
++insert into #dblib0005 values (15, 'row 0015')
++go
++insert into #dblib0005 values (16, 'row 0016')
++go
++insert into #dblib0005 values (17, 'row 0017')
++go
++insert into #dblib0005 values (18, 'row 0018')
++go
++insert into #dblib0005 values (19, 'row 0019')
++go
++insert into #dblib0005 values (20, 'row 0020')
++go
++insert into #dblib0005 values (21, 'row 0021')
++go
++insert into #dblib0005 values (22, 'row 0022')
++go
++insert into #dblib0005 values (23, 'row 0023')
++go
++insert into #dblib0005 values (24, 'row 0024')
++go
++insert into #dblib0005 values (25, 'row 0025')
++go
++insert into #dblib0005 values (26, 'row 0026')
++go
++insert into #dblib0005 values (27, 'row 0027')
++go
++insert into #dblib0005 values (28, 'row 0028')
++go
++insert into #dblib0005 values (29, 'row 0029')
++go
++insert into #dblib0005 values (30, 'row 0030')
++go
++insert into #dblib0005 values (31, 'row 0031')
++go
++insert into #dblib0005 values (32, 'row 0032')
++go
++insert into #dblib0005 values (33, 'row 0033')
++go
++insert into #dblib0005 values (34, 'row 0034')
++go
++insert into #dblib0005 values (35, 'row 0035')
++go
++insert into #dblib0005 values (36, 'row 0036')
++go
++insert into #dblib0005 values (37, 'row 0037')
++go
++insert into #dblib0005 values (38, 'row 0038')
++go
++insert into #dblib0005 values (39, 'row 0039')
++go
++insert into #dblib0005 values (40, 'row 0040')
++go
++insert into #dblib0005 values (41, 'row 0041')
++go
++insert into #dblib0005 values (42, 'row 0042')
++go
++insert into #dblib0005 values (43, 'row 0043')
++go
++insert into #dblib0005 values (44, 'row 0044')
++go
++insert into #dblib0005 values (45, 'row 0045')
++go
++insert into #dblib0005 values (46, 'row 0046')
++go
++insert into #dblib0005 values (47, 'row 0047')
++go
++insert into #dblib0005 values (48, 'row 0048')
++go
++insert into #dblib0005 values (49, 'row 0049')
++go
++select * from #dblib0005 where i < 5 order by i
++go
++select * from #dblib0005 where i < 6 order by i
++go
++/*
++ * The following query should fail because the test 
++ * has not fetched all the rows in the result set.
++ */
++select * from #dblib0005 where i > 950 order by i
++go
++if object_id('t0005_proc') is not null drop procedure t0005_proc
++go
++create proc t0005_proc (@b int out) as
++begin
++select * from #dblib0005 where i < 6 order by i
++select @b = 42
++end
++
++go
++declare @myout int exec t0005_proc @b = @myout output
++go
++select getdate()
++go
++drop procedure t0005_proc
++go
+diff --git a/src/dblib/unittests/t0006.c b/src/dblib/unittests/t0006.c
+index 019c177..127ac63 100644
+--- a/src/dblib/unittests/t0006.c
++++ b/src/dblib/unittests/t0006.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0006.c,v 1.17 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0006.c,v 1.18 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -92,7 +92,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0006 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -100,10 +100,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-	char cmd[1024];
+-
+-		sprintf(cmd, "insert into #dblib0006 values (%d, 'row %04d')", i, i);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -111,7 +108,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "first select\n");
+-	if (SUCCEED != dbcmd(dbproc, "select * from #dblib0006 where i<50 order by i")) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -148,7 +145,7 @@ main(int argc, char **argv)
+ 	testint = -1;
+ 	strcpy(teststr, "bogus");
+ 	fprintf(stdout, "second select\n");
+-	dbcmd(dbproc, "select * from #dblib0006 where i>=25 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -174,7 +171,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0006.sql b/src/dblib/unittests/t0006.sql
+new file mode 100644
+index 0000000..0ee11eb
+--- /dev/null
++++ b/src/dblib/unittests/t0006.sql
+@@ -0,0 +1,104 @@
++create table #dblib0006 (i int not null, s char(10) not null)
++go
++insert into #dblib0006 values (1, 'row 0001')
++go
++insert into #dblib0006 values (2, 'row 0002')
++go
++insert into #dblib0006 values (3, 'row 0003')
++go
++insert into #dblib0006 values (4, 'row 0004')
++go
++insert into #dblib0006 values (5, 'row 0005')
++go
++insert into #dblib0006 values (6, 'row 0006')
++go
++insert into #dblib0006 values (7, 'row 0007')
++go
++insert into #dblib0006 values (8, 'row 0008')
++go
++insert into #dblib0006 values (9, 'row 0009')
++go
++insert into #dblib0006 values (10, 'row 0010')
++go
++insert into #dblib0006 values (11, 'row 0011')
++go
++insert into #dblib0006 values (12, 'row 0012')
++go
++insert into #dblib0006 values (13, 'row 0013')
++go
++insert into #dblib0006 values (14, 'row 0014')
++go
++insert into #dblib0006 values (15, 'row 0015')
++go
++insert into #dblib0006 values (16, 'row 0016')
++go
++insert into #dblib0006 values (17, 'row 0017')
++go
++insert into #dblib0006 values (18, 'row 0018')
++go
++insert into #dblib0006 values (19, 'row 0019')
++go
++insert into #dblib0006 values (20, 'row 0020')
++go
++insert into #dblib0006 values (21, 'row 0021')
++go
++insert into #dblib0006 values (22, 'row 0022')
++go
++insert into #dblib0006 values (23, 'row 0023')
++go
++insert into #dblib0006 values (24, 'row 0024')
++go
++insert into #dblib0006 values (25, 'row 0025')
++go
++insert into #dblib0006 values (26, 'row 0026')
++go
++insert into #dblib0006 values (27, 'row 0027')
++go
++insert into #dblib0006 values (28, 'row 0028')
++go
++insert into #dblib0006 values (29, 'row 0029')
++go
++insert into #dblib0006 values (30, 'row 0030')
++go
++insert into #dblib0006 values (31, 'row 0031')
++go
++insert into #dblib0006 values (32, 'row 0032')
++go
++insert into #dblib0006 values (33, 'row 0033')
++go
++insert into #dblib0006 values (34, 'row 0034')
++go
++insert into #dblib0006 values (35, 'row 0035')
++go
++insert into #dblib0006 values (36, 'row 0036')
++go
++insert into #dblib0006 values (37, 'row 0037')
++go
++insert into #dblib0006 values (38, 'row 0038')
++go
++insert into #dblib0006 values (39, 'row 0039')
++go
++insert into #dblib0006 values (40, 'row 0040')
++go
++insert into #dblib0006 values (41, 'row 0041')
++go
++insert into #dblib0006 values (42, 'row 0042')
++go
++insert into #dblib0006 values (43, 'row 0043')
++go
++insert into #dblib0006 values (44, 'row 0044')
++go
++insert into #dblib0006 values (45, 'row 0045')
++go
++insert into #dblib0006 values (46, 'row 0046')
++go
++insert into #dblib0006 values (47, 'row 0047')
++go
++insert into #dblib0006 values (48, 'row 0048')
++go
++insert into #dblib0006 values (49, 'row 0049')
++go
++select * from #dblib0006 where i<50 order by i
++go
++select * from #dblib0006 where i>=25 order by i
++go
+diff --git a/src/dblib/unittests/t0007.c b/src/dblib/unittests/t0007.c
+index f82cc7e..01e0f60 100644
+--- a/src/dblib/unittests/t0007.c
++++ b/src/dblib/unittests/t0007.c
+@@ -5,21 +5,16 @@
+ 
+ #include "common.h"
+ 
+-
+-static char software_version[] = "$Id: t0007.c,v 1.18 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.19 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-
+-
+ static void
+ create_tables(DBPROCESS * dbproc, int rows_to_add)
+ {
+ 	int i;
+-	char cmd[1024];
+-
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0007 (i int not null, s char(12) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -27,24 +22,21 @@ create_tables(DBPROCESS * dbproc, int rows_to_add)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sprintf(cmd, "insert into #dblib0007 values (%d, 'row %07d')", i, i);
+-		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+ 		}
+ 	}
+-}				/* create_tables()  */
++}
+ 
+ 
+ static int
+-start_query(DBPROCESS * dbproc, const char *cmd)
++start_query(DBPROCESS * dbproc)
+ {
+ 	int i;
+ 
+-	fprintf(stdout, "%s\n", cmd);
+-	if (SUCCEED != dbcmd(dbproc, cmd)) {
++	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
+ 		return 0;
+ 	}
+ 	if (SUCCEED != dbsqlexec(dbproc)) {
+@@ -64,7 +56,7 @@ start_query(DBPROCESS * dbproc, const char *cmd)
+ 		add_bread_crumb();
+ 	}
+ 	return 1;
+-}				/* start_query()  */
++}
+ 
+ int
+ main(int argc, char **argv)
+@@ -112,7 +104,7 @@ main(int argc, char **argv)
+ 
+ 	create_tables(dbproc, 10);
+ 
+-	if (!start_query(dbproc, "select * from #dblib0007 where i<=5 order by i")) {
++	if (!start_query(dbproc)) {
+ 		fprintf(stderr, "%s:%d: start_query failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -162,7 +154,7 @@ main(int argc, char **argv)
+ 	expected_error = 20019;
+ 	dbsetuserdata(dbproc, (BYTE*) &expected_error);
+ 
+-	if (start_query(dbproc, "select * from #dblib0007 where i>=5 order by i")) {
++	if (start_query(dbproc)) {
+ 		fprintf(stderr, "%s:%d: start_query should have failed but didn't\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -171,7 +163,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0007.sql b/src/dblib/unittests/t0007.sql
+new file mode 100644
+index 0000000..8101406
+--- /dev/null
++++ b/src/dblib/unittests/t0007.sql
+@@ -0,0 +1,27 @@
++create table #dblib0007 (i int not null, s char(12) not null)
++go
++insert into #dblib0007 values (1, 'row 0000001')
++go
++insert into #dblib0007 values (2, 'row 0000002')
++go
++insert into #dblib0007 values (3, 'row 0000003')
++go
++insert into #dblib0007 values (4, 'row 0000004')
++go
++insert into #dblib0007 values (5, 'row 0000005')
++go
++insert into #dblib0007 values (6, 'row 0000006')
++go
++insert into #dblib0007 values (7, 'row 0000007')
++go
++insert into #dblib0007 values (8, 'row 0000008')
++go
++insert into #dblib0007 values (9, 'row 0000009')
++go
++select * from #dblib0007 where i<=5 order by i
++go
++/*
++ * Second select, should fail: expected_error = 20019
++ */
++select * from #dblib0007 where i>=5 order by i
++go
+diff --git a/src/dblib/unittests/t0008.c b/src/dblib/unittests/t0008.c
+index d81caab..f054dca 100644
+--- a/src/dblib/unittests/t0008.c
++++ b/src/dblib/unittests/t0008.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0008.c,v 1.17 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0008.c,v 1.18 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -159,10 +159,8 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	if (last_read == rows_to_add - 1)
+-		printf("dblib okay for %s\n", __FILE__);
+-	else
+-		fprintf(stderr, "dblib failed for %s last_read %d\n", __FILE__, (int) last_read);
++	fprintf(stdout, "%s %s (last_read: %d)\n", __FILE__, ((last_read != rows_to_add - 1)? "failed!" : "OK"), (int) last_read);
++
+ 	free_bread_crumb();
+ 	return (last_read == rows_to_add - 1) ? 0 : 1;
+ }
+diff --git a/src/dblib/unittests/t0009.c b/src/dblib/unittests/t0009.c
+index 22f1cd4..43ebf3d 100644
+--- a/src/dblib/unittests/t0009.c
++++ b/src/dblib/unittests/t0009.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0009.c,v 1.15 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0009.c,v 1.16 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -60,19 +60,19 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0009 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "insert\n");
+-	dbcmd(dbproc, "insert into #dblib0009 values (1, 'abcdef')");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+-	dbcmd(dbproc, "insert into #dblib0009 values (2, 'abc')");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -80,7 +80,7 @@ main(int argc, char **argv)
+ 
+ 
+ 	fprintf(stdout, "select\n");
+-	dbcmd(dbproc, "select * from #dblib0009 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/t0009.sql b/src/dblib/unittests/t0009.sql
+new file mode 100644
+index 0000000..c96f7c5
+--- /dev/null
++++ b/src/dblib/unittests/t0009.sql
+@@ -0,0 +1,8 @@
++create table #dblib0009 (i int not null, s char(10) not null)
++go
++insert into #dblib0009 values (1, 'abcdef')
++go
++insert into #dblib0009 values (2, 'abc')
++go
++select * from #dblib0009 order by i
++go
+diff --git a/src/dblib/unittests/t0011.c b/src/dblib/unittests/t0011.c
+index 7d0996a..7e2f3b6 100644
+--- a/src/dblib/unittests/t0011.c
++++ b/src/dblib/unittests/t0011.c
+@@ -6,14 +6,14 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0011.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0011.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+ const char long_column[] = "This is a really long column to ensure that the next row ends properly.";
+ const char short_column[] = "Short column";
+ 
+-void insert_row(DBPROCESS * dbproc, char *cmd);
++void insert_row(DBPROCESS * dbproc);
+ int select_rows(DBPROCESS * dbproc, int bind_type);
+ 
+ int
+@@ -43,14 +43,14 @@ main(int argc, char **argv)
+ 	dbloginfree(login);
+ 
+ 	fprintf(stdout, "Dropping table\n");
+-	dbcmd(dbproc, "drop table #dblib0011");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0011 (i int not null, c1 char(200) not null, c2 char(200) null, vc varchar(200) null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -58,18 +58,15 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 
+-	sprintf(cmd, "insert into #dblib0011 values (1, '%s','%s','%s')", long_column, long_column, long_column);
+-	insert_row(dbproc, cmd);
+-	sprintf(cmd, "insert into #dblib0011 values (2, '%s','%s','%s')", short_column, short_column, short_column);
+-	insert_row(dbproc, cmd);
+-	sprintf(cmd, "insert into #dblib0011 values (3, '%s',NULL,NULL)", short_column);
+-	insert_row(dbproc, cmd);
++	insert_row(dbproc);
++	insert_row(dbproc);
++	insert_row(dbproc);
+ 
+ 	failed = select_rows(dbproc, STRINGBIND);
+ 
+ 	dbexit();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	return failed ? 1 : 0;
+ }
+ 
+@@ -84,7 +81,7 @@ select_rows(DBPROCESS * dbproc, int bind_type)
+ 
+ 
+ 	fprintf(stdout, "select\n");
+-	dbcmd(dbproc, "select * from #dblib0011 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 
+@@ -133,10 +130,9 @@ select_rows(DBPROCESS * dbproc, int bind_type)
+ }
+ 
+ void
+-insert_row(DBPROCESS * dbproc, char *cmd)
++insert_row(DBPROCESS * dbproc)
+ {
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0011.sql b/src/dblib/unittests/t0011.sql
+new file mode 100644
+index 0000000..8771f27
+--- /dev/null
++++ b/src/dblib/unittests/t0011.sql
+@@ -0,0 +1,12 @@
++drop table #dblib0011
++go
++create table #dblib0011 (i int not null, c1 char(200) not null, c2 char(200) null, vc varchar(200) null)
++go
++insert into #dblib0011 values (1, 'This is a really long column to ensure that the next row ends properly.','This is a really long column to ensure that the next row ends properly.','This is a really long column to ensure that the next row ends properly.')
++go
++insert into #dblib0011 values (2, 'Short column','Short column','Short column')
++go
++insert into #dblib0011 values (3, 'Short column',NULL,NULL)
++go
++select * from #dblib0011 order by i
++go
+diff --git a/src/dblib/unittests/t0012.c b/src/dblib/unittests/t0012.c
+index 3fe88fa..d7f34ea 100644
+--- a/src/dblib/unittests/t0012.c
++++ b/src/dblib/unittests/t0012.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0012.c,v 1.22 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0012.c,v 1.23 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int failed = 0;
+ 
+@@ -15,8 +15,6 @@ main(int argc, char *argv[])
+ {
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+-	char cmd[512];
+-	char sqlCmd[256];
+ 	char datestring[256];
+ 	DBDATEREC dateinfo;
+ 	DBDATETIME mydatetime;
+@@ -45,29 +43,23 @@ main(int argc, char *argv[])
+ 	fprintf(stdout, "After logon\n");
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0012 (dt datetime not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+-	sprintf(cmd, "insert into #dblib0012 values ('Feb 27 2001 10:24:35:056AM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+-	sprintf(cmd, "insert into #dblib0012 values ('Dec 25 1898 07:30:00:567PM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	sprintf(sqlCmd, "SELECT dt FROM #dblib0012");
+-	dbcmd(dbproc, sqlCmd);
+ 	dbsqlexec(dbproc);
+ 	dbresults(dbproc);
+ 
+@@ -108,7 +100,7 @@ main(int argc, char *argv[])
+ 	dbclose(dbproc);
+ 	dbexit();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0012.sql b/src/dblib/unittests/t0012.sql
+new file mode 100644
+index 0000000..29a8f9c
+--- /dev/null
++++ b/src/dblib/unittests/t0012.sql
+@@ -0,0 +1,8 @@
++create table #dblib0012 (dt datetime not null)
++go
++insert into #dblib0012 values ('Feb 27 2001 10:24:35:056AM')
++go
++insert into #dblib0012 values ('Dec 25 1898 07:30:00:567PM')
++go
++SELECT dt FROM #dblib0012
++go
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index c3044a7..06b2396 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.27 2008/12/02 10:54:38 freddy77 Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -25,16 +25,12 @@ DBPROCESS *dbproc, *dbprocw;
+ static void
+ drop_table(void)
+ {
+-	char cmd[1024];
+-
+ 	if (!dbproc) 
+ 		return;
+ 
+ 	dbcancel(dbproc);
+ 
+-	sprintf(cmd, "drop table " TABLE_NAME);
+-	fprintf(stdout, "sql: %s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -52,11 +48,9 @@ main(int argc, char **argv)
+ 	char *blob, *rblob;
+ 	DBBINARY *textPtr = NULL, *timeStamp = NULL;
+ 	char objname[256];
+-	char sqlCmd[256];
+ 	char rbuf[BLOB_BLOCK_SIZE];
+ 	long numread;
+ 	BOOL readFirstImage;
+-	char cmd[1024];
+ 	int data_ok;
+ #ifdef DBWRITE_OK_FOR_OVER_4K
+ 	int numtowrite, numwritten;
+@@ -112,9 +106,7 @@ main(int argc, char **argv)
+ 	fread((void *) blob, isiz, 1, fp);
+ 	fclose(fp);
+ 
+-	sprintf(cmd, "create table " TABLE_NAME " (i int not null, PigTure image not null)");
+-	fprintf(stdout, "sql: %s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -122,17 +114,13 @@ main(int argc, char **argv)
+ 
+ 	atexit(drop_table);
+ 
+-	sprintf(cmd, "insert into " TABLE_NAME " values (1, '')");
+-	fprintf(stdout, "sql: %s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+-	sprintf(sqlCmd, "SELECT PigTure FROM " TABLE_NAME " WHERE i = 1");
+-	fprintf(stdout, "sql: %s\n", sqlCmd);
+-	dbcmd(dbproc, sqlCmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	if (dbresults(dbproc) != SUCCEED) {
+ 		fprintf(stderr, "Error inserting blob\n");
+@@ -198,10 +186,7 @@ main(int argc, char **argv)
+ 		dbuse(dbproc, DATABASE);
+ 	}
+ #endif
+-	sprintf(cmd, "select i, PigTure from " TABLE_NAME " order by i");
+-
+-	fprintf(stdout, "sql: %s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -236,17 +221,13 @@ main(int argc, char **argv)
+ 	dbnextrow(dbproc);
+ 
+ 	/* get the image */
+-	strcpy(sqlCmd, "SET TEXTSIZE 2147483647");
+-	fprintf(stdout, "sql: %s\n", sqlCmd);
+-	dbcmd(dbproc, sqlCmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	dbresults(dbproc);
+ 
+ 	fprintf(stdout, "select 2\n");
+ 
+-	sprintf(sqlCmd, "SELECT PigTure FROM " TABLE_NAME " WHERE i = 1");
+-	fprintf(stdout, "sql: %s\n", sqlCmd);
+-	dbcmd(dbproc, sqlCmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	if (dbresults(dbproc) != SUCCEED) {
+ 		fprintf(stderr, "Error extracting blob\n");
+@@ -303,6 +284,6 @@ main(int argc, char **argv)
+ 
+ 	dbexit();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0013.sql b/src/dblib/unittests/t0013.sql
+new file mode 100644
+index 0000000..9f976c2
+--- /dev/null
++++ b/src/dblib/unittests/t0013.sql
+@@ -0,0 +1,14 @@
++create table freetds_dblib_t0013 (i int not null, PigTure image not null)
++go
++insert into freetds_dblib_t0013 values (1, '')
++go
++SELECT PigTure FROM freetds_dblib_t0013 WHERE i = 1
++go
++select i, PigTure from freetds_dblib_t0013 order by i
++go
++SET TEXTSIZE 2147483647
++go
++SELECT PigTure FROM freetds_dblib_t0013 WHERE i = 1
++go
++drop table freetds_dblib_t0013
++go
+diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c
+index 96ca83e..9666086 100644
+--- a/src/dblib/unittests/t0014.c
++++ b/src/dblib/unittests/t0014.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0014.c,v 1.28 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0014.c,v 1.29 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -85,14 +85,14 @@ main(int argc, char **argv)
+ 
+ 	/* FIXME this test seem to not work using temporary tables (sybase?)... */
+ 	fprintf(stdout, "Dropping table\n");
+-	dbcmd(dbproc, "if object_id('dblib0014') is not null drop table dblib0014");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table dblib0014 (i int not null, PigTure image not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -103,9 +103,8 @@ main(int argc, char **argv)
+ 	for (i = 0; i < rows_to_add; i++) {
+ 	char cmd[1024];
+ 
+-		sprintf(cmd, "insert into dblib0014 values (%d, '')", i);
+ 		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -113,8 +112,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	for (i = 0; i < rows_to_add; i++) {
+-		sprintf(sqlCmd, "SELECT PigTure FROM dblib0014 WHERE i = %d", i);
+-		dbcmd(dbproc, sqlCmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		if (dbresults(dbproc) != SUCCEED) {
+ 			fprintf(stderr, "Error inserting blob\n");
+@@ -159,7 +157,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "select\n");
+ 
+-	dbcmd(dbproc, "select * from dblib0014 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -250,7 +248,7 @@ main(int argc, char **argv)
+ 	free(blob);
+ 
+ 	fprintf(stdout, "Dropping table\n");
+-	dbcmd(dbproc, "drop table dblib0014");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0014.sql b/src/dblib/unittests/t0014.sql
+new file mode 100644
+index 0000000..7d1d96c
+--- /dev/null
++++ b/src/dblib/unittests/t0014.sql
+@@ -0,0 +1,20 @@
++if object_id('dblib0014') is not null drop table dblib0014
++go
++create table dblib0014 (i int not null, PigTure image not null)
++go
++insert into dblib0014 values (0, '')
++go
++insert into dblib0014 values (1, '')
++go
++insert into dblib0014 values (2, '')
++go
++SELECT PigTure FROM dblib0014 WHERE i = 0
++go
++SELECT PigTure FROM dblib0014 WHERE i = 1
++go
++SELECT PigTure FROM dblib0014 WHERE i = 2
++go
++select * from dblib0014 order by i
++go
++drop table dblib0014
++go
+diff --git a/src/dblib/unittests/t0015.c b/src/dblib/unittests/t0015.c
+index ba8a3b8..16d8176 100644
+--- a/src/dblib/unittests/t0015.c
++++ b/src/dblib/unittests/t0015.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0015.c,v 1.18 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0015.c,v 1.19 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -55,7 +55,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0015 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -63,11 +63,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-	char cmd[1024];
+-
+-		sprintf(cmd, "insert into #dblib0015 values (%d, 'row %03d')", i, i);
+-		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -75,7 +71,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	dbcmd(dbproc, "select * from #dblib0015 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -119,7 +115,7 @@ main(int argc, char **argv)
+ 	dbcancel(dbproc);
+ 
+ 	fprintf(stdout, "select 2\n");
+-	dbcmd(dbproc, "select * from #dblib0015 where i > 25 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -179,7 +175,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0015.sql b/src/dblib/unittests/t0015.sql
+new file mode 100644
+index 0000000..6e3f2a0
+--- /dev/null
++++ b/src/dblib/unittests/t0015.sql
+@@ -0,0 +1,106 @@
++create table #dblib0015 (i int not null, s char(10) not null)
++go
++insert into #dblib0015 values (0, 'row 000')
++go
++insert into #dblib0015 values (1, 'row 001')
++go
++insert into #dblib0015 values (2, 'row 002')
++go
++insert into #dblib0015 values (3, 'row 003')
++go
++insert into #dblib0015 values (4, 'row 004')
++go
++insert into #dblib0015 values (5, 'row 005')
++go
++insert into #dblib0015 values (6, 'row 006')
++go
++insert into #dblib0015 values (7, 'row 007')
++go
++insert into #dblib0015 values (8, 'row 008')
++go
++insert into #dblib0015 values (9, 'row 009')
++go
++insert into #dblib0015 values (10, 'row 010')
++go
++insert into #dblib0015 values (11, 'row 011')
++go
++insert into #dblib0015 values (12, 'row 012')
++go
++insert into #dblib0015 values (13, 'row 013')
++go
++insert into #dblib0015 values (14, 'row 014')
++go
++insert into #dblib0015 values (15, 'row 015')
++go
++insert into #dblib0015 values (16, 'row 016')
++go
++insert into #dblib0015 values (17, 'row 017')
++go
++insert into #dblib0015 values (18, 'row 018')
++go
++insert into #dblib0015 values (19, 'row 019')
++go
++insert into #dblib0015 values (20, 'row 020')
++go
++insert into #dblib0015 values (21, 'row 021')
++go
++insert into #dblib0015 values (22, 'row 022')
++go
++insert into #dblib0015 values (23, 'row 023')
++go
++insert into #dblib0015 values (24, 'row 024')
++go
++insert into #dblib0015 values (25, 'row 025')
++go
++insert into #dblib0015 values (26, 'row 026')
++go
++insert into #dblib0015 values (27, 'row 027')
++go
++insert into #dblib0015 values (28, 'row 028')
++go
++insert into #dblib0015 values (29, 'row 029')
++go
++insert into #dblib0015 values (30, 'row 030')
++go
++insert into #dblib0015 values (31, 'row 031')
++go
++insert into #dblib0015 values (32, 'row 032')
++go
++insert into #dblib0015 values (33, 'row 033')
++go
++insert into #dblib0015 values (34, 'row 034')
++go
++insert into #dblib0015 values (35, 'row 035')
++go
++insert into #dblib0015 values (36, 'row 036')
++go
++insert into #dblib0015 values (37, 'row 037')
++go
++insert into #dblib0015 values (38, 'row 038')
++go
++insert into #dblib0015 values (39, 'row 039')
++go
++insert into #dblib0015 values (40, 'row 040')
++go
++insert into #dblib0015 values (41, 'row 041')
++go
++insert into #dblib0015 values (42, 'row 042')
++go
++insert into #dblib0015 values (43, 'row 043')
++go
++insert into #dblib0015 values (44, 'row 044')
++go
++insert into #dblib0015 values (45, 'row 045')
++go
++insert into #dblib0015 values (46, 'row 046')
++go
++insert into #dblib0015 values (47, 'row 047')
++go
++insert into #dblib0015 values (48, 'row 048')
++go
++insert into #dblib0015 values (49, 'row 049')
++go
++select * from #dblib0015 order by i
++go
++select * from #dblib0015 where i > 25 order by i
++go
+diff --git a/src/dblib/unittests/t0016.c b/src/dblib/unittests/t0016.c
+index 5c966bd..8847562 100644
+--- a/src/dblib/unittests/t0016.c
++++ b/src/dblib/unittests/t0016.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <sys/stat.h>
+ 
+-static char software_version[] = "$Id: t0016.c,v 1.27 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0016.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -82,9 +82,7 @@ main(int argc, char *argv[])
+ 	printf("After logon\n");
+ 
+ 	printf("Creating table '%s'\n", TABLE_NAME);
+-	strcpy(sqlCmd, "create table #dblib0016 (f1 int not null, s1 int null, f2 numeric(10,2) null, ");
+-	strcat(sqlCmd, "f3 varchar(255) not null, f4 datetime null) ");
+-	dbcmd(dbproc, sqlCmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -99,7 +97,7 @@ main(int argc, char *argv[])
+ 
+ 	printf("return from bcp_init = %d\n", ret);
+ 
+-	ret = dbcmd(dbproc, "select * from #dblib0016 where 0=1");
++	ret = sql_cmd(dbproc, INPUT);
+ 	printf("return from dbcmd = %d\n", ret);
+ 
+ 	ret = dbsqlexec(dbproc);
+@@ -141,7 +139,7 @@ main(int argc, char *argv[])
+ 		failure("bcp_int failed\n");
+ 
+ 	printf("select\n");
+-	dbcmd(dbproc, "select * from #dblib0016 where 0=1");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != FAIL) {
+diff --git a/src/dblib/unittests/t0016.sql b/src/dblib/unittests/t0016.sql
+new file mode 100644
+index 0000000..279987d
+--- /dev/null
++++ b/src/dblib/unittests/t0016.sql
+@@ -0,0 +1,6 @@
++create table #dblib0016 (f1 int not null, s1 int null, f2 numeric(10,2) null, f3 varchar(255) not null, f4 datetime null) 
++go
++select * from #dblib0016 where 0=1
++go
++select * from #dblib0016 where 0=1
++go
+diff --git a/src/dblib/unittests/t0017.c b/src/dblib/unittests/t0017.c
+index d7cb459..4b12456 100644
+--- a/src/dblib/unittests/t0017.c
++++ b/src/dblib/unittests/t0017.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0017.c,v 1.27 2006/08/25 09:04:18 freddy77 Exp $";
++static char software_version[] = "$Id: t0017.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -68,14 +68,14 @@ main(int argc, char *argv[])
+ 	printf("done\n");
+ 
+ 	printf("Creating table ... ");
+-	dbcmd(dbproc, "create table #dblib0017 (c1 int null, c2 text)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 	printf("done\n");
+ 
+-	dbcmd(dbproc, "insert into #dblib0017(c1,c2) values(1144201745,'prova di testo questo testo dovrebbe andare a finire in un campo text')");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -89,7 +89,7 @@ main(int argc, char *argv[])
+ 	printf("done\n");
+ 
+ 	printf("Issuing SELECT ... ");
+-	dbcmd(dbproc, "select * from #dblib0017 where 0=1");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	printf("done\nFetching metadata ... ");
+ 	if (dbresults(dbproc) != FAIL) {
+@@ -132,7 +132,7 @@ main(int argc, char *argv[])
+ 	printf("%d rows copied\n", rows_copied);
+ 
+ 	/* delete rows */
+-	dbcmd(dbproc, "delete from #dblib0017");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -148,7 +148,7 @@ main(int argc, char *argv[])
+ 	printf("done\n");
+ 
+ 	printf("Issuing SELECT ... ");
+-	dbcmd(dbproc, "select * from #dblib0017 where 0=1");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	printf("done\nFetching metadata ... ");
+ 	if (dbresults(dbproc) != FAIL) {
+@@ -194,7 +194,7 @@ main(int argc, char *argv[])
+ 
+ 	/* test we inserted correctly row */
+ 	if (!failed) {
+-		dbcmd(dbproc, "SET NOCOUNT ON DECLARE @n INT SELECT @n = COUNT(*) FROM #dblib0017 WHERE c1=1144201745 AND c2 LIKE 'prova di testo questo testo dovrebbe andare a finire in un campo text' IF @n <> 1 SELECT 0");
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			while ((ret=dbnextrow(dbproc)) != NO_MORE_ROWS) {
+diff --git a/src/dblib/unittests/t0017.sql b/src/dblib/unittests/t0017.sql
+new file mode 100644
+index 0000000..7a75f53
+--- /dev/null
++++ b/src/dblib/unittests/t0017.sql
+@@ -0,0 +1,12 @@
++create table #dblib0017 (c1 int null, c2 text)
++go
++insert into #dblib0017(c1,c2) values(1144201745,'prova di testo questo testo dovrebbe andare a finire in un campo text')
++go
++select * from #dblib0017 where 0=1
++go
++delete from #dblib0017
++go
++select * from #dblib0017 where 0=1
++go
++SET NOCOUNT ON DECLARE @n INT SELECT @n = COUNT(*) FROM #dblib0017 WHERE c1=1144201745 AND c2 LIKE 'prova di testo questo testo dovrebbe andare a finire in un campo text' IF @n <> 1 SELECT 0
++go
+diff --git a/src/dblib/unittests/t0018.c b/src/dblib/unittests/t0018.c
+index 8b5bd82..6f5febc 100644
+--- a/src/dblib/unittests/t0018.c
++++ b/src/dblib/unittests/t0018.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0018.c,v 1.19 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0018.c,v 1.20 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -55,7 +55,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0018 (i int not null, s char(10) not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -63,11 +63,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-	char cmd[1024];
+-
+-		sprintf(cmd, "insert into #dblib0018 values (%d, 'row %03d')", i, i);
+-		fprintf(stdout, "%s\n", cmd);
+-		dbcmd(dbproc, cmd);
++		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -80,7 +76,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	dbcmd(dbproc, "select * into #tmp0 from #dblib0018\nselect * from #tmp0 order by i");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -170,7 +166,7 @@ main(int argc, char **argv)
+ 		exit(1);
+ 	}
+ 
+-	dbcmd(dbproc, "update #dblib0018 set s = 'row 000'");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+@@ -188,7 +184,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0018.sql b/src/dblib/unittests/t0018.sql
+new file mode 100644
+index 0000000..3de28a1
+--- /dev/null
++++ b/src/dblib/unittests/t0018.sql
+@@ -0,0 +1,107 @@
++create table #dblib0018 (i int not null, s char(10) not null)
++go
++insert into #dblib0018 values (0, 'row 000')
++go
++insert into #dblib0018 values (1, 'row 001')
++go
++insert into #dblib0018 values (2, 'row 002')
++go
++insert into #dblib0018 values (3, 'row 003')
++go
++insert into #dblib0018 values (4, 'row 004')
++go
++insert into #dblib0018 values (5, 'row 005')
++go
++insert into #dblib0018 values (6, 'row 006')
++go
++insert into #dblib0018 values (7, 'row 007')
++go
++insert into #dblib0018 values (8, 'row 008')
++go
++insert into #dblib0018 values (9, 'row 009')
++go
++insert into #dblib0018 values (10, 'row 010')
++go
++insert into #dblib0018 values (11, 'row 011')
++go
++insert into #dblib0018 values (12, 'row 012')
++go
++insert into #dblib0018 values (13, 'row 013')
++go
++insert into #dblib0018 values (14, 'row 014')
++go
++insert into #dblib0018 values (15, 'row 015')
++go
++insert into #dblib0018 values (16, 'row 016')
++go
++insert into #dblib0018 values (17, 'row 017')
++go
++insert into #dblib0018 values (18, 'row 018')
++go
++insert into #dblib0018 values (19, 'row 019')
++go
++insert into #dblib0018 values (20, 'row 020')
++go
++insert into #dblib0018 values (21, 'row 021')
++go
++insert into #dblib0018 values (22, 'row 022')
++go
++insert into #dblib0018 values (23, 'row 023')
++go
++insert into #dblib0018 values (24, 'row 024')
++go
++insert into #dblib0018 values (25, 'row 025')
++go
++insert into #dblib0018 values (26, 'row 026')
++go
++insert into #dblib0018 values (27, 'row 027')
++go
++insert into #dblib0018 values (28, 'row 028')
++go
++insert into #dblib0018 values (29, 'row 029')
++go
++insert into #dblib0018 values (30, 'row 030')
++go
++insert into #dblib0018 values (31, 'row 031')
++go
++insert into #dblib0018 values (32, 'row 032')
++go
++insert into #dblib0018 values (33, 'row 033')
++go
++insert into #dblib0018 values (34, 'row 034')
++go
++insert into #dblib0018 values (35, 'row 035')
++go
++insert into #dblib0018 values (36, 'row 036')
++go
++insert into #dblib0018 values (37, 'row 037')
++go
++insert into #dblib0018 values (38, 'row 038')
++go
++insert into #dblib0018 values (39, 'row 039')
++go
++insert into #dblib0018 values (40, 'row 040')
++go
++insert into #dblib0018 values (41, 'row 041')
++go
++insert into #dblib0018 values (42, 'row 042')
++go
++insert into #dblib0018 values (43, 'row 043')
++go
++insert into #dblib0018 values (44, 'row 044')
++go
++insert into #dblib0018 values (45, 'row 045')
++go
++insert into #dblib0018 values (46, 'row 046')
++go
++insert into #dblib0018 values (47, 'row 047')
++go
++insert into #dblib0018 values (48, 'row 048')
++go
++insert into #dblib0018 values (49, 'row 049')
++go
++select * into #tmp0 from #dblib0018
++select * from #tmp0 order by i
++go
++update #dblib0018 set s = 'row 000'
++go
+diff --git a/src/dblib/unittests/t0020.c b/src/dblib/unittests/t0020.c
+index aa8b4b9..90e0ec0 100644
+--- a/src/dblib/unittests/t0020.c
++++ b/src/dblib/unittests/t0020.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0020.c,v 1.16 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0020.c,v 1.17 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -66,7 +66,7 @@ main(int argc, char **argv)
+ 	dbloginfree(login);
+ 	add_bread_crumb();
+ 
+-	dbcmd(dbproc, "select dsjfkl dsjf");
++	sql_cmd(dbproc, INPUT);
+ 	fprintf(stderr, "The following invalid column error is normal.\n");
+ 
+ 	expected_error = 207;
+@@ -79,7 +79,7 @@ main(int argc, char **argv)
+ 		exit(1);
+ 	}
+ 
+-	dbcmd(dbproc, "select db_name()");
++	sql_cmd(dbproc, INPUT);
+ 	ret = dbsqlexec(dbproc);
+ 	if (ret != SUCCEED) {
+ 		failed = 1;
+@@ -95,7 +95,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0020.sql b/src/dblib/unittests/t0020.sql
+new file mode 100644
+index 0000000..927e0ac
+--- /dev/null
++++ b/src/dblib/unittests/t0020.sql
+@@ -0,0 +1,5 @@
++/* request an invalid column from a non-existent table */
++select dsjfkl dsjf
++go
++select db_name()
++go
+diff --git a/src/dblib/unittests/t0021.c b/src/dblib/unittests/t0021.c
+index 2d0c8d6..2c6bac9 100644
+--- a/src/dblib/unittests/t0021.c
++++ b/src/dblib/unittests/t0021.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0021.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0021.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -59,6 +59,6 @@ main(int argc, char **argv)
+ 
+ 	dbexit();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0022.c b/src/dblib/unittests/t0022.c
+index 09eaf80..7a258b7 100644
+--- a/src/dblib/unittests/t0022.c
++++ b/src/dblib/unittests/t0022.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0022.c,v 1.25 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0022.c,v 1.26 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -56,7 +56,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping proc\n");
+ 	add_bread_crumb();
+-	dbcmd(dbproc, "if object_id('t0022') is not null drop proc t0022");
++	sql_cmd(dbproc, INPUT);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -72,7 +72,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating proc\n");
+-	dbcmd(dbproc, "create proc t0022 (@b int out) as\nbegin\n select @b = 42\n return 66\nend\n");
++	sql_cmd(dbproc, INPUT);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		fprintf(stdout, "Failed to create proc t0022.\n");
+@@ -88,7 +88,7 @@ main(int argc, char **argv)
+ 
+ 	sprintf(cmd, "declare @b int\nexec t0022 @b = @b output\n");
+ 	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -157,7 +157,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping proc\n");
+ 	add_bread_crumb();
+-	dbcmd(dbproc, "drop proc t0022");
++	sql_cmd(dbproc, INPUT);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -170,7 +170,7 @@ main(int argc, char **argv)
+ 	 */
+ 	
+ 	fprintf(stdout, "Dropping proc t0022a\n");
+-	dbcmd(dbproc, "if object_id('t0022a') is not null drop proc t0022a");
++	sql_cmd(dbproc, INPUT);
+ 
+ 	dbsqlexec(dbproc);
+ 
+@@ -185,7 +185,7 @@ main(int argc, char **argv)
+ 	assert(erc == NO_MORE_RESULTS);
+ 
+ 	fprintf(stdout, "creating proc t0022a\n");
+-	dbcmd(dbproc, "create proc t0022a (@b int) as\nreturn @b\n");
++	sql_cmd(dbproc, INPUT);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		fprintf(stdout, "Failed to create proc t0022a.\n");
+ 		exit(1);
+@@ -198,9 +198,7 @@ main(int argc, char **argv)
+ 		assert(erc == NO_MORE_ROWS);
+ 	}
+ 
+-	sprintf(cmd, "exec t0022a 17 exec t0022a 1024\n");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 
+ 	for (i=1; (erc = dbresults(dbproc)) != NO_MORE_RESULTS; i++) {
+@@ -234,7 +232,7 @@ main(int argc, char **argv)
+ 	assert(erc == NO_MORE_RESULTS);
+ 	
+ 	fprintf(stdout, "Dropping proc t0022a\n");
+-	dbcmd(dbproc, "drop proc t0022a");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -247,7 +245,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0022.sql b/src/dblib/unittests/t0022.sql
+new file mode 100644
+index 0000000..79c605a
+--- /dev/null
++++ b/src/dblib/unittests/t0022.sql
+@@ -0,0 +1,23 @@
++if object_id('t0022') is not null drop proc t0022
++go
++create proc t0022 (@b int out) as
++begin
++ select @b = 42
++ return 66
++end
++go
++declare @b int
++exec t0022 @b = @b output
++go
++drop proc t0022
++go
++if object_id('t0022a') is not null drop proc t0022a
++go
++create proc t0022a (@b int) as
++return @b
++go
++exec t0022a 17 
++exec t0022a 1024
++go
++drop proc t0022a
++go
+diff --git a/src/dblib/unittests/t0023.c b/src/dblib/unittests/t0023.c
+index 9d57529..515d880 100644
+--- a/src/dblib/unittests/t0023.c
++++ b/src/dblib/unittests/t0023.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0023.c,v 1.13 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: t0023.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -60,7 +60,7 @@ main(int argc, char *argv[])
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib0023 (col1 int not null,  col2 char(1) not null, col3 datetime not null)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+@@ -68,47 +68,34 @@ main(int argc, char *argv[])
+ 
+ 	fprintf(stdout, "insert\n");
+ 
+-	strcpy(cmd, "insert into #dblib0023 values (1, 'A', 'Jan  1 2002 10:00:00AM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	strcpy(cmd, "insert into #dblib0023 values (2, 'A', 'Jan  2 2002 10:00:00AM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	strcpy(cmd, "insert into #dblib0023 values (3, 'A', 'Jan  3 2002 10:00:00AM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	strcpy(cmd, "insert into #dblib0023 values (8, 'B', 'Jan  4 2002 10:00:00AM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	strcpy(cmd, "insert into #dblib0023 values (9, 'B', 'Jan  5 2002 10:00:00AM')");
+-	fprintf(stdout, "%s\n", cmd);
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	strcpy(cmd, "select col1, col2, col3 from #dblib0023 order by col2 ");
+-	strcat(cmd, "compute sum(col1) by col2 ");
+-	strcat(cmd, "compute max(col3)");
+-	dbcmd(dbproc, cmd);
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -241,7 +228,7 @@ main(int argc, char *argv[])
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return failed ? 1 : 0;
+ }
+diff --git a/src/dblib/unittests/t0023.sql b/src/dblib/unittests/t0023.sql
+new file mode 100644
+index 0000000..e615da1
+--- /dev/null
++++ b/src/dblib/unittests/t0023.sql
+@@ -0,0 +1,14 @@
++create table #dblib0023 (col1 int not null,  col2 char(1) not null, col3 datetime not null)
++go
++insert into #dblib0023 values (1, 'A', 'Jan  1 2002 10:00:00AM')
++go
++insert into #dblib0023 values (2, 'A', 'Jan  2 2002 10:00:00AM')
++go
++insert into #dblib0023 values (3, 'A', 'Jan  3 2002 10:00:00AM')
++go
++insert into #dblib0023 values (8, 'B', 'Jan  4 2002 10:00:00AM')
++go
++insert into #dblib0023 values (9, 'B', 'Jan  5 2002 10:00:00AM')
++go
++select col1, col2, col3 from #dblib0023 order by col2 compute sum(col1) by col2 compute max(col3)
++go
+diff --git a/src/dblib/unittests/text_buffer.c b/src/dblib/unittests/text_buffer.c
+index 2af70a9..f0e2d20 100644
+--- a/src/dblib/unittests/text_buffer.c
++++ b/src/dblib/unittests/text_buffer.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: text_buffer.c,v 1.4 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: text_buffer.c,v 1.5 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -59,19 +59,19 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	dbcmd(dbproc, "create table #dblib (i int not null, s text)");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "insert\n");
+-	dbcmd(dbproc, "insert into #dblib values (1, 'ABCDEF')");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+-	dbcmd(dbproc, "insert into #dblib values (2, 'abc')");
++	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -147,7 +147,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	printf("dblib passed for %s\n", __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (0 ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 	return 0;
+ }
+diff --git a/src/dblib/unittests/text_buffer.sql b/src/dblib/unittests/text_buffer.sql
+new file mode 100644
+index 0000000..7aff639
+--- /dev/null
++++ b/src/dblib/unittests/text_buffer.sql
+@@ -0,0 +1,8 @@
++create table #dblib (i int not null, s text)
++go
++insert into #dblib values (1, 'ABCDEF')
++go
++insert into #dblib values (2, 'abc')
++go
++select * from #dblib order by i
++go
+diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c
+index ea897ee..2431d0c 100644
+--- a/src/dblib/unittests/timeout.c
++++ b/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.5 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.6 2009/02/01 22:29:39 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+@@ -159,7 +159,7 @@ main(int argc, char **argv)
+ 	}
+ 	printf ("issuing a query that will take 30 seconds\n");
+ 
+-	if (FAIL == dbcmd(dbproc, "select getdate() as 'begintime' waitfor delay '00:00:30' select getdate() as 'endtime' ")) {
++	if (FAIL == sql_cmd(dbproc, INPUT)) {
+ 		fprintf(stderr, "Failed: dbcmd\n");
+ 		exit(1);
+ 	}
+@@ -237,7 +237,7 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "dblib %s on %s\n", (failed ? "failed!" : "okay"), __FILE__);
++	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	free_bread_crumb();
+ 
+ 	return failed ? 1 : 0;
+diff --git a/src/dblib/unittests/timeout.sql b/src/dblib/unittests/timeout.sql
+new file mode 100644
+index 0000000..2f40559
+--- /dev/null
++++ b/src/dblib/unittests/timeout.sql
+@@ -0,0 +1,2 @@
++select getdate() as 'begintime' waitfor delay '00:00:30' select getdate() as 'endtime' 
++go
+
+commit f61685f8ad47f7b3579c889548e061868343511f
+Author: jklowden <jklowden>
+Date:   Sun Feb 1 23:40:56 2009 +0000
+
+    first stab at adding SQL files
+
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index 2eb5e54..e83959e 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.44 2008/11/12 00:47:40 jklowden Exp $
++# $Id: Makefile.am,v 1.45 2009/02/01 23:40:56 jklowden Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -13,6 +13,11 @@ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			setnull$(EXEEXT)
+ check_PROGRAMS	=	$(TESTS)
+ 
++EXTRA_DIST = 	bcp.sql dbmorecmds.sql done_handling.sql rpc.sql \
++		t0001.sql t0002.sql t0003.sql t0004.sql t0005.sql t0006.sql t0007.sql t0009.sql \
++		t0011.sql t0012.sql t0013.sql t0014.sql t0015.sql t0016.sql t0017.sql t0018.sql \
++		t0020.sql t0022.sql t0023.sql text_buffer.sql timeout.sql
++
+ t0001_SOURCES	=	t0001.c common.c common.h
+ t0002_SOURCES	=	t0002.c common.c common.h
+ t0003_SOURCES	=	t0003.c common.c common.h
+
+commit e7d47686d2f4cef7cdfc627a03102895bd446262
+Author: jklowden <jklowden>
+Date:   Tue Feb 3 05:00:48 2009 +0000
+
+    still looking for a way to use .sql input files
+
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index e83959e..7591549 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.45 2009/02/01 23:40:56 jklowden Exp $
++# $Id: Makefile.am,v 1.46 2009/02/03 05:00:48 jklowden Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -13,12 +13,14 @@ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			setnull$(EXEEXT)
+ check_PROGRAMS	=	$(TESTS)
+ 
+-EXTRA_DIST = 	bcp.sql dbmorecmds.sql done_handling.sql rpc.sql \
++SQL_DIST = 	bcp.sql dbmorecmds.sql done_handling.sql rpc.sql \
+ 		t0001.sql t0002.sql t0003.sql t0004.sql t0005.sql t0006.sql t0007.sql t0009.sql \
+ 		t0011.sql t0012.sql t0013.sql t0014.sql t0015.sql t0016.sql t0017.sql t0018.sql \
+ 		t0020.sql t0022.sql t0023.sql text_buffer.sql timeout.sql
+ 
+-t0001_SOURCES	=	t0001.c common.c common.h
++nodist_bin_SCRIPTS	= $(SQL_DIST)
++
++t0001_SOURCES	=	t0001.c common.c common.h t0001.sql
+ t0002_SOURCES	=	t0002.c common.c common.h
+ t0003_SOURCES	=	t0003.c common.c common.h
+ t0004_SOURCES	=	t0004.c common.c common.h
+@@ -59,7 +61,7 @@ else
+ AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
+ endif
+ LIBS		=	../libsybdb.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+-EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32)
++EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32) 
+ CLEANFILES	=	tdsdump.out t0013.out t0014.out t0016.out \
+ 				t0016.err t0017.err t0017.out
+ 
+@@ -76,3 +78,5 @@ clean-local:
+ EXTRA_DIST_WIN32 = vc6 dblib.dsw dblib.mak
+ endif
+ 
++$(SQL_DIST): 
++	ln -s $(srcdir)/$@ .
+
+commit cf8a3b0d329c1ecdc31160c5290ed35df376f582
+Author: freddy77 <freddy77>
+Date:   Tue Feb 3 09:10:58 2009 +0000
+
+    fix memory error
+
+diff --git a/ChangeLog b/ChangeLog
+index 1e7ee47..5ddb2f0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Feb  3 10:10:24 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0014.c: fix memory error
++
+ Sun Feb  1 17:15:49 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/unittests/common.h src/dblib/unittests/common.c
+ 	* src/dblib/unittests/bcp.c src/dblib/unittests/dbmorecmds.c
+@@ -1268,4 +1271,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2718 2009/02/01 22:29:38 jklowden Exp $
++$Id: ChangeLog,v 1.2719 2009/02/03 09:10:58 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c
+index 9666086..68a65a7 100644
+--- a/src/dblib/unittests/t0014.c
++++ b/src/dblib/unittests/t0014.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0014.c,v 1.29 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0014.c,v 1.30 2009/02/03 09:10:58 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -101,9 +101,6 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-	char cmd[1024];
+-
+-		fprintf(stdout, "%s\n", cmd);
+ 		sql_cmd(dbproc, INPUT);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+
+commit 6833b69efd7873d5df4bc0b01a0c0b7750bf9bdf
+Author: freddy77 <freddy77>
+Date:   Thu Feb 5 08:49:45 2009 +0000
+
+    remove warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index 5ddb2f0..7e223ea 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Thu Feb  5 09:49:08 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/done_handling.c src/dblib/unittests/rpc.c:
++	* src/dblib/unittests/t0011.c src/dblib/unittests/t0016.c:
++	* src/dblib/unittests/t0023.c:
++	- remove warnings
++
+ Tue Feb  3 10:10:24 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0014.c: fix memory error
+ 
+@@ -1271,4 +1277,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2719 2009/02/03 09:10:58 freddy77 Exp $
++$Id: ChangeLog,v 1.2720 2009/02/05 08:49:45 freddy77 Exp $
+diff --git a/src/dblib/unittests/done_handling.c b/src/dblib/unittests/done_handling.c
+index c2e5cc0..56d95d3 100644
+--- a/src/dblib/unittests/done_handling.c
++++ b/src/dblib/unittests/done_handling.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: done_handling.c,v 1.8 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: done_handling.c,v 1.9 2009/02/05 08:49:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -60,16 +60,14 @@ prretcode(int retcode)
+ 	return unknown;
+ }
+ 
+-static RETCODE
++static void
+ query(const char comment[])
+ {
+-	RETCODE erc;
+-	
+ 	if (comment)
+ 		printf("%s\n", comment);
+ 	sql_cmd(dbproc, INPUT);
+ 	dbsqlexec(dbproc);
+-	while ((erc = dbresults(dbproc)) == SUCCEED) {
++	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ }
+@@ -149,7 +147,6 @@ int
+ main(int argc, char *argv[])
+ {
+ 	const static int invalid_column_name = 207;
+-	RETCODE erc;
+ 	LOGINREC *login;	/* Our login information. */
+ 	int i;
+ 
+@@ -184,9 +181,8 @@ main(int argc, char *argv[])
+ 	if (strlen(DATABASE))
+ 		dbuse(dbproc, DATABASE);
+ 
+-	for (i=0; i < 6; i++) {
+-		erc = query(NULL);
+-	}
++	for (i=0; i < 6; i++)
++		query(NULL);
+ #if 0	
+ 	check_state("setup done ", prretcode, erc);
+ 	
+@@ -202,7 +198,7 @@ main(int argc, char *argv[])
+ 	do_test("normal row with rowcount off");
+ 	query("turn rowcount back on");
+ 	do_test("normal row without rows");
+-	dbsetuserdata(dbproc, &invalid_column_name);
++	dbsetuserdata(dbproc, (BYTE*) &invalid_column_name);
+ 	do_test("error query");
+ 	do_test("stored procedure call with output parameters");
+ 
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index 5c54197..2dfbf88 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,10 +5,9 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.36 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.37 2009/02/05 08:49:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static char cmd[4096];
+ static int init_proc(DBPROCESS * dbproc, const char *name);
+ int ignore_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ int ignore_msg_handler(DBPROCESS * dbproc, DBINT msgno, int state, int severity, char *text, char *server, char *proc, int line);
+diff --git a/src/dblib/unittests/t0011.c b/src/dblib/unittests/t0011.c
+index 7e2f3b6..cbd8d33 100644
+--- a/src/dblib/unittests/t0011.c
++++ b/src/dblib/unittests/t0011.c
+@@ -6,7 +6,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0011.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0011.c,v 1.15 2009/02/05 08:49:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -21,7 +21,6 @@ main(int argc, char **argv)
+ {
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+-	char cmd[2048];
+ 
+ 	read_login_info(argc, argv);
+ 	fprintf(stdout, "Starting %s\n", argv[0]);
+diff --git a/src/dblib/unittests/t0016.c b/src/dblib/unittests/t0016.c
+index 8847562..f3803ac 100644
+--- a/src/dblib/unittests/t0016.c
++++ b/src/dblib/unittests/t0016.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <sys/stat.h>
+ 
+-static char software_version[] = "$Id: t0016.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0016.c,v 1.29 2009/02/05 08:49:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -32,7 +32,6 @@ main(int argc, char *argv[])
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+ 	int i;
+-	char sqlCmd[256];
+ 	RETCODE ret;
+ 	const char *out_file = "t0016.out";
+ 	const char *in_file = FREETDS_SRCDIR "/" INFILE_NAME;
+diff --git a/src/dblib/unittests/t0023.c b/src/dblib/unittests/t0023.c
+index 515d880..3ec2afc 100644
+--- a/src/dblib/unittests/t0023.c
++++ b/src/dblib/unittests/t0023.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0023.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0023.c,v 1.15 2009/02/05 08:49:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -18,7 +18,6 @@ main(int argc, char *argv[])
+ {
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+-	char cmd[1024];
+ 	int i;
+ 	DBINT rowint;
+ 	DBCHAR rowchar[2];
+
+commit 3b57fc9ae5a9c7dd78c6b1b758ec5b582c689be6
+Author: freddy77 <freddy77>
+Date:   Fri Feb 6 10:11:08 2009 +0000
+
+    remove file leak in unittests
+
+diff --git a/ChangeLog b/ChangeLog
+index 7e223ea..ad95872 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb  6 11:10:35 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: remove file leak in unittests
++
+ Thu Feb  5 09:49:08 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/done_handling.c src/dblib/unittests/rpc.c:
+ 	* src/dblib/unittests/t0011.c src/dblib/unittests/t0016.c:
+@@ -1277,4 +1280,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2720 2009/02/05 08:49:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2721 2009/02/06 10:11:08 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index a087112..58b6c1b 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -18,7 +18,7 @@
+ 
+ #include <err.h>
+ 
+-static char software_version[] = "$Id: common.c,v 1.26 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: common.c,v 1.27 2009/02/06 10:11:09 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -90,6 +90,16 @@ tds_dirname(char* path)
+ 
+ #endif
+ 
++char free_file_registered = 0;
++static void
++free_file(void)
++{
++	if (INPUT) {
++		fclose(INPUT);
++		INPUT = NULL;
++	}
++}
++
+ int
+ read_login_info(int argc, char **argv)
+ {
+@@ -215,6 +225,10 @@ read_login_info(int argc, char **argv)
+ 		fflush(stdout);
+ 		warnx("could not open SQL input file \"%s\"\n", sql_file);
+ 	}
++
++	if (!free_file_registered)
++		atexit(free_file);
++	free_file_registered = 1;
+ 	
+ 	printf("SQL text will be read from %s\n", sql_file);
+ 
+
+commit a9e3584c0b2cc9b8a32c666a1dc71c7582426159
+Author: freddy77 <freddy77>
+Date:   Fri Feb 6 10:59:28 2009 +0000
+
+    fix rpc test
+
+diff --git a/ChangeLog b/ChangeLog
+index ad95872..dabad20 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb  6 11:59:03 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/rpc.sql: fix rpc test
++
+ Fri Feb  6 11:10:35 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c: remove file leak in unittests
+ 
+@@ -1280,4 +1283,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2721 2009/02/06 10:11:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2722 2009/02/06 10:59:28 freddy77 Exp $
+diff --git a/src/dblib/unittests/rpc.sql b/src/dblib/unittests/rpc.sql
+index 7b35e76..7e73cc0 100644
+--- a/src/dblib/unittests/rpc.sql
++++ b/src/dblib/unittests/rpc.sql
+@@ -18,7 +18,7 @@ return 42
+ END 
+ 
+ go
+-DROP PROCEDURE t0022
++IF OBJECT_ID('t0022') IS NOT NULL DROP PROC t0022
+ go
+ CREATE PROCEDURE t0022 
+   @null_input varchar(30) OUTPUT 
+@@ -40,5 +40,5 @@ return 42
+ END 
+ 
+ go
+-DROP PROCEDURE t0022
++IF OBJECT_ID('t0022') IS NOT NULL DROP PROC t0022
+ go
+
+commit e675b6914c21eeb0852f77c0000d0f2aaa702401
+Author: freddy77 <freddy77>
+Date:   Fri Feb 6 11:12:01 2009 +0000
+
+    fix convert test
+
+diff --git a/ChangeLog b/ChangeLog
+index dabad20..e0e19c6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb  6 12:11:27 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/unittests/convert.c: fix convert test
++
+ Fri Feb  6 11:59:03 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/rpc.sql: fix rpc test
+ 
+@@ -1283,4 +1286,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2722 2009/02/06 10:59:28 freddy77 Exp $
++$Id: ChangeLog,v 1.2723 2009/02/06 11:12:01 freddy77 Exp $
+diff --git a/src/tds/unittests/convert.c b/src/tds/unittests/convert.c
+index 70d28c3..2cfb472 100644
+--- a/src/tds/unittests/convert.c
++++ b/src/tds/unittests/convert.c
+@@ -32,7 +32,7 @@
+ #include <sys/time.h>
+ #endif
+ 
+-static char software_version[] = "$Id: convert.c,v 1.24 2008/12/10 14:56:27 freddy77 Exp $";
++static char software_version[] = "$Id: convert.c,v 1.25 2009/02/06 11:12:01 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int g_result = 0;
+@@ -92,6 +92,8 @@ main(int argc, char **argv)
+ 	TDS_REAL tds_real;
+ 	TDS_FLOAT tds_float;
+ 
++	TDS_UNIQUE tds_unique;
++
+ 	if (argc > 1) {
+ 		iterations = atoi(argv[1]);
+ 		printf("Computing %d iterations\n", iterations);
+@@ -153,6 +155,9 @@ main(int argc, char **argv)
+ 				cr.n.precision = 8;
+ 				cr.n.scale = 2;
+ 				break;
++			case SYBUNIQUE:
++				src = "A8C60F70-5BD4-3E02-B769-7CCCCA585DCC";
++				break;
+ 			case SYBBIT:
+ 			default:
+ 				src = "1";
+@@ -201,6 +206,7 @@ main(int argc, char **argv)
+ 			srclen = sizeof(money4);
+ 			break;
+ 		case SYBBIT:
++		case SYBBITN:
+ 			src = (char *) &bit_input;
+ 			srclen = sizeof(bit_input);
+ 			break;
+@@ -212,6 +218,10 @@ main(int argc, char **argv)
+ 			src = (char *) &datetime4;
+ 			srclen = sizeof(datetime4);
+ 			break;
++		case SYBUNIQUE:
++			src = (char *) &tds_unique;
++			srclen = sizeof(tds_unique);
++			break;
+ 		/*****  not defined yet
+ 			case SYBBOUNDARY:
+ 			case SYBSENSITIVITY:
+
+commit 3ecbc42b79dfb334efe64baa17380b4e34f0f533
+Author: freddy77 <freddy77>
+Date:   Fri Feb 6 14:26:54 2009 +0000
+
+    fix minor test issues
+
+diff --git a/ChangeLog b/ChangeLog
+index e0e19c6..de609a5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Feb  6 15:25:10 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: remove openjade warning
++	* src/tds/unittests/convert.c: make valgrind happy
++
+ Fri Feb  6 12:11:27 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/unittests/convert.c: fix convert test
+ 
+@@ -1286,4 +1290,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2723 2009/02/06 11:12:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2724 2009/02/06 14:26:54 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 8b6c790..17b9ab1 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -159,7 +159,7 @@ fi
+ 
+ # upload our test results
+ cd logs
+-perl -pe "\$_ = '' if \$_ =~ /^2:bcp.c: In function 'bcp_colfmt'|^2:bcp.c:\\d+: warning: suggest parentheses around && within \\|\\|/" < log.txt | ../misc/online.pl
++perl -pe "\$_ = '' if \$_ =~ /^2:bcp.c: In function 'bcp_colfmt'|^2:bcp.c:\\d+: warning: suggest parentheses around && within \\|\\||^2:.*content model is mixed but does not allow #PCDATA everywhere/" < log.txt | ../misc/online.pl
+ upload "$OUTDIR/test" '*.html'
+ cd ..
+ 
+diff --git a/src/tds/unittests/convert.c b/src/tds/unittests/convert.c
+index 2cfb472..81c103a 100644
+--- a/src/tds/unittests/convert.c
++++ b/src/tds/unittests/convert.c
+@@ -32,7 +32,7 @@
+ #include <sys/time.h>
+ #endif
+ 
+-static char software_version[] = "$Id: convert.c,v 1.25 2009/02/06 11:12:01 freddy77 Exp $";
++static char software_version[] = "$Id: convert.c,v 1.26 2009/02/06 14:26:54 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int g_result = 0;
+@@ -292,6 +292,9 @@ main(int argc, char **argv)
+ 		case SYBINT8:
+ 			tds_int8 = cr.bi;
+ 			break;
++		case SYBUNIQUE:
++			tds_unique = cr.u;
++			break;
+ 		default:
+ 			break;
+ 		}
+
+commit c896828577d907de109f9b99842656c39f704915
+Author: jklowden <jklowden>
+Date:   Sat Feb 7 00:26:22 2009 +0000
+
+    better winsock initialization and dbdatecrack
+
+diff --git a/ChangeLog b/ChangeLog
+index de609a5..bbeb142 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Feb  6 19:22:16 EST 2009	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h include/tds.h src/dblib/dblib.c 
++	* src/tds/convert.c src/tds/mem.c src/tds/net.c
++	- better winsock initialization and dbdatecrack
++
+ Fri Feb  6 15:25:10 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild: remove openjade warning
+ 	* src/tds/unittests/convert.c: make valgrind happy
+@@ -1290,4 +1295,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2724 2009/02/06 14:26:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2725 2009/02/07 00:26:22 jklowden Exp $
+diff --git a/include/sybdb.h b/include/sybdb.h
+index f2b7d04..866a5d5 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.87 2009/01/31 19:13:20 jklowden Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.88 2009/02/07 00:26:22 jklowden Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -370,32 +370,52 @@ typedef struct
+ 
+ typedef struct tds_dblib_dbprocess DBPROCESS;
+ 
+-typedef struct dbdaterec
++/*
++ * Sybase & Microsoft use different names for the dbdaterec members. 
++ * Keep these two structures physically identical in memory.  
++ * dbdatecrack() casts one to the other for ease of implementation. 
++ * N.B. Microsoft documents the members as int, not long.   
++ *
++ * Giving credit where credit is due, we can acknowledge that
++ * Microsoft chose the better names here, hands down.  ("datedmonth"?!)
++ */
++struct tds_microsoft_dbdaterec
++{
++	long year;		/* 1753 - 9999  	   */
++	long quarter;		/* 1 - 4 		   */
++	long month;		/* 1 - 12 		   */
++	long day;		/* 1 - 31 		   */
++	long dayofyear;		/* 1 - 366 		   */
++	long week;            	/* 1 - 54 (for leap years) */
++	long weekday;		/* 1 - 7 (Mon. - Sun.)     */
++	long hour;		/* 0 - 23 		   */
++	long minute;		/* 0 - 59 		   */
++	long second;		/* 0 - 59 		   */
++	long millisecond;	/* 0 - 999 		   */
++	long tzone;		/* 0 - 127  (Sybase only)  */	
++};					
++
++struct tds_sybase_dbdaterec
+ {
++	long dateyear;		/* 1900 and counting	  */ 
++	long quarter;		/* 0 - 3 (Microsoft only) */
++	long datemonth;		/* 0 - 11   	     	  */
++	long datedmonth;	/* 1 - 31   	     	  */
++	long datedyear;		/* 1 - 366  	     	  */
++	long week;            	/* 1 - 54 (Microsoft only) */
++	long datedweek;		/* 0 - 6    	     	  */
++	long datehour; 		/* 0 - 23   	     	  */
++	long dateminute;	/* 0 - 59   	     	  */
++	long datesecond;	/* 0 - 59   	     	  */
++	long datemsecond;	/* 0 - 997  	     	  */
++	long datetzone;		/* 0 - 127  	     	  */
++};
++
+ #ifdef MSDBLIB
+-	DBINT year;
+-	DBINT month;
+-	DBINT day;
+-	DBINT dayofyear;
+-	DBINT weekday;
+-	DBINT hour;
+-	DBINT minute;
+-	DBINT second;
+-	DBINT millisecond;
+-	DBINT tzone;
++typedef struct tds_microsoft_dbdaterec DBDATEREC;
+ #else
+-	DBINT dateyear;
+-	DBINT datemonth;
+-	DBINT datedmonth;
+-	DBINT datedyear;
+-	DBINT datedweek;
+-	DBINT datehour;
+-	DBINT dateminute;
+-	DBINT datesecond;
+-	DBINT datemsecond;
+-	DBINT datetzone;
++typedef struct tds_sybase_dbdaterec DBDATEREC;
+ #endif
+-} DBDATEREC;
+ 
+ typedef int (*EHANDLEFUNC) (DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ 
+diff --git a/include/tds.h b/include/tds.h
+index bf61881..1ae3dea 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.310 2009/01/16 20:27:57 jklowden Exp $ */
++/* $Id: tds.h,v 1.311 2009/02/07 00:26:22 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -173,9 +173,11 @@ typedef struct tdsunique
+ typedef struct tdsdaterec
+ {
+ 	TDS_INT year;	       /**< year */
++	TDS_INT quarter;       /**< quarter (0-3) */
+ 	TDS_INT month;	       /**< month number (0-11) */
+ 	TDS_INT day;	       /**< day of month (1-31) */
+ 	TDS_INT dayofyear;     /**< day of year  (1-366) */
++	TDS_INT week;          /**< 1 - 54 (can be 54 in leap year) */
+ 	TDS_INT weekday;       /**< day of week  (0-6, 0 = sunday) */
+ 	TDS_INT hour;	       /**< 0-23 */
+ 	TDS_INT minute;	       /**< 0-59 */
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index a846159..db40841 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -62,7 +62,6 @@
+  * 	This affects how certain application-addressable 
+  * 	strucures are defined.  
+  */
+-#define SYBDBLIB 1
+ #include <tds.h>
+ #include <tdsthread.h>
+ #include <tdsconvert.h>
+@@ -76,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.340 2009/01/31 19:13:20 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.341 2009/02/07 00:26:22 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1836,7 +1835,6 @@ RETCODE
+ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ {
+ 	BYTE *pval;
+-	size_t len;
+ 	
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsetnull(%p, %d, %d, %p)\n", dbproc, bindtype, bindlen, bindval);
+ 	
+@@ -1856,22 +1854,21 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 	case SMALLDATETIMEBIND:
+ 	case SMALLMONEYBIND:
+ 	case TINYBIND:
+-		len = default_null_representations[bindtype].len;
++		bindlen = (int)default_null_representations[bindtype].len;
+ 		break;
+ 
+ 	case CHARBIND:
+ 	case BINARYBIND:
+ 		CHECK_PARAMETER(bindlen >= 0, SYBEBBL, FAIL);
+-		len = bindlen;
+ 		break;
+ 		
+-	case NTBSTRINGBIND:	len = strlen((char *) bindval);
++	case NTBSTRINGBIND:	bindlen = (int)strlen((char *) bindval);
+ 		break;
+-	case STRINGBIND:	len = strlen((char *) bindval);
++	case STRINGBIND:	bindlen = (int)strlen((char *) bindval);
+ 		break;
+-	case VARYBINBIND:	len = ((TDS_VARBINARY*) bindval)->len;
++	case VARYBINBIND:	bindlen = ((TDS_VARBINARY*) bindval)->len;
+ 		break;
+-	case VARYCHARBIND:	len = ((TDS_VARCHAR*) bindval)->len;
++	case VARYCHARBIND:	bindlen = ((TDS_VARCHAR*) bindval)->len;
+ 		break;
+ 
+ #if 0
+@@ -1883,7 +1880,7 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 		return FAIL;
+ 	}
+ 
+-	if ((pval = malloc(len)) == NULL) {
++	if ((pval = malloc(bindlen)) == NULL) {
+ 		dbperror(dbproc, SYBEMEM, errno);
+ 		return FAIL;
+ 	}
+@@ -1892,12 +1889,12 @@ dbsetnull(DBPROCESS * dbproc, int bindtype, int bindlen, BYTE *bindval)
+ 	if (dbproc->nullreps[bindtype].bindval != default_null_representations[bindtype].bindval)
+ 		free((BYTE*)dbproc->nullreps[bindtype].bindval);
+ 
+-	memcpy(pval, bindval, len);
++	memcpy(pval, bindval, bindlen);
+ 	
+ 	dbproc->nullreps[bindtype].bindval = pval;
+-	dbproc->nullreps[bindtype].len = len;
++	dbproc->nullreps[bindtype].len = bindlen;
+ 
+-	tdsdump_dump_buf(TDS_DBG_NETWORK, "null representation set ", pval,  len);
++	tdsdump_dump_buf(TDS_DBG_NETWORK, "null representation set ", pval,  bindlen);
+ 	return SUCCEED;
+ }
+ 
+@@ -5531,19 +5528,24 @@ dbdatecmp(DBPROCESS * dbproc, DBDATETIME * d1, DBDATETIME * d2)
+  * \sa dbconvert(), dbdata(), dbdatechar(), dbdatename(), dbdatepart().
+  */
+ RETCODE
+-dbdatecrack(DBPROCESS * dbproc, DBDATEREC * di, DBDATETIME * datetime)
++dbdatecrack(DBPROCESS * dbproc, DBDATEREC * output, DBDATETIME * datetime)
+ {
++#if MSDBLIB
++	const int msdblib = 1;
++#else
++	const int msdblib = 0;
++#endif
+ 	TDSDATEREC dr;
++	struct tds_sybase_dbdaterec *di = (struct tds_sybase_dbdaterec*) output;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "dbdatecrack(%p, %p, %p)\n", dbproc, di, datetime);
+-	CHECK_DBPROC();
+-	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+-	CHECK_NULP(di, "dbdatecrack", 2, FAIL);
++	tdsdump_log(TDS_DBG_FUNC, "dbdatecrack(%p, %p, %p)\n", dbproc, output, datetime);
++	CHECK_NULP(output, "dbdatecrack", 2, FAIL);
+ 	CHECK_PARAMETER(datetime, SYBENDTP, FAIL);
+ 
+ 	tds_datecrack(SYBDATETIME, datetime, &dr);
+ 
+ 	di->dateyear = dr.year;
++	di->quarter = dr.quarter;
+ 	di->datemonth = dr.month;
+ 	di->datedmonth = dr.day;
+ 	di->datedyear = dr.dayofyear;
+@@ -5552,7 +5554,9 @@ dbdatecrack(DBPROCESS * dbproc, DBDATEREC * di, DBDATETIME * datetime)
+ 	di->dateminute = dr.minute;
+ 	di->datesecond = dr.second;
+ 	di->datemsecond = dr.millisecond;
+-	if (dbproc->msdblib) {
++	/* Revert to compiled-in default if dbproc can't be used to find the runtime override. */
++	if( dbproc && dbproc->msdblib || msdblib && !dbproc  ) {
++		++di->quarter;
+ 		++di->datemonth;
+ 		++di->datedweek;
+ 	}
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 5810975..32dc709 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.187 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.188 2009/02/07 00:26:22 jklowden Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -2877,6 +2877,42 @@ tds_willconvert(int srctype, int desttype)
+ #endif
+ }
+ 
++#if 0
++select day(d) as day, datepart(dw, d) as weekday, datepart(week, d) as week, d as 'date' from #t order by d
++day         weekday     week        date                                                   
++----------- ----------- ----------- ----------
++          1           5           1 2009-01-01 Thursday
++          2           6           1 2009-01-02 Friday
++          3           7           1 2009-01-03 Saturday
++          4           1           2 2009-01-04 Sunday
++          5           2           2 2009-01-05
++          6           3           2 2009-01-06
++          7           4           2 2009-01-07
++          8           5           2 2009-01-08
++          9           6           2 2009-01-09
++         10           7           2 2009-01-10
++         11           1           3 2009-01-11
++         12           2           3 2009-01-12
++         13           3           3 2009-01-13
++         14           4           3 2009-01-14
++         15           5           3 2009-01-15
++         16           6           3 2009-01-16
++         17           7           3 2009-01-17
++         18           1           4 2009-01-18
++         19           2           4 2009-01-19
++         20           3           4 2009-01-20
++         21           4           4 2009-01-21
++         22           5           4 2009-01-22
++         23           6           4 2009-01-23
++         24           7           4 2009-01-24
++         25           1           5 2009-01-25
++         26           2           5 2009-01-26
++         27           3           5 2009-01-27
++         28           4           5 2009-01-28
++         29           5           5 2009-01-29
++         30           6           5 2009-01-30
++         31           7           5 2009-01-31
++#endif
+ /**
+  * Convert from db date format to a structured date format
+  * @param datetype source date type. SYBDATETIME or SYBDATETIME4
+@@ -2939,8 +2975,10 @@ tds_datecrack(TDS_INT datetype, const void *di, TDSDATEREC * dr)
+ 
+ 	dr->year = years;
+ 	dr->month = months;
++	dr->quarter = months / 3;
+ 	dr->day = days;
+ 	dr->dayofyear = ydays;
++	dr->week = -1;
+ 	dr->weekday = wday;
+ 	dr->hour = hours;
+ 	dr->minute = mins;
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 218ecfd..33d6e99 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.187 2009/01/23 10:42:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.188 2009/02/07 00:26:22 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -616,23 +616,27 @@ tds_free_all_results(TDSSOCKET * tds)
+ /*
+  * Return 1 if winsock is initialized, else 0.
+  */
++const char *tds_prwsaerror( int erc );
+ static int
+ winsock_initialized(void)
+ {
+ #if defined(_WIN32) || defined(_WIN64)
+ 	WSADATA wsa_data;
+ 	int erc;
+-	DWORD how_much = 0;
++	WSAPROTOCOL_INFO protocols[8];
++	DWORD how_much = sizeof(protocols);
+ 	WORD requested_version = MAKEWORD(2, 2);
+-
+-	if (SOCKET_ERROR != WSAEnumProtocols(NULL, NULL, &how_much))
++	 
++	if (SOCKET_ERROR != WSAEnumProtocols(NULL, protocols, &how_much)) 
+ 		return 1;
+ 
+-	if (WSANOTINITIALISED != WSAGetLastError())
++	if (WSANOTINITIALISED != (erc = WSAGetLastError())) {
++		fprintf(stderr, "tds_init_winsock: WSAEnumProtocols failed with %d(%s)\n", erc, tds_prwsaerror(erc) ); 
+ 		return 0;
+-
++	}
++	
+ 	if (SOCKET_ERROR == (erc = WSAStartup(requested_version, &wsa_data))) {
+-		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d(%s)\n", erc, WSAGetLastError() );
++		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d(%s)\n", erc, tds_prwsaerror(erc) ); 
+ 		return 0;
+ 	}
+ #endif
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 7b5a63a..5fd6ebb 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.85 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.86 2009/02/07 00:26:22 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -1130,6 +1130,128 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 	return port;
+ }
+ 
++#if defined(_WIN32)
++const char *
++tds_prwsaerror( int erc ) 
++{
++	switch(erc) {
++	case WSAEINTR: /* 10004 */
++		return "WSAEINTR: Interrupted function call.";
++	case WSAEACCES: /* 10013 */
++		return "WSAEACCES: Permission denied.";
++	case WSAEFAULT: /* 10014 */
++		return "WSAEFAULT: Bad address.";
++	case WSAEINVAL: /* 10022 */
++		return "WSAEINVAL: Invalid argument.";
++	case WSAEMFILE: /* 10024 */
++		return "WSAEMFILE: Too many open files.";
++	case WSAEWOULDBLOCK: /* 10035 */
++		return "WSAEWOULDBLOCK: Resource temporarily unavailable.";
++	case WSAEINPROGRESS: /* 10036 */
++		return "WSAEINPROGRESS: Operation now in progress.";
++	case WSAEALREADY: /* 10037 */
++		return "WSAEALREADY: Operation already in progress.";
++	case WSAENOTSOCK: /* 10038 */
++		return "WSAENOTSOCK: Socket operation on nonsocket.";
++	case WSAEDESTADDRREQ: /* 10039 */
++		return "WSAEDESTADDRREQ: Destination address required.";
++	case WSAEMSGSIZE: /* 10040 */
++		return "WSAEMSGSIZE: Message too long.";
++	case WSAEPROTOTYPE: /* 10041 */
++		return "WSAEPROTOTYPE: Protocol wrong type for socket.";
++	case WSAENOPROTOOPT: /* 10042 */
++		return "WSAENOPROTOOPT: Bad protocol option.";
++	case WSAEPROTONOSUPPORT: /* 10043 */
++		return "WSAEPROTONOSUPPORT: Protocol not supported.";
++	case WSAESOCKTNOSUPPORT: /* 10044 */
++		return "WSAESOCKTNOSUPPORT: Socket type not supported.";
++	case WSAEOPNOTSUPP: /* 10045 */
++		return "WSAEOPNOTSUPP: Operation not supported.";
++	case WSAEPFNOSUPPORT: /* 10046 */
++		return "WSAEPFNOSUPPORT: Protocol family not supported.";
++	case WSAEAFNOSUPPORT: /* 10047 */
++		return "WSAEAFNOSUPPORT: Address family not supported by protocol family.";
++	case WSAEADDRINUSE: /* 10048 */
++		return "WSAEADDRINUSE: Address already in use.";
++	case WSAEADDRNOTAVAIL: /* 10049 */
++		return "WSAEADDRNOTAVAIL: Cannot assign requested address.";
++	case WSAENETDOWN: /* 10050 */
++		return "WSAENETDOWN: Network is down.";
++	case WSAENETUNREACH: /* 10051 */
++		return "WSAENETUNREACH: Network is unreachable.";
++	case WSAENETRESET: /* 10052 */
++		return "WSAENETRESET: Network dropped connection on reset.";
++	case WSAECONNABORTED: /* 10053 */
++		return "WSAECONNABORTED: Software caused connection abort.";
++	case WSAECONNRESET: /* 10054 */
++		return "WSAECONNRESET: Connection reset by peer.";
++	case WSAENOBUFS: /* 10055 */
++		return "WSAENOBUFS: No buffer space available.";
++	case WSAEISCONN: /* 10056 */
++		return "WSAEISCONN: Socket is already connected.";
++	case WSAENOTCONN: /* 10057 */
++		return "WSAENOTCONN: Socket is not connected.";
++	case WSAESHUTDOWN: /* 10058 */
++		return "WSAESHUTDOWN: Cannot send after socket shutdown.";
++	case WSAETIMEDOUT: /* 10060 */
++		return "WSAETIMEDOUT: Connection timed out.";
++	case WSAECONNREFUSED: /* 10061 */
++		return "WSAECONNREFUSED: Connection refused.";
++	case WSAEHOSTDOWN: /* 10064 */
++		return "WSAEHOSTDOWN: Host is down.";
++	case WSAEHOSTUNREACH: /* 10065 */
++		return "WSAEHOSTUNREACH: No route to host.";
++	case WSAEPROCLIM: /* 10067 */
++		return "WSAEPROCLIM: Too many processes.";
++	case WSASYSNOTREADY: /* 10091 */
++		return "WSASYSNOTREADY: Network subsystem is unavailable.";
++	case WSAVERNOTSUPPORTED: /* 10092 */
++		return "WSAVERNOTSUPPORTED: Winsock.dll version out of range.";
++	case WSANOTINITIALISED: /* 10093 */
++		return "WSANOTINITIALISED: Successful WSAStartup not yet performed.";
++	case WSAEDISCON: /* 10101 */
++		return "WSAEDISCON: Graceful shutdown in progress.";
++	case WSATYPE_NOT_FOUND: /* 10109 */
++		return "WSATYPE_NOT_FOUND: Class type not found.";
++	case WSAHOST_NOT_FOUND: /* 11001 */
++		return "WSAHOST_NOT_FOUND: Host not found.";
++	case WSATRY_AGAIN: /* 11002 */
++		return "WSATRY_AGAIN: Nonauthoritative host not found.";
++	case WSANO_RECOVERY: /* 11003 */
++		return "WSANO_RECOVERY: This is a nonrecoverable error.";
++	case WSANO_DATA: /* 11004 */
++		return "WSANO_DATA: Valid name, no data record of requested type.";
++	case WSA_INVALID_HANDLE: /* OS dependent */
++		return "WSA_INVALID_HANDLE: Specified event object handle is invalid.";
++	case WSA_INVALID_PARAMETER: /* OS dependent */
++		return "WSA_INVALID_PARAMETER: One or more parameters are invalid.";
++	case WSA_IO_INCOMPLETE: /* OS dependent */
++		return "WSA_IO_INCOMPLETE: Overlapped I/O event object not in signaled state.";
++	case WSA_IO_PENDING: /* OS dependent */
++		return "WSA_IO_PENDING: Overlapped operations will complete later.";
++	case WSA_NOT_ENOUGH_MEMORY: /* OS dependent */
++		return "WSA_NOT_ENOUGH_MEMORY: Insufficient memory available.";
++	case WSA_OPERATION_ABORTED: /* OS dependent */
++		return "WSA_OPERATION_ABORTED: Overlapped operation aborted.";
++#if defined(WSAINVALIDPROCTABLE)
++	case WSAINVALIDPROCTABLE: /* OS dependent */
++		return "WSAINVALIDPROCTABLE: Invalid procedure table from service provider.";
++#endif
++#if defined(WSAINVALIDPROVIDER)
++	case WSAINVALIDPROVIDER: /* OS dependent */
++		return "WSAINVALIDPROVIDER: Invalid service provider version number.";
++#endif
++#if defined(WSAPROVIDERFAILEDINIT)
++	case WSAPROVIDERFAILEDINIT: /* OS dependent */
++		return "WSAPROVIDERFAILEDINIT: Unable to initialize a service provider.";
++#endif
++	case WSASYSCALLFAILURE: /* OS dependent */
++		return "WSASYSCALLFAILURE: System call failure.";
++	}
++	return "undocumented WSA error code";
++}
++#endif
++
+ #if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
+ 
+ #ifdef HAVE_GNUTLS
+
+commit a4f342e7ab4bc572714c92e4172487df0e0e6122
+Author: jklowden <jklowden>
+Date:   Wed Feb 11 02:41:58 2009 +0000
+
+    updated brian's address
+
+diff --git a/ChangeLog b/ChangeLog
+index bbeb142..fbcc0a8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Tue Feb 10 21:39:47 EST 2009	JK Lowden <jklowden@freetds.org>
++	* doc/getting_started.txt doc/policy.txt
++	* doc/userguide.sgml doc/htdoc/contrib.html
++	* doc/htdoc/faq.html
++	- updated brian's address
++
+ Fri Feb  6 19:22:16 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/sybdb.h include/tds.h src/dblib/dblib.c 
+ 	* src/tds/convert.c src/tds/mem.c src/tds/net.c
+@@ -1295,4 +1301,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2725 2009/02/07 00:26:22 jklowden Exp $
++$Id: ChangeLog,v 1.2726 2009/02/11 02:41:58 jklowden Exp $
+diff --git a/doc/getting_started.txt b/doc/getting_started.txt
+index 976345b..292fad5 100644
+--- a/doc/getting_started.txt
++++ b/doc/getting_started.txt
+@@ -78,6 +78,6 @@ it.
+ Misc
+ ----
+ 
+-Please send fixes and updates to this document to Brian Bruns (camber@ais.org)
++Please send fixes and updates to this document to Brian Bruns (brian@bruns.org)
+ I realize it's a little rough right now but I wanted to at least put something
+ out.
+diff --git a/doc/htdoc/contrib.html b/doc/htdoc/contrib.html
+index 284f3e1..2c22f37 100644
+--- a/doc/htdoc/contrib.html
++++ b/doc/htdoc/contrib.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: contrib.html,v 1.5 2007/08/09 07:52:07 freddy77 Exp $ -->
++<!-- $Id: contrib.html,v 1.6 2009/02/11 02:41:58 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -55,7 +55,7 @@ If on the other hand you simply want to donate money to the FreeTDS Project, we
+ <form action="https://www.paypal.com/cgi-bin/webscr" method="post">
+ <p align="center">
+ <input type="hidden" name="cmd" value="_xclick" />
+-<input type="hidden" name="business" value="camber@ais.org" />
++<input type="hidden" name="business" value="brian@bruns.org" />
+ <input type="hidden" name="item_name" value="freetds" />
+ <input type="hidden" name="item_number" value="1" />
+ <input type="hidden" name="image_url" value="http://www.freetds.org/logo_small.gif" />
+diff --git a/doc/htdoc/faq.html b/doc/htdoc/faq.html
+index dd03394..72488dd 100644
+--- a/doc/htdoc/faq.html
++++ b/doc/htdoc/faq.html
+@@ -3,7 +3,7 @@
+     "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ 
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: faq.html,v 1.24 2008/11/20 15:59:06 jklowden Exp $ -->
++<!-- $Id: faq.html,v 1.25 2009/02/11 02:41:58 jklowden Exp $ -->
+ 
+ <head>
+   <meta name="generator" content=
+@@ -242,7 +242,7 @@
+ 
+   <table summary="Who is responsible for FreeTDS">
+     <tr>
+-      <td><a href="mailto:camber@nospam.ais.org">Brian
++      <td><a href="mailto:brian@nospam.bruns.org">Brian
+       Bruns</a></td>
+ 
+       <td>Started this crazy thing</td>
+@@ -907,7 +907,7 @@
+   <font size="-1">Updates and comments <a href=
+   "mailto:jklowden@freetds.org">FreeTDS FAQ Master</a> 
+   <br/>
+-    <i>$Id: faq.html,v 1.24 2008/11/20 15:59:06 jklowden Exp $</i>
++    <i>$Id: faq.html,v 1.25 2009/02/11 02:41:58 jklowden Exp $</i>
+ 	</font>
+ <hr/>
+   <p>
+diff --git a/doc/policy.txt b/doc/policy.txt
+index cb4f078..eb5dc75 100644
+--- a/doc/policy.txt
++++ b/doc/policy.txt
+@@ -52,9 +52,9 @@ release), old FAQ entries should be reviewed.
+ 
+ --
+ Date: Fri, 9 Nov 2001 08:07:18 -0500 (EST)
+-From: Brian Bruns <camber@ais.org>
++From: Brian Bruns <brian@bruns.org>
+ To: <james.cameron@compaq.com>
+-Cc: <jklowden@speakeasy.org>
++Cc: <jklowden@freetds.org>
+ Subject: Re: FreeTDS Documentation Design Policy, Draft
+ In-Reply-To: <3BEB6E09.9BC32E58@stl.dec.com>
+ Message-ID: <Pine.LNX.4.33.0111090753430.2606-100000@localhost.localdomain>
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index c759cd2..cc88ecf 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2008/12/20 06:01:41 $</date>
+-		<releaseinfo>$Revision: 1.120 $</releaseinfo>
++		<date>$Date: 2009/02/11 02:41:58 $</date>
++		<releaseinfo>$Revision: 1.121 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -56,9 +56,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.120 $</>
+-<member>$Date: 2008/12/20 06:01:41 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.120 2008/12/20 06:01:41 jklowden Exp $.</>
++<member>$Revision: 1.121 $</>
++<member>$Date: 2009/02/11 02:41:58 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.121 2009/02/11 02:41:58 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +568,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2008/12/20 06:01:41 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2009/02/11 02:41:58 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -3971,7 +3971,7 @@ err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr,
+ 			</para>
+ 			<simplelist columns=2>
+ 				<member>
+-<ulink url="mailto:camber@ais.org">Brian Bruns</ulink> (camber@ais.org)</member>
++<ulink url="mailto:brian@bruns.org">Brian Bruns</ulink> (brian@bruns.org)</member>
+ <member>Started this crazy thing</>
+ 				<member>
+ <ulink url="mailto:misa@dntis.ro">Mihai Ibanescu</ulink> (misa@dntis.ro)</member>
+
+commit df4ea962e51431a1fa147511fbc1d902c7d4ce97
+Author: freddy77 <freddy77>
+Date:   Wed Feb 11 14:40:15 2009 +0000
+
+    use libtool -R option instead of -Wl,--rpath
+
+diff --git a/ChangeLog b/ChangeLog
+index fbcc0a8..69f8006 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Feb 11 15:39:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
++	* src/odbc/unittests/Makefile.am src/tds/unittests/Makefile.am:
++	- use libtool -R option instead of -Wl,--rpath
++
+ Tue Feb 10 21:39:47 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* doc/getting_started.txt doc/policy.txt
+ 	* doc/userguide.sgml doc/htdoc/contrib.html
+@@ -1301,4 +1306,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2726 2009/02/11 02:41:58 jklowden Exp $
++$Id: ChangeLog,v 1.2727 2009/02/11 14:40:15 freddy77 Exp $
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index a82e807..9c0301b 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.30 2008/11/12 00:47:40 jklowden Exp $
++# $Id: Makefile.am,v 1.31 2009/02/11 14:40:15 freddy77 Exp $
+ 
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT) t0004$(EXEEXT) \
+ 			t0005$(EXEEXT) t0006$(EXEEXT) t0007$(EXEEXT) t0008$(EXEEXT) \
+@@ -46,7 +46,7 @@ AM_CPPFLAGS	=	-I$(top_srcdir)/include
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
++AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+ LIBS		=	../libct.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index 7591549..add1189 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.46 2009/02/03 05:00:48 jklowden Exp $
++# $Id: Makefile.am,v 1.47 2009/02/11 14:40:15 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -58,7 +58,7 @@ AM_CPPFLAGS	= 	-DFREETDS_SRCDIR=\"$(srcdir)\" -I$(top_srcdir)/include
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
++AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+ LIBS		=	../libsybdb.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32) 
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index c8dedb1..6df8c3f 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.79 2008/11/12 00:47:41 jklowden Exp $
++# $Id: Makefile.am,v 1.80 2009/02/11 14:40:15 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -94,7 +94,7 @@ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
++AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+ LIBS		=	$(ODBCLIB) $(ODBCNODMLIB) @NETWORK_LIBS@
+ DISTCLEANFILES	=	odbc.ini odbcinst.ini
+diff --git a/src/tds/unittests/Makefile.am b/src/tds/unittests/Makefile.am
+index 51ca91f..cb11688 100644
+--- a/src/tds/unittests/Makefile.am
++++ b/src/tds/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.25 2008/11/12 00:47:41 jklowden Exp $
++# $Id: Makefile.am,v 1.26 2009/02/11 14:40:15 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) dynamic1$(EXEEXT)\
+@@ -34,7 +34,7 @@ AM_CPPFLAGS	=	-I$(top_srcdir)/include -I$(srcdir)/.. -I../
+ if MINGW32
+ AM_LDFLAGS	=	-no-fast-install
+ else
+-AM_LDFLAGS	=	-no-install -L../.libs -Wl,--rpath,../.libs
++AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+ LIBS		=	../libtds.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+
+commit aa65e962391bb45772500622b689c02a3a82996a
+Author: freddy77 <freddy77>
+Date:   Mon Feb 23 16:08:33 2009 +0000
+
+    fix core in SQLXxxDescRec
+
+diff --git a/ChangeLog b/ChangeLog
+index 69f8006..5ffb819 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Feb 23 17:07:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: applied patch by Amir Shamsuddin to fix core
++
+ Wed Feb 11 15:39:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
+ 	* src/odbc/unittests/Makefile.am src/tds/unittests/Makefile.am:
+@@ -1306,4 +1309,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2727 2009/02/11 14:40:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2728 2009/02/23 16:08:33 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index ff298b0..04a556b 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.508 2008/12/17 11:04:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.509 2009/02/23 16:08:34 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -2199,12 +2199,12 @@ SQLSetDescRec(SQLHDESC hdesc, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLS
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	if (nRecordNumber > desc->header.sql_desc_count || nRecordNumber < 0) {
++	if (nRecordNumber > desc->header.sql_desc_count || nRecordNumber <= 0) {
+ 		odbc_errs_add(&desc->errs, "07009", NULL);
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	drec = &desc->records[nRecordNumber];
++	drec = &desc->records[nRecordNumber - 1];
+ 
+ 	/* check for valid types and return "HY021" if not */
+ 	if (desc->type == DESC_IPD) {
+@@ -2257,12 +2257,12 @@ SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALL
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	if (RecordNumber > desc->header.sql_desc_count || RecordNumber < 0) {
++	if (RecordNumber > desc->header.sql_desc_count || RecordNumber <= 0) {
+ 		odbc_errs_add(&desc->errs, "07009", NULL);
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	drec = &desc->records[RecordNumber];
++	drec = &desc->records[RecordNumber - 1];
+ 
+ 	if ((rc = odbc_set_string(Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1)) != SQL_SUCCESS)
+ 		odbc_errs_add(&desc->errs, "01004", NULL);
+
+commit 07158d34437e58145aab006489e6b2acc1699f61
+Author: freddy77 <freddy77>
+Date:   Thu Feb 26 19:04:10 2009 +0000
+
+    MingW fixes
+
+diff --git a/ChangeLog b/ChangeLog
+index 5ffb819..d3df53d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Feb 26 20:04:00 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/dblib/bcp.c:
++	- fixes for MingW
++	- don't use old winsock library
++
+ Mon Feb 23 17:07:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: applied patch by Amir Shamsuddin to fix core
+ 
+@@ -1309,4 +1314,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2728 2009/02/23 16:08:33 freddy77 Exp $
++$Id: ChangeLog,v 1.2729 2009/02/26 19:04:10 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index f49be71..f399bfe 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.38 2008/12/20 06:01:26 jklowden Exp $
++dnl $Id: configure.ac,v 1.39 2009/02/26 19:04:10 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.38 $)
++AC_REVISION($Revision: 1.39 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -143,10 +143,10 @@ case $host in
+ 	tds_mingw=yes
+ 	if test "$host_cpu" = "x86_64"; then
+ 		LIBS="-lws2_32"
+-	elif test -r /usr/lib/w32api/libwsock32.a; then
+-		LIBS="-L/usr/lib/w32api -lwsock32"
++	elif test -r /usr/lib/w32api/libws2_32.a; then
++		LIBS="-L/usr/lib/w32api -lws2_32"
+ 	else
+-		LIBS="-lwsock32"
++		LIBS="-lws2_32"
+ 	fi
+ 	AM_CONDITIONAL(MINGW32, true)
+ 	;;
+@@ -433,7 +433,8 @@ TDS_NULL_IS_ZERO
+ AC_CHECK_FUNCS([vsnprintf _vsnprintf gettimeofday \
+ nl_langinfo locale_charset setenv putenv \
+ getuid getpwuid getpwuid_r fstat alarm fork \
+-gethrtime localtime_r setitimer])
++gethrtime localtime_r setitimer _lseeki64 _telli64 \
++_fseeki64 _ftelli64])
+ OLD_LIBS="$LIBS"
+ LIBS="$LIBS $NETWORK_LIBS"
+ AC_CHECK_FUNCS([inet_ntoa_r getipnodebyaddr getipnodebyname \
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 78a8141..9303dd2 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,15 +61,20 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.180 2009/01/31 19:13:20 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.181 2009/02/26 19:04:10 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+ #elif defined(WIN32) || defined(WIN64)
+ /* win32 version */
+ typedef __int64 offset_type;
+-#define fseeko(f,o,w) (_fseeki64((f),o,w) == -1)
+-#define ftello(f) _ftelli64((f))
++# if defined(HAVE__FSEEKI64) && defined(HAVE__FTELLI64)
++#  define fseeko(f,o,w) (_fseeki64((f),o,w) == -1)
++#  define ftello(f) _ftelli64((f))
++# else
++#  define fseeko(f,o,w) (_lseeki64(fileno(f),o,w) == -1)
++#  define ftello(f) _telli64(fileno(f))
++# endif
+ #else
+ /* use old version */
+ #define fseeko(f,o,w) fseek(f,o,w)
+
+commit 3a841513dd6869ec82dd3a885708b845d6686387
+Author: freddy77 <freddy77>
+Date:   Fri Feb 27 10:07:34 2009 +0000
+
+    fix possible format problems
+
+diff --git a/ChangeLog b/ChangeLog
+index d3df53d..1d44bfc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb 27 11:07:20 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/log.c src/tds/query.c: fix possible format problems
++
+ Thu Feb 26 20:04:00 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/dblib/bcp.c:
+ 	- fixes for MingW
+@@ -1314,4 +1317,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2729 2009/02/26 19:04:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2730 2009/02/27 10:07:34 freddy77 Exp $
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 7b814e4..e7401b7 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.11 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.12 2009/02/27 10:07:34 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+@@ -318,7 +318,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con
+ 		/*
+ 		 * print the offset as a 4 digit hex number
+ 		 */
+-		p += sprintf(p, "%04x", i);
++		p += sprintf(p, "%04x", ((unsigned int) i) & 0xffffu);
+ 
+ 		/*
+ 		 * print each byte in hex
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 59a7c44..08314cc 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.230 2009/01/23 10:37:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.231 2009/02/27 10:07:34 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -927,7 +927,8 @@ tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t quer
+ static void
+ tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len)
+ {
+-	size_t len, i, num_placeholders;
++	size_t len;
++	int i, num_placeholders;
+ 	const char *s, *e;
+ 	char buf[24];
+ 	const char *const query_end = query + query_len;
+
+commit 30f07ff6899b8146df4d5f362ee8e97675dfc6d1
+Author: freddy77 <freddy77>
+Date:   Fri Feb 27 10:11:42 2009 +0000
+
+    fix nasty problem under HP-UX
+
+diff --git a/ChangeLog b/ChangeLog
+index 1d44bfc..4ced9a7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Feb 27 11:11:32 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds_sysdep_private.h:
++	* src/odbc/unittests/freeclose.c src/odbc/unittests/timeout3.c:
++	* src/pool/user.c src/server/login.c src/tds/net.c:
++	- fix nasty problem under HP-UX
++
+ Fri Feb 27 11:07:20 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/log.c src/tds/query.c: fix possible format problems
+ 
+@@ -1317,4 +1323,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2730 2009/02/27 10:07:34 freddy77 Exp $
++$Id: ChangeLog,v 1.2731 2009/02/27 10:11:42 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index f399bfe..a705473 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.39 2009/02/26 19:04:10 freddy77 Exp $
++dnl $Id: configure.ac,v 1.40 2009/02/27 10:11:42 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.39 $)
++AC_REVISION($Revision: 1.40 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -169,6 +169,9 @@ case $host in
+ 		fi
+ 	fi
+ 
++	# check for _xpg_ functions
++	AC_CHECK_FUNCS([_xpg_accept _xpg_getpeername _xpg_getsockname _xpg_getsockopt _xpg_recvfrom \
++	__accept __getpeername __getsockname __getsockopt __recvfrom])
+ 	AM_CONDITIONAL(MINGW32, false)
+ 	;;
+ *)
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 4089fd4..47c5126 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.27 2009/01/16 20:27:57 jklowden Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.28 2009/02/27 10:11:42 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -160,6 +160,50 @@ typedef DWORD pid_t;
+ # define SOCKLEN_T socklen_t
+ #endif
+ 
++#define tds_accept      accept
++#define tds_getpeername getpeername
++#define tds_getsockopt  getsockopt
++#define tds_getsockname getsockname
++#define tds_recvfrom    recvfrom
++
++#if defined(__hpux__) && SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
++# if HAVE__XPG_ACCEPT
++#  undef tds_accept
++#  define tds_accept _xpg_accept
++# elif HAVE___ACCEPT
++#  undef tds_accept
++#  define tds_accept __accept
++# endif
++# if HAVE__XPG_GETPEERNAME
++#  undef tds_getpeername
++#  define tds_getpeername _xpg_getpeername
++# elif HAVE___GETPEERNAME
++#  undef tds_getpeername
++#  define tds_getpeername __getpeername
++# endif
++# if HAVE__XPG_GETSOCKOPT
++#  undef tds_getsockopt
++#  define tds_getsockopt _xpg_getsockopt
++# elif HAVE___GETSOCKOPT
++#  undef tds_getsockopt
++#  define tds_getsockopt __getsockopt
++# endif
++# if HAVE__XPG_GETSOCKNAME
++#  undef tds_getsockname
++#  define tds_getsockname _xpg_getsockname
++# elif HAVE___GETSOCKNAME
++#  undef tds_getsockname
++#  define tds_getsockname __getsockname
++# endif
++# if HAVE__XPG_RECVFROM
++#  undef tds_recvfrom
++#  define tds_recvfrom _xpg_recvfrom
++# elif HAVE___RECVFROM
++#  undef tds_recvfrom
++#  define tds_recvfrom __recvfrom
++# endif
++#endif
++
+ #ifndef TDS_SDIR_SEPARATOR
+ #define TDS_SDIR_SEPARATOR "/"
+ #endif /* !TDS_SDIR_SEPARATOR */
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 3f56323..1098546 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -50,7 +50,7 @@
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.9 2008/11/05 19:23:33 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.10 2009/02/27 10:11:42 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+@@ -188,7 +188,7 @@ fake_thread_proc(void * arg)
+ 	memset(&sin, 0, sizeof(sin));
+ 	len = sizeof(sin);
+ 	alarm(30);
+-	if ((fake_sock = accept(s, (struct sockaddr *) &sin, &len)) < 0) {
++	if ((fake_sock = tds_accept(s, (struct sockaddr *) &sin, &len)) < 0) {
+ 		perror("accept");
+ 		exit(1);
+ 	}
+@@ -288,7 +288,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	remote_addr_len = sizeof(remote_addr);
+-	if (getpeername(last_socket, &remote_addr, &remote_addr_len)) {
++	if (tds_getpeername(last_socket, &remote_addr, &remote_addr_len)) {
+ 		fprintf(stderr, "Unable to get remote address\n");
+ 		return 1;
+ 	}
+diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c
+index 27e81fd..b10e03e 100644
+--- a/src/odbc/unittests/timeout3.c
++++ b/src/odbc/unittests/timeout3.c
+@@ -40,7 +40,7 @@
+ 	test connection timeout
+ */
+ 
+-static char software_version[] = "$Id: timeout3.c,v 1.9 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: timeout3.c,v 1.10 2009/02/27 10:11:42 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -99,7 +99,7 @@ fake_thread_proc(void * arg)
+ 	memset(&sin, 0, sizeof(sin));
+ 	len = sizeof(sin);
+ 	alarm(30);
+-	if ((fake_sock = accept(s, (struct sockaddr *) &sin, &len)) < 0) {
++	if ((fake_sock = tds_accept(s, (struct sockaddr *) &sin, &len)) < 0) {
+ 		perror("accept");
+ 		exit(1);
+ 	}
+diff --git a/src/pool/user.c b/src/pool/user.c
+index e2db9db..2fbd78a 100644
+--- a/src/pool/user.c
++++ b/src/pool/user.c
+@@ -48,7 +48,7 @@
+ #include "tdssrv.h"
+ #include "tdsstring.h"
+ 
+-TDS_RCSID(var, "$Id: user.c,v 1.33 2008/11/15 09:57:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: user.c,v 1.34 2009/02/27 10:11:42 freddy77 Exp $");
+ 
+ static TDS_POOL_USER *pool_user_find_new(TDS_POOL * pool);
+ static int pool_user_login(TDS_POOL * pool, TDS_POOL_USER * puser);
+@@ -109,7 +109,7 @@ pool_user_create(TDS_POOL * pool, TDS_SYS_SOCKET s, struct sockaddr_in *sin)
+ 
+ 	fprintf(stderr, "accepting connection\n");
+ 	len = sizeof(*sin);
+-	if (TDS_IS_SOCKET_INVALID(fd = accept(s, (struct sockaddr *) sin, &len))) {
++	if (TDS_IS_SOCKET_INVALID(fd = tds_accept(s, (struct sockaddr *) sin, &len))) {
+ 		perror("accept");
+ 		return NULL;
+ 	}
+diff --git a/src/server/login.c b/src/server/login.c
+index 976beed..db0163d 100644
+--- a/src/server/login.c
++++ b/src/server/login.c
+@@ -58,7 +58,7 @@
+ #include "tdssrv.h"
+ #include "tdsstring.h"
+ 
+-static char software_version[] = "$Id: login.c,v 1.53 2008/11/14 16:34:22 freddy77 Exp $";
++static char software_version[] = "$Id: login.c,v 1.54 2009/02/27 10:11:43 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ unsigned char *
+@@ -100,7 +100,7 @@ tds_listen(TDSCONTEXT * ctx, int ip_port)
+ 	}
+ 	listen(s, 5);
+ 	len = sizeof(sin);
+-	fd = accept(s, (struct sockaddr *) &sin, &len);
++	fd = tds_accept(s, (struct sockaddr *) &sin, &len);
+ 	if (TDS_IS_SOCKET_INVALID(fd)) {
+ 		CLOSESOCKET(s);
+ 		perror("accept");
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 5fd6ebb..926627d 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.86 2009/02/07 00:26:22 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.87 2009/02/27 10:11:43 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -299,7 +299,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	/* check socket error */
+ 	optlen = sizeof(len);
+ 	len = 0;
+-	if (getsockopt(tds->s, SOL_SOCKET, SO_ERROR, (char *) &len, &optlen) != 0) {
++	if (tds_getsockopt(tds->s, SOL_SOCKET, SO_ERROR, (char *) &len, &optlen) != 0) {
+ 		tds->oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) failed: %s\n", strerror(sock_errno));
+ 		goto not_available;
+
+commit e19e11d69bf779be35a1abe5d1a2da6a88718495
+Author: freddy77 <freddy77>
+Date:   Fri Feb 27 10:37:41 2009 +0000
+
+    replace errx and warnx
+
+diff --git a/ChangeLog b/ChangeLog
+index 4ced9a7..334e58c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Feb 27 11:37:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c:
++	- replace errx and warnx cause not that portable
++
+ Fri Feb 27 11:11:32 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac include/tds_sysdep_private.h:
+ 	* src/odbc/unittests/freeclose.c src/odbc/unittests/timeout3.c:
+@@ -1323,4 +1327,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2731 2009/02/27 10:11:42 freddy77 Exp $
++$Id: ChangeLog,v 1.2732 2009/02/27 10:37:41 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 58b6c1b..5a8089b 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -16,9 +16,7 @@
+ #include "replacements.h"
+ #endif
+ 
+-#include <err.h>
+-
+-static char software_version[] = "$Id: common.c,v 1.27 2009/02/06 10:11:09 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.28 2009/02/27 10:37:41 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -223,7 +221,7 @@ read_login_info(int argc, char **argv)
+ 
+ 	if ((INPUT = fopen(sql_file, "r")) == NULL) {
+ 		fflush(stdout);
+-		warnx("could not open SQL input file \"%s\"\n", sql_file);
++		fprintf(stderr, "could not open SQL input file \"%s\"\n", sql_file);
+ 	}
+ 
+ 	if (!free_file_registered)
+@@ -248,12 +246,14 @@ sql_cmd(DBPROCESS *dbproc, FILE *stream)
+ 	while ((p = fgets(line, (int)sizeof(line), stream)) != NULL && strcasecmp("go\n", p) != 0) {
+ 		printf("\t%3d: %s", ++i, p);
+ 		if ((erc = dbcmd(dbproc, p)) != SUCCEED) {
+-			errx(1, "%s: error: could write \"%s\" to dbcmd()\n", BASENAME, p);
++			fprintf(stderr, "%s: error: could write \"%s\" to dbcmd()\n", BASENAME, p);
++			exit(1);
+ 		}
+ 	}
+ 
+ 	if (ferror(stream)) {
+-		errx(1, "%s: error: could not read SQL input file \"%s\"\n", BASENAME, sql_file);
++		fprintf(stderr, "%s: error: could not read SQL input file \"%s\"\n", BASENAME, sql_file);
++		exit(1);
+ 	}
+ 
+ 	return erc;
+
+commit 397c27a46c4a4785f261e70333c64cc4b522d10f
+Author: freddy77 <freddy77>
+Date:   Fri Feb 27 10:46:23 2009 +0000
+
+    cleanup public sysdep header
+
+diff --git a/ChangeLog b/ChangeLog
+index 334e58c..fe76286 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Feb 27 11:46:15 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h include/tds_sysdep_public.h.in:
++	- cleanup public sysdep header
++
+ Fri Feb 27 11:37:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c:
+ 	- replace errx and warnx cause not that portable
+@@ -1327,4 +1331,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2732 2009/02/27 10:37:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2733 2009/02/27 10:46:23 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 47c5126..0b63187 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.28 2009/02/27 10:11:42 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.29 2009/02/27 10:46:24 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -160,6 +160,15 @@ typedef DWORD pid_t;
+ # define SOCKLEN_T socklen_t
+ #endif
+ 
++#if !defined(__WIN32__) && !defined(_WIN32) && !defined(WIN32)
++typedef int TDS_SYS_SOCKET;
++#define INVALID_SOCKET -1
++#define TDS_IS_SOCKET_INVALID(s) ((s) < 0)
++#else
++typedef SOCKET TDS_SYS_SOCKET;
++#define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
++#endif
++
+ #define tds_accept      accept
+ #define tds_getpeername getpeername
+ #define tds_getsockopt  getsockopt
+diff --git a/include/tds_sysdep_public.h.in b/include/tds_sysdep_public.h.in
+index 96a782c..7e50ac0 100644
+--- a/include/tds_sysdep_public.h.in
++++ b/include/tds_sysdep_public.h.in
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_public_h_
+ #define _tds_sysdep_public_h_
+ 
+-/* $Id: tds_sysdep_public.h.in,v 1.12 2008/01/20 14:23:59 freddy77 Exp $ */
++/* $Id: tds_sysdep_public.h.in,v 1.13 2009/02/27 10:46:24 freddy77 Exp $ */
+ 
+ #ifdef __cplusplus
+ extern "C"
+@@ -68,15 +68,6 @@ extern "C"
+ #define tds_sysdep_intptr_type @tds_sysdep_intptr_type@
+ #endif				/* !tds_sysdep_intptr_type */
+ 
+-#if !defined(__WIN32__) && !defined(_WIN32) && !defined(WIN32)
+-typedef int TDS_SYS_SOCKET;
+-#define INVALID_SOCKET -1
+-#define TDS_IS_SOCKET_INVALID(s) ((s) < 0)
+-#else
+-typedef SOCKET TDS_SYS_SOCKET;
+-#define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
+-#endif
+-
+ #if !defined(MSDBLIB) && !defined(SYBDBLIB)
+ @dblib_define@
+ #endif
+
+commit 6d91a04faee759ae78e38b1abfd317bec842c66b
+Author: freddy77 <freddy77>
+Date:   Fri Feb 27 15:51:39 2009 +0000
+
+    remove INPUT param from sql_cmd
+
+diff --git a/ChangeLog b/ChangeLog
+index fe76286..721e89f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,20 @@
++Fri Feb 27 16:50:57 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/bcp.c src/dblib/unittests/common.c:
++	* src/dblib/unittests/common.h src/dblib/unittests/dbmorecmds.c:
++	* src/dblib/unittests/done_handling.c src/dblib/unittests/rpc.c:
++	* src/dblib/unittests/t0001.c src/dblib/unittests/t0002.c:
++	* src/dblib/unittests/t0003.c src/dblib/unittests/t0004.c:
++	* src/dblib/unittests/t0005.c src/dblib/unittests/t0006.c:
++	* src/dblib/unittests/t0007.c src/dblib/unittests/t0009.c:
++	* src/dblib/unittests/t0011.c src/dblib/unittests/t0012.c:
++	* src/dblib/unittests/t0013.c src/dblib/unittests/t0014.c:
++	* src/dblib/unittests/t0015.c src/dblib/unittests/t0016.c:
++	* src/dblib/unittests/t0017.c src/dblib/unittests/t0018.c:
++	* src/dblib/unittests/t0020.c src/dblib/unittests/t0022.c:
++	* src/dblib/unittests/t0023.c src/dblib/unittests/text_buffer.c:
++	* src/dblib/unittests/timeout.c:
++	- remove INPUT param from sql_cmd
++
+ Fri Feb 27 11:46:15 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h include/tds_sysdep_public.h.in:
+ 	- cleanup public sysdep header
+@@ -1331,4 +1348,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2733 2009/02/27 10:46:23 freddy77 Exp $
++$Id: ChangeLog,v 1.2734 2009/02/27 15:51:39 freddy77 Exp $
+diff --git a/src/dblib/unittests/bcp.c b/src/dblib/unittests/bcp.c
+index d777aa3..ca06526 100644
+--- a/src/dblib/unittests/bcp.c
++++ b/src/dblib/unittests/bcp.c
+@@ -13,7 +13,7 @@
+ 
+ #include "bcp.h"
+ 
+-static char software_version[] = "$Id: bcp.c,v 1.17 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: bcp.c,v 1.18 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char cmd[512];
+@@ -46,7 +46,7 @@ init(DBPROCESS * dbproc, const char *name)
+ 	RETCODE rc;
+ 
+ 	fprintf(stdout, "Dropping %s.%s..%s\n", SERVER, DATABASE, name);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -58,8 +58,8 @@ init(DBPROCESS * dbproc, const char *name)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "Creating %s.%s..%s\n", SERVER, DATABASE, name);
+-	sql_cmd(dbproc, INPUT);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
++	sql_cmd(dbproc);
+ 
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+@@ -271,7 +271,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ #if 1
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 
+ 	dbsqlexec(dbproc);
+ 	while ((i=dbresults(dbproc)) == SUCCEED) {
+@@ -287,7 +287,7 @@ main(int argc, char **argv)
+ 	} else {
+ 		fprintf(stdout, "Dropping table %s\n", table_name);
+ 		add_bread_crumb();
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		add_bread_crumb();
+ 		dbsqlexec(dbproc);
+ 		add_bread_crumb();
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 5a8089b..2dbad1c 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -16,7 +16,7 @@
+ #include "replacements.h"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.28 2009/02/27 10:37:41 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.29 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -42,7 +42,7 @@ char PASSWORD[512];
+ char DATABASE[512];
+ 
+ static char sql_file[PATH_MAX];
+-FILE* INPUT;
++static FILE* input_file;
+ 
+ static char *DIRNAME = NULL;
+ static const char *BASENAME = NULL;
+@@ -92,9 +92,9 @@ char free_file_registered = 0;
+ static void
+ free_file(void)
+ {
+-	if (INPUT) {
+-		fclose(INPUT);
+-		INPUT = NULL;
++	if (input_file) {
++		fclose(input_file);
++		input_file = NULL;
+ 	}
+ }
+ 
+@@ -219,7 +219,7 @@ read_login_info(int argc, char **argv)
+ 	len = snprintf(sql_file, sizeof(sql_file), "%s.sql", BASENAME);
+ 	assert(len <= sizeof(sql_file));
+ 
+-	if ((INPUT = fopen(sql_file, "r")) == NULL) {
++	if ((input_file = fopen(sql_file, "r")) == NULL) {
+ 		fflush(stdout);
+ 		fprintf(stderr, "could not open SQL input file \"%s\"\n", sql_file);
+ 	}
+@@ -237,13 +237,13 @@ read_login_info(int argc, char **argv)
+  * Fill the command buffer from a file while echoing it to standard output.
+  */
+ RETCODE 
+-sql_cmd(DBPROCESS *dbproc, FILE *stream)
++sql_cmd(DBPROCESS *dbproc)
+ {
+ 	char line[2048], *p = line;
+ 	int i = 0;
+ 	RETCODE erc=SUCCEED;
+ 	
+-	while ((p = fgets(line, (int)sizeof(line), stream)) != NULL && strcasecmp("go\n", p) != 0) {
++	while ((p = fgets(line, (int)sizeof(line), input_file)) != NULL && strcasecmp("go\n", p) != 0) {
+ 		printf("\t%3d: %s", ++i, p);
+ 		if ((erc = dbcmd(dbproc, p)) != SUCCEED) {
+ 			fprintf(stderr, "%s: error: could write \"%s\" to dbcmd()\n", BASENAME, p);
+@@ -251,7 +251,7 @@ sql_cmd(DBPROCESS *dbproc, FILE *stream)
+ 		}
+ 	}
+ 
+-	if (ferror(stream)) {
++	if (ferror(input_file)) {
+ 		fprintf(stderr, "%s: error: could not read SQL input file \"%s\"\n", BASENAME, sql_file);
+ 		exit(1);
+ 	}
+diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h
+index 0f5d023..b0d2e6a 100644
+--- a/src/dblib/unittests/common.h
++++ b/src/dblib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.16 2009/02/01 22:29:39 jklowden Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.17 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #if HAVE_CONFIG_H
+@@ -76,7 +76,6 @@ extern char PASSWORD[512];
+ extern char USER[512];
+ extern char SERVER[512];
+ extern char DATABASE[512];
+-extern FILE* INPUT;
+ 
+ void set_malloc_options(void);
+ int read_login_info(int argc, char **argv);
+@@ -87,7 +86,7 @@ int syb_msg_handler(DBPROCESS * dbproc,
+ 		    DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line);
+ int syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ 
+-RETCODE sql_cmd(DBPROCESS *dbproc, FILE *stream);
++RETCODE sql_cmd(DBPROCESS *dbproc);
+ 
+ #define int2ptr(i) ((void*)(((char*)0)+(i)))
+ #define ptr2int(p) ((int)(((char*)(p))-((char*)0)))
+diff --git a/src/dblib/unittests/dbmorecmds.c b/src/dblib/unittests/dbmorecmds.c
+index a01522b..45e5067 100644
+--- a/src/dblib/unittests/dbmorecmds.c
++++ b/src/dblib/unittests/dbmorecmds.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: dbmorecmds.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: dbmorecmds.c,v 1.15 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version,	no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -64,7 +64,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -72,7 +72,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -80,7 +80,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select one resultset\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -104,7 +104,7 @@ main(int argc, char **argv)
+ 	dbcancel(dbproc);
+ 
+ 	fprintf(stdout, "select two resultsets\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 	nresults = 0;
+diff --git a/src/dblib/unittests/done_handling.c b/src/dblib/unittests/done_handling.c
+index 56d95d3..ff843c5 100644
+--- a/src/dblib/unittests/done_handling.c
++++ b/src/dblib/unittests/done_handling.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: done_handling.c,v 1.9 2009/02/05 08:49:45 freddy77 Exp $";
++static char software_version[] = "$Id: done_handling.c,v 1.10 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -65,7 +65,7 @@ query(const char comment[])
+ {
+ 	if (comment)
+ 		printf("%s\n", comment);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+@@ -115,7 +115,7 @@ do_test(const char comment[])
+ 
+ 	if (comment)
+ 		printf("%s\n", comment);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 
+ 	check_state("sqlexec ", prretcode, dbsqlexec(dbproc));
+ 
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index 2dfbf88..e02eefe 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.37 2009/02/05 08:49:45 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.38 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int init_proc(DBPROCESS * dbproc, const char *name);
+@@ -47,7 +47,7 @@ init_proc(DBPROCESS * dbproc, const char *name)
+ 	if (name[0] != '#') {
+ 		fprintf(stdout, "Dropping procedure %s\n", name);
+ 		add_bread_crumb();
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		add_bread_crumb();
+ 		dbsqlexec(dbproc);
+ 		add_bread_crumb();
+@@ -58,7 +58,7 @@ init_proc(DBPROCESS * dbproc, const char *name)
+ 	}
+ 
+ 	fprintf(stdout, "Creating procedure %s\n", name);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	if ((ret = dbsqlexec(dbproc)) == FAIL) {
+ 		add_bread_crumb();
+ 		if (name[0] == '#')
+@@ -411,7 +411,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping procedure\n");
+ 	add_bread_crumb();
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+diff --git a/src/dblib/unittests/t0001.c b/src/dblib/unittests/t0001.c
+index 56ae4d8..15cdbbd 100644
+--- a/src/dblib/unittests/t0001.c
++++ b/src/dblib/unittests/t0001.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.29 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -82,20 +82,20 @@ main(int argc, char **argv)
+ #ifdef DBQUOTEDIDENT
+ 	fprintf(stdout, "QUOTED_IDENTIFIER is %s\n", (dbisopt(dbproc, DBQUOTEDIDENT, NULL))? "ON":"OFF");
+ #endif
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+-	for (i = 0; i < rows_to_add && sql_cmd(dbproc, INPUT) == SUCCEED; i++) {
++	for (i = 0; i < rows_to_add && sql_cmd(dbproc) == SUCCEED; i++) {
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) == SUCCEED) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/t0002.c b/src/dblib/unittests/t0002.c
+index 7f65bc1..aaba66b 100644
+--- a/src/dblib/unittests/t0002.c
++++ b/src/dblib/unittests/t0002.c
+@@ -10,7 +10,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.23 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.24 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -89,7 +89,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	add_bread_crumb();
+-	sql_cmd(dbproc,  INPUT); /* drop table if exists */
++	sql_cmd(dbproc); /* drop table if exists */
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -102,21 +102,21 @@ main(int argc, char **argv)
+ 	}
+ 	add_bread_crumb();
+ 
+-	sql_cmd(dbproc,  INPUT); /* create table */
++	sql_cmd(dbproc); /* create table */
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	for (i = 1; i <= rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);	/* two result sets */
++	sql_cmd(dbproc);	/* two result sets */
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/t0003.c b/src/dblib/unittests/t0003.c
+index 4d9dcc5..b0ca667 100644
+--- a/src/dblib/unittests/t0003.c
++++ b/src/dblib/unittests/t0003.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.15 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.16 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -65,7 +65,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -73,7 +73,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -81,7 +81,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c
+index 48aa4a1..1a62955 100644
+--- a/src/dblib/unittests/t0004.c
++++ b/src/dblib/unittests/t0004.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.18 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.19 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -56,7 +56,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -64,14 +64,14 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+ 		}
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT); /* select */
++	sql_cmd(dbproc); /* select */
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -133,7 +133,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "second select\n");
+ 
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+diff --git a/src/dblib/unittests/t0005.c b/src/dblib/unittests/t0005.c
+index ff5b5ad..5c2db20 100644
+--- a/src/dblib/unittests/t0005.c
++++ b/src/dblib/unittests/t0005.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0005.c,v 1.25 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0005.c,v 1.26 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -55,7 +55,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -71,7 +71,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -79,7 +79,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -139,7 +139,7 @@ main(int argc, char **argv)
+ 	expected_error = 20019;
+ 	dbsetuserdata(dbproc, (BYTE*) &expected_error);
+ 
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -200,7 +200,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Testing anticipated failure\n");
+ 
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -215,7 +215,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping proc\n");
+ 	add_bread_crumb();
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -225,7 +225,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating proc\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		fprintf(stderr, "%s:%d: failed to create procedure\n", __FILE__, __LINE__);
+@@ -236,7 +236,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "calling proc\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		fprintf(stderr, "%s:%d: failed to call procedure\n", __FILE__, __LINE__);
+@@ -294,7 +294,7 @@ main(int argc, char **argv)
+ 	fprintf(stdout, "The following command should succeed because\n"
+ 			"we have fetched the exact number of rows in the result set\n");
+ 
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -306,7 +306,7 @@ main(int argc, char **argv)
+ 
+ 	dbcancel(dbproc);
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0006.c b/src/dblib/unittests/t0006.c
+index 127ac63..a4c69c1 100644
+--- a/src/dblib/unittests/t0006.c
++++ b/src/dblib/unittests/t0006.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0006.c,v 1.18 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0006.c,v 1.19 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -92,7 +92,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -100,7 +100,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -108,7 +108,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "first select\n");
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+ 		failed = 1;
+ 	}
+@@ -145,7 +145,7 @@ main(int argc, char **argv)
+ 	testint = -1;
+ 	strcpy(teststr, "bogus");
+ 	fprintf(stdout, "second select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/t0007.c b/src/dblib/unittests/t0007.c
+index 01e0f60..444486c 100644
+--- a/src/dblib/unittests/t0007.c
++++ b/src/dblib/unittests/t0007.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0007.c,v 1.19 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.20 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -14,7 +14,7 @@ create_tables(DBPROCESS * dbproc, int rows_to_add)
+ 	int i;
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -22,7 +22,7 @@ create_tables(DBPROCESS * dbproc, int rows_to_add)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 1; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -36,7 +36,7 @@ start_query(DBPROCESS * dbproc)
+ {
+ 	int i;
+ 
+-	if (SUCCEED != sql_cmd(dbproc, INPUT)) {
++	if (SUCCEED != sql_cmd(dbproc)) {
+ 		return 0;
+ 	}
+ 	if (SUCCEED != dbsqlexec(dbproc)) {
+diff --git a/src/dblib/unittests/t0009.c b/src/dblib/unittests/t0009.c
+index 43ebf3d..0f77205 100644
+--- a/src/dblib/unittests/t0009.c
++++ b/src/dblib/unittests/t0009.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0009.c,v 1.16 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0009.c,v 1.17 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -60,19 +60,19 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "insert\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -80,7 +80,7 @@ main(int argc, char **argv)
+ 
+ 
+ 	fprintf(stdout, "select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/t0011.c b/src/dblib/unittests/t0011.c
+index cbd8d33..df102d5 100644
+--- a/src/dblib/unittests/t0011.c
++++ b/src/dblib/unittests/t0011.c
+@@ -6,7 +6,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0011.c,v 1.15 2009/02/05 08:49:45 freddy77 Exp $";
++static char software_version[] = "$Id: t0011.c,v 1.16 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -42,14 +42,14 @@ main(int argc, char **argv)
+ 	dbloginfree(login);
+ 
+ 	fprintf(stdout, "Dropping table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -80,7 +80,7 @@ select_rows(DBPROCESS * dbproc, int bind_type)
+ 
+ 
+ 	fprintf(stdout, "select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 
+@@ -131,7 +131,7 @@ select_rows(DBPROCESS * dbproc, int bind_type)
+ void
+ insert_row(DBPROCESS * dbproc)
+ {
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0012.c b/src/dblib/unittests/t0012.c
+index d7f34ea..91d3894 100644
+--- a/src/dblib/unittests/t0012.c
++++ b/src/dblib/unittests/t0012.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0012.c,v 1.23 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0012.c,v 1.24 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int failed = 0;
+ 
+@@ -43,19 +43,19 @@ main(int argc, char *argv[])
+ 	fprintf(stdout, "After logon\n");
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index 06b2396..6f88015 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.29 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -30,7 +30,7 @@ drop_table(void)
+ 
+ 	dbcancel(dbproc);
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -106,7 +106,7 @@ main(int argc, char **argv)
+ 	fread((void *) blob, isiz, 1, fp);
+ 	fclose(fp);
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -114,13 +114,13 @@ main(int argc, char **argv)
+ 
+ 	atexit(drop_table);
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	if (dbresults(dbproc) != SUCCEED) {
+ 		fprintf(stderr, "Error inserting blob\n");
+@@ -186,7 +186,7 @@ main(int argc, char **argv)
+ 		dbuse(dbproc, DATABASE);
+ 	}
+ #endif
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -221,13 +221,13 @@ main(int argc, char **argv)
+ 	dbnextrow(dbproc);
+ 
+ 	/* get the image */
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	dbresults(dbproc);
+ 
+ 	fprintf(stdout, "select 2\n");
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	if (dbresults(dbproc) != SUCCEED) {
+ 		fprintf(stderr, "Error extracting blob\n");
+diff --git a/src/dblib/unittests/t0014.c b/src/dblib/unittests/t0014.c
+index 68a65a7..4a82e6c 100644
+--- a/src/dblib/unittests/t0014.c
++++ b/src/dblib/unittests/t0014.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0014.c,v 1.30 2009/02/03 09:10:58 freddy77 Exp $";
++static char software_version[] = "$Id: t0014.c,v 1.31 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -85,14 +85,14 @@ main(int argc, char **argv)
+ 
+ 	/* FIXME this test seem to not work using temporary tables (sybase?)... */
+ 	fprintf(stdout, "Dropping table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -101,7 +101,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -109,7 +109,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	for (i = 0; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		if (dbresults(dbproc) != SUCCEED) {
+ 			fprintf(stderr, "Error inserting blob\n");
+@@ -154,7 +154,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "select\n");
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+@@ -245,7 +245,7 @@ main(int argc, char **argv)
+ 	free(blob);
+ 
+ 	fprintf(stdout, "Dropping table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0015.c b/src/dblib/unittests/t0015.c
+index 16d8176..cd49aa6 100644
+--- a/src/dblib/unittests/t0015.c
++++ b/src/dblib/unittests/t0015.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0015.c,v 1.19 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0015.c,v 1.20 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -55,7 +55,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -63,7 +63,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -71,7 +71,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -115,7 +115,7 @@ main(int argc, char **argv)
+ 	dbcancel(dbproc);
+ 
+ 	fprintf(stdout, "select 2\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != SUCCEED) {
+diff --git a/src/dblib/unittests/t0016.c b/src/dblib/unittests/t0016.c
+index f3803ac..13d1ee7 100644
+--- a/src/dblib/unittests/t0016.c
++++ b/src/dblib/unittests/t0016.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <sys/stat.h>
+ 
+-static char software_version[] = "$Id: t0016.c,v 1.29 2009/02/05 08:49:45 freddy77 Exp $";
++static char software_version[] = "$Id: t0016.c,v 1.30 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -81,7 +81,7 @@ main(int argc, char *argv[])
+ 	printf("After logon\n");
+ 
+ 	printf("Creating table '%s'\n", TABLE_NAME);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -96,7 +96,7 @@ main(int argc, char *argv[])
+ 
+ 	printf("return from bcp_init = %d\n", ret);
+ 
+-	ret = sql_cmd(dbproc, INPUT);
++	ret = sql_cmd(dbproc);
+ 	printf("return from dbcmd = %d\n", ret);
+ 
+ 	ret = dbsqlexec(dbproc);
+@@ -138,7 +138,7 @@ main(int argc, char *argv[])
+ 		failure("bcp_int failed\n");
+ 
+ 	printf("select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 	if (dbresults(dbproc) != FAIL) {
+diff --git a/src/dblib/unittests/t0017.c b/src/dblib/unittests/t0017.c
+index 4b12456..afb510b 100644
+--- a/src/dblib/unittests/t0017.c
++++ b/src/dblib/unittests/t0017.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0017.c,v 1.28 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0017.c,v 1.29 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -68,14 +68,14 @@ main(int argc, char *argv[])
+ 	printf("done\n");
+ 
+ 	printf("Creating table ... ");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 	printf("done\n");
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -89,7 +89,7 @@ main(int argc, char *argv[])
+ 	printf("done\n");
+ 
+ 	printf("Issuing SELECT ... ");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	printf("done\nFetching metadata ... ");
+ 	if (dbresults(dbproc) != FAIL) {
+@@ -132,7 +132,7 @@ main(int argc, char *argv[])
+ 	printf("%d rows copied\n", rows_copied);
+ 
+ 	/* delete rows */
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -148,7 +148,7 @@ main(int argc, char *argv[])
+ 	printf("done\n");
+ 
+ 	printf("Issuing SELECT ... ");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	printf("done\nFetching metadata ... ");
+ 	if (dbresults(dbproc) != FAIL) {
+@@ -194,7 +194,7 @@ main(int argc, char *argv[])
+ 
+ 	/* test we inserted correctly row */
+ 	if (!failed) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			while ((ret=dbnextrow(dbproc)) != NO_MORE_ROWS) {
+diff --git a/src/dblib/unittests/t0018.c b/src/dblib/unittests/t0018.c
+index 6f5febc..b1ca8ca 100644
+--- a/src/dblib/unittests/t0018.c
++++ b/src/dblib/unittests/t0018.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0018.c,v 1.20 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0018.c,v 1.21 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -55,7 +55,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+@@ -63,7 +63,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "insert\n");
+ 	for (i = 0; i < rows_to_add; i++) {
+-		sql_cmd(dbproc, INPUT);
++		sql_cmd(dbproc);
+ 		dbsqlexec(dbproc);
+ 		while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 			/* nop */
+@@ -76,7 +76,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -166,7 +166,7 @@ main(int argc, char **argv)
+ 		exit(1);
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+diff --git a/src/dblib/unittests/t0020.c b/src/dblib/unittests/t0020.c
+index 90e0ec0..083eb22 100644
+--- a/src/dblib/unittests/t0020.c
++++ b/src/dblib/unittests/t0020.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0020.c,v 1.17 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0020.c,v 1.18 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -66,7 +66,7 @@ main(int argc, char **argv)
+ 	dbloginfree(login);
+ 	add_bread_crumb();
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	fprintf(stderr, "The following invalid column error is normal.\n");
+ 
+ 	expected_error = 207;
+@@ -79,7 +79,7 @@ main(int argc, char **argv)
+ 		exit(1);
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	ret = dbsqlexec(dbproc);
+ 	if (ret != SUCCEED) {
+ 		failed = 1;
+diff --git a/src/dblib/unittests/t0022.c b/src/dblib/unittests/t0022.c
+index 7a258b7..0ddc8d4 100644
+--- a/src/dblib/unittests/t0022.c
++++ b/src/dblib/unittests/t0022.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0022.c,v 1.26 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0022.c,v 1.27 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -56,7 +56,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping proc\n");
+ 	add_bread_crumb();
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -72,7 +72,7 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating proc\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		add_bread_crumb();
+ 		fprintf(stdout, "Failed to create proc t0022.\n");
+@@ -88,7 +88,7 @@ main(int argc, char **argv)
+ 
+ 	sprintf(cmd, "declare @b int\nexec t0022 @b = @b output\n");
+ 	fprintf(stdout, "%s\n", cmd);
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+@@ -157,7 +157,7 @@ main(int argc, char **argv)
+ 
+ 	fprintf(stdout, "Dropping proc\n");
+ 	add_bread_crumb();
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	add_bread_crumb();
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+@@ -170,7 +170,7 @@ main(int argc, char **argv)
+ 	 */
+ 	
+ 	fprintf(stdout, "Dropping proc t0022a\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 
+ 	dbsqlexec(dbproc);
+ 
+@@ -185,7 +185,7 @@ main(int argc, char **argv)
+ 	assert(erc == NO_MORE_RESULTS);
+ 
+ 	fprintf(stdout, "creating proc t0022a\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	if (dbsqlexec(dbproc) == FAIL) {
+ 		fprintf(stdout, "Failed to create proc t0022a.\n");
+ 		exit(1);
+@@ -198,7 +198,7 @@ main(int argc, char **argv)
+ 		assert(erc == NO_MORE_ROWS);
+ 	}
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 
+ 	for (i=1; (erc = dbresults(dbproc)) != NO_MORE_RESULTS; i++) {
+@@ -232,7 +232,7 @@ main(int argc, char **argv)
+ 	assert(erc == NO_MORE_RESULTS);
+ 	
+ 	fprintf(stdout, "Dropping proc t0022a\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/t0023.c b/src/dblib/unittests/t0023.c
+index 3ec2afc..3c03537 100644
+--- a/src/dblib/unittests/t0023.c
++++ b/src/dblib/unittests/t0023.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0023.c,v 1.15 2009/02/05 08:49:45 freddy77 Exp $";
++static char software_version[] = "$Id: t0023.c,v 1.16 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -59,7 +59,7 @@ main(int argc, char *argv[])
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+@@ -67,34 +67,34 @@ main(int argc, char *argv[])
+ 
+ 	fprintf(stdout, "insert\n");
+ 
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) == SUCCEED) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "select\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+ 
+diff --git a/src/dblib/unittests/text_buffer.c b/src/dblib/unittests/text_buffer.c
+index f0e2d20..9662ca4 100644
+--- a/src/dblib/unittests/text_buffer.c
++++ b/src/dblib/unittests/text_buffer.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: text_buffer.c,v 1.5 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: text_buffer.c,v 1.6 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -59,19 +59,19 @@ main(int argc, char **argv)
+ 	add_bread_crumb();
+ 
+ 	fprintf(stdout, "creating table\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+ 
+ 	fprintf(stdout, "insert\n");
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+ 	}
+-	sql_cmd(dbproc, INPUT);
++	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+ 		/* nop */
+diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c
+index 2431d0c..1551cb6 100644
+--- a/src/dblib/unittests/timeout.c
++++ b/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.6 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.7 2009/02/27 15:52:48 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+@@ -159,7 +159,7 @@ main(int argc, char **argv)
+ 	}
+ 	printf ("issuing a query that will take 30 seconds\n");
+ 
+-	if (FAIL == sql_cmd(dbproc, INPUT)) {
++	if (FAIL == sql_cmd(dbproc)) {
+ 		fprintf(stderr, "Failed: dbcmd\n");
+ 		exit(1);
+ 	}
+
+commit 71c7541d6a4feadf27ea08c9611bca06a11baa22
+Author: jklowden <jklowden>
+Date:   Sat Feb 28 17:38:38 2009 +0000
+
+    DBDATEREC members are 32-bit
+
+diff --git a/ChangeLog b/ChangeLog
+index 721e89f..48941f4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Sat Feb 28 12:32:06 EST 2009	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h DBDATEREC members are 32-bit
++	* BUGS TODO more things to fix
++	* include/tds.h src/tds/login.c src/tds/net.c
++	- login packet debugging options
++
+ Fri Feb 27 16:50:57 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/bcp.c src/dblib/unittests/common.c:
+ 	* src/dblib/unittests/common.h src/dblib/unittests/dbmorecmds.c:
+@@ -1348,4 +1354,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2734 2009/02/27 15:51:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2735 2009/02/28 17:38:38 jklowden Exp $
+diff --git a/include/sybdb.h b/include/sybdb.h
+index 866a5d5..fc3dd4b 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.88 2009/02/07 00:26:22 jklowden Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.89 2009/02/28 17:38:39 jklowden Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -374,41 +374,40 @@ typedef struct tds_dblib_dbprocess DBPROCESS;
+  * Sybase & Microsoft use different names for the dbdaterec members. 
+  * Keep these two structures physically identical in memory.  
+  * dbdatecrack() casts one to the other for ease of implementation. 
+- * N.B. Microsoft documents the members as int, not long.   
+  *
+  * Giving credit where credit is due, we can acknowledge that
+  * Microsoft chose the better names here, hands down.  ("datedmonth"?!)
+  */
+ struct tds_microsoft_dbdaterec
+ {
+-	long year;		/* 1753 - 9999  	   */
+-	long quarter;		/* 1 - 4 		   */
+-	long month;		/* 1 - 12 		   */
+-	long day;		/* 1 - 31 		   */
+-	long dayofyear;		/* 1 - 366 		   */
+-	long week;            	/* 1 - 54 (for leap years) */
+-	long weekday;		/* 1 - 7 (Mon. - Sun.)     */
+-	long hour;		/* 0 - 23 		   */
+-	long minute;		/* 0 - 59 		   */
+-	long second;		/* 0 - 59 		   */
+-	long millisecond;	/* 0 - 999 		   */
+-	long tzone;		/* 0 - 127  (Sybase only)  */	
++	DBINT year;		/* 1753 - 9999  	   */
++	DBINT quarter;		/* 1 - 4 		   */
++	DBINT month;		/* 1 - 12 		   */
++	DBINT day;		/* 1 - 31 		   */
++	DBINT dayofyear;	/* 1 - 366 		   */
++	DBINT week;            	/* 1 - 54 (for leap years) */
++	DBINT weekday;		/* 1 - 7 (Mon. - Sun.)     */
++	DBINT hour;		/* 0 - 23 		   */
++	DBINT minute;		/* 0 - 59 		   */
++	DBINT second;		/* 0 - 59 		   */
++	DBINT millisecond;	/* 0 - 999 		   */
++	DBINT tzone;		/* 0 - 127  (Sybase only)  */	
+ };					
+ 
+ struct tds_sybase_dbdaterec
+ {
+-	long dateyear;		/* 1900 and counting	  */ 
+-	long quarter;		/* 0 - 3 (Microsoft only) */
+-	long datemonth;		/* 0 - 11   	     	  */
+-	long datedmonth;	/* 1 - 31   	     	  */
+-	long datedyear;		/* 1 - 366  	     	  */
+-	long week;            	/* 1 - 54 (Microsoft only) */
+-	long datedweek;		/* 0 - 6    	     	  */
+-	long datehour; 		/* 0 - 23   	     	  */
+-	long dateminute;	/* 0 - 59   	     	  */
+-	long datesecond;	/* 0 - 59   	     	  */
+-	long datemsecond;	/* 0 - 997  	     	  */
+-	long datetzone;		/* 0 - 127  	     	  */
++	DBINT dateyear;		/* 1900 and counting	  */ 
++	DBINT quarter;		/* 0 - 3 (Microsoft only) */
++	DBINT datemonth;	/* 0 - 11   	     	  */
++	DBINT datedmonth;	/* 1 - 31   	     	  */
++	DBINT datedyear;	/* 1 - 366  	     	  */
++	DBINT week;            	/* 1 - 54 (Microsoft only) */
++	DBINT datedweek;	/* 0 - 6    	     	  */
++	DBINT datehour; 	/* 0 - 23   	     	  */
++	DBINT dateminute;	/* 0 - 59   	     	  */
++	DBINT datesecond;	/* 0 - 59   	     	  */
++	DBINT datemsecond;	/* 0 - 997  	     	  */
++	DBINT datetzone;	/* 0 - 127  	     	  */
+ };
+ 
+ #ifdef MSDBLIB
+
+commit a0bf919c13585a59c247529be84a70446e64c80c
+Author: jklowden <jklowden>
+Date:   Sat Feb 28 17:38:43 2009 +0000
+
+    more things to fix
+
+diff --git a/BUGS b/BUGS
+index 0468242..71bc340 100644
+--- a/BUGS
++++ b/BUGS
+@@ -11,5 +11,9 @@ Needs Fixing
+ 3. dbwritetext() and friends do not work under TDS 7.0
+ 4. There is a bug with the order of returns from ct_results() such that rows
+    affected doesn't show up in sqsh.
++5. ct-lib placeholders do not work with TDS 7.0+.  To fix 
++   this requires either an SQL parser or API modification, 
++   because the library has to determine the SQL datatype 
++   of the placeholder variable.  
+ 
+ 
+diff --git a/TODO b/TODO
+index 984895a..b18f209 100644
+--- a/TODO
++++ b/TODO
+@@ -8,12 +8,17 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.171 2008/07/17 11:52:34 freddy77 Exp $
++To Do List	$Id: TODO,v 1.172 2009/02/28 17:38:43 jklowden Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+ 	tds_send_cancel in tds_goodwrite (wrong??)
+-
++BUG: ML 2009-02-10 "Problem with Set TEXT field to NULL"
++	libtds seems to misinterpret NULL TEXT fields as 
++	zero-length strings. 
++BUG: sending ICONV charset name, not TDS name in 
++	5.0 login packet.  
++	
+ Must be fixed:
+ . ctlib parameters, handle all case even in tds7
+   . handle and test prepared query
+
+commit cc600e2bb48b5273ba11656e8545c60a2d32dd05
+Author: jklowden <jklowden>
+Date:   Sat Feb 28 17:38:50 2009 +0000
+
+    login packet debugging options
+
+diff --git a/include/tds.h b/include/tds.h
+index 1ae3dea..8f7d4b5 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.311 2009/02/07 00:26:22 jklowden Exp $ */
++/* $Id: tds.h,v 1.312 2009/02/28 17:38:50 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1069,6 +1069,7 @@ typedef enum _TDS_STATE
+ } TDS_STATE;
+ 
+ #define TDS_DBG_LOGIN   __FILE__, ((__LINE__ << 4) | 11)
++#define TDS_DBG_HEADER  __FILE__, ((__LINE__ << 4) | 10)
+ #define TDS_DBG_FUNC    __FILE__, ((__LINE__ << 4) |  7)
+ #define TDS_DBG_INFO2   __FILE__, ((__LINE__ << 4) |  6)
+ #define TDS_DBG_INFO1   __FILE__, ((__LINE__ << 4) |  5)
+@@ -1086,6 +1087,7 @@ typedef enum _TDS_STATE
+ #define TDS_DBGFLAG_SEVERE  0x02
+ #define TDS_DBGFLAG_ALL     0xfff
+ #define TDS_DBGFLAG_LOGIN   0x0800
++#define TDS_DBGFLAG_HEADER  0x0400
+ #define TDS_DBGFLAG_PID     0x1000
+ #define TDS_DBGFLAG_TIME    0x2000
+ #define TDS_DBGFLAG_SOURCE  0x4000
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 17490fa..8da8d10 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.181 2009/01/23 09:42:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.182 2009/02/28 17:38:50 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -765,9 +765,10 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	} else
+ 		packet_size += (user_name_len + password_len) * 2;
+ 
++#if !defined(TDS_DEBUG_LOGIN)
+ 	tdsdump_log(TDS_DBG_INFO2, "quietly sending TDS 7+ login packet\n");
+ 	tdsdump_off();
+-
++#endif
+ 	TDS_PUT_INT(tds, packet_size);
+ 	if (IS_TDS90(tds)) {
+ 		tds_put_n(tds, tds9Version, 4);
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 926627d..086d4eb 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.87 2009/02/27 10:11:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.88 2009/02/28 17:38:50 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -581,7 +581,7 @@ tds_read_packet(TDSSOCKET * tds)
+ 			tds->in_pos = 0;
+ 			return -1;
+ 		}
+-
++		
+ 		/* GW ADDED */
+ 		/*
+ 		 * Not sure if this is the best way to do the error
+@@ -597,6 +597,8 @@ tds_read_packet(TDSSOCKET * tds)
+ 		return -1;
+ 	}
+ 
++	tdsdump_dump_buf(TDS_DBG_HEADER, "Received header", header, sizeof(header));	
++
+ 	/* Convert our packet length from network to host byte order */
+ 	len = (((unsigned int) header[2]) << 8) | header[3];
+ 
+
+commit d4521980eb466bdf5945d4c08e348304e672f6de
+Author: jklowden <jklowden>
+Date:   Mon Mar 2 05:39:44 2009 +0000
+
+    bcp_init sets default values for host file columns if host_filename is not NULL.
+
+diff --git a/ChangeLog b/ChangeLog
+index 48941f4..56501f3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Mon Mar  2 00:09:58 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/dblib.c
++	* samples/bcp_test.cpp samples/Makefile.bcp_test
++	- bcp_init sets default values for host file columns
++	- if host_filename is not NULL.
++
+ Sat Feb 28 12:32:06 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/sybdb.h DBDATEREC members are 32-bit
+ 	* BUGS TODO more things to fix
+@@ -1354,4 +1360,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2735 2009/02/28 17:38:38 jklowden Exp $
++$Id: ChangeLog,v 1.2736 2009/03/02 05:39:44 jklowden Exp $
+diff --git a/samples/Makefile.bcp_test b/samples/Makefile.bcp_test
+new file mode 100644
+index 0000000..bef6616
+--- /dev/null
++++ b/samples/Makefile.bcp_test
+@@ -0,0 +1,12 @@
++# This file is not part of Makefile.am because the source code is C++, 
++# and FreeTDS requires only a C compiler.  
++#
++
++DBLIB_H = /usr/local
++DBLIB_L = ../build/src/dblib/.libs
++FLAGS = -D MSDBLIB -fmessage-length=$$(stty -a | awk '/^speed/ {print $$6}')
++INC = -I $(DBLIB_H)/include
++LIB = -L $(DBLIB_L) -Wl,-R$(DBLIB_L) -lsybdb
++
++bcp_test: bcp_test.cpp
++	$(CXX) -o $@ bcp_test.cpp -g -O0 $(FLAGS) $(INC) $(LIB)
+diff --git a/samples/bcp_test.cpp b/samples/bcp_test.cpp
+new file mode 100644
+index 0000000..de345de
+--- /dev/null
++++ b/samples/bcp_test.cpp
+@@ -0,0 +1,346 @@
++#ifdef _WIN32
++	#ifndef _CRT_SECURE_NO_WARNINGS
++	//	define _CRT_SECURE_NO_WARNINGS
++	#endif
++	#ifndef _WIN32_WINNT
++	#define _WIN32_WINNT 0x0400
++	#endif
++
++	#include <windows.h>
++#endif // _WIN32
++
++#include <sqlfront.h>
++#include <sqldb.h>
++
++#include <cassert>
++
++#include <iostream>
++#include <iomanip>
++#include <fstream>
++#include <sstream>
++
++using namespace std;
++
++#if defined(_INC_SQLFRONT)
++#define MSGNO_T DBINT
++#define MSGNO_LINE DBUSMALLINT
++#else
++#define MSGNO_T int
++#define MSGNO_LINE int
++#define LPCSTR char*
++#define LPCBYTE unsigned char*
++#endif	// _INC_SQLFRONT
++
++/*
++ * Classes for reading the native bcp data file
++ */
++struct counted_string : public std::string
++{};
++
++istream&
++operator>>( istream& is, counted_string& output ) 
++{
++	unsigned char len;
++	is.read( reinterpret_cast<char*>(&len), sizeof(len) );
++	streamsize nread = is.gcount();
++	assert(is.good() && nread == 1);
++	char buf[80];
++	if( sizeof(buf) <= len ){
++		cerr << "error reading counted_string at offset 0x" << hex << is.tellg() << "; "
++			 << "len = 0x" << hex << (unsigned short)len << ", should be <= 30\n";
++			 abort();  
++	}
++	nread = is.readsome( buf, len );
++	assert(len == nread);
++	buf[len] = '\0';
++	std::string& that(output);
++	that = buf;
++	return is;
++}
++
++template <typename T>
++struct number
++{
++	T datum;
++	number() : datum(0) {}
++};
++
++template <typename T>
++istream&
++operator>>( istream& is, number<T>& output ) 
++{
++	static const streamsize len(sizeof(T));
++	streamsize nread = is.readsome( reinterpret_cast<char*>(&output.datum), len );
++	assert(is.good() && len == nread);
++	return is;
++}
++
++template <typename T>
++ostream&
++operator<<( ostream& os, const number<T>& input ) 
++{
++	return os << input.datum;
++}
++
++istream&
++operator>>( istream& is, DBDATETIME& dt ) 
++{
++	streamsize nread = is.readsome( reinterpret_cast<char*>(&dt), sizeof(dt) );
++	assert(is.good() && sizeof(dt) == nread);
++	
++	return is;
++}
++
++ostream&
++operator<<( ostream& os, DBDATETIME& dt ) 
++{
++	DBDATEREC date;
++	RETCODE erc = dbdatecrack( 0, &date, &dt );
++	assert(erc == SUCCEED);
++
++	os << setfill('0') << right 
++	   << date.year 
++	   << '-' << setw(2) << (1+date.month)
++	   << '-' << setw(2) << date.day 
++	   << ' ' << setw(2) << date.hour 
++	   << ':' << setw(2) << date.minute
++	   << setfill(' ');	
++	return os;
++}
++
++/*
++ * Error and Message handlers
++ */
++int
++ErrorHandler(	PDBPROCESS	dbproc 
++			  , DBINT		severity
++			  , DBINT		dberr 
++			  , DBINT		oserr 
++			  , LPCSTR		dberrstr
++			  , LPCSTR		oserrstr
++			  )
++{
++		cerr  << "DB-Library error " << dberr << " (severity " << severity << "):\n";
++		cerr  << "dbproc:\t"		<< dbproc 			<< '\n'
++			  << "message:\t"		<< dberrstr 	<< '\n';
++		if( oserr ) {
++			cerr	<< "OS error "	<< oserr 	<< ": "	<< oserrstr << '\n';
++		}
++		return INT_CANCEL;
++}
++
++int
++MessageHandler(	  PDBPROCESS	dbproc
++				, MSGNO_T		msgno 
++				, DBINT			msgstate 
++				, DBINT			severity 
++				, LPCSTR		msgtext 
++				, LPCSTR		srvname 
++				, LPCSTR		procname 
++				, MSGNO_LINE	line 
++				)
++{
++	switch(msgno) {
++	case 5701:
++	case 5703:
++		return 0;
++	} 
++	if( msgno > 0 ) {
++		cerr	<< "Error "		<< msgno 
++				<< " (severity " << severity << ") " 
++				<< "from "		<< srvname;
++	}
++
++	if( procname )	// potentially empty, std::string()
++		cerr << ".." << procname << "(line " << line << ")";
++	cerr << '\n';
++
++	cerr	<< "dbproc:\t"		<< dbproc			<< '\n'
++		<< "message:\t"		<< msgtext 	<< '\n';
++
++	return 0;
++}
++
++/*
++ * Data and row buffer types
++ */
++struct data_t {
++	char *name;
++	short type;
++	double ftype;
++	char *date;
++} data[] = {
++	  {"AddressLine", 39, 3.9, "Feb 27 2009  2:39PM" }
++	, {"Date",        58, 5.8, "Feb 27 2009  2:39PM" }
++	, {"DateOnly",    61, 6.1, "Feb 27 2009  2:39PM" }
++	, {"Handle",      39, 3.9, "Feb 27 2009  2:39PM" }
++};
++struct buf_t : public data_t
++{
++	enum{ MAX_NAME = 32 };
++	buf_t() {
++		name = new char(MAX_NAME);
++		date = new char(MAX_NAME);
++	}
++	buf_t& operator=( const data_t& that ) {
++		assert( that.name && MAX_NAME > strlen(that.name) );
++		assert( that.date && MAX_NAME > strlen(that.date) );
++		strcpy( name, that.name );
++		strcpy( date, that.date );
++		type = that.type;
++		ftype = that.ftype;
++		return  *this;
++	}
++};
++
++static const char drop_table[] = 	"if object_id('xsystypes') is not NULL "
++									"	drop table xsystypes";
++static const char create_table[] = 	"CREATE TABLE xsystypes "
++									"	( name varchar(30)   NOT NULL "
++									"	, type int           NOT NULL "
++									"	, ftype float        NOT NULL "
++									"	, date datetime      NOT NULL "
++									"   ) ";
++
++#ifdef _WIN32
++const bool fwin32(true);
++#else
++const bool fwin32(false);
++#endif
++
++void
++execute( DBPROCESS * dbproc ) 
++{
++	RETCODE erc = dbsqlexec(dbproc);
++	assert( erc == SUCCEED );
++	
++	while( (erc = dbresults(dbproc)) != NO_MORE_RESULTS ){
++		assert( erc == SUCCEED );
++		dbprhead(dbproc);
++		while( (erc = dbnextrow(dbproc)) != NO_MORE_ROWS ) {
++			assert( erc == SUCCEED );
++			dbprrow(dbproc);
++		}
++	}
++}
++
++int main( int argc, char *argv[] ) 
++{
++	cout << "initialized DB-Library: " << dbinit() << endl;
++
++	dberrhandle(ErrorHandler);
++	dbmsghandle(MessageHandler);
++
++	LOGINREC * login = dblogin();
++	DBSETLSECURE (login);
++	BCP_SETL (login, 1);
++	
++	if( argc < 3 || argc < 5 && !fwin32 ) {
++		cerr << "syntax: " << argv[0] << " server database [user] [password]\n";
++		return 1;
++	}
++
++	const char * server = argv[1];
++	const char * dbname = argv[2];
++	const char * username = argc > 3? argv[3] : NULL;
++	const char * password = argc > 4? argv[4] : NULL;
++
++	if( username ) {
++		DBSETLUSER (login, username);
++		if( password ) 
++			DBSETLPWD (login, password);
++	} else {
++		DBSETLSECURE (login);
++	}
++
++	DBPROCESS *dbproc = dbopen( login, server );
++	assert( dbproc );
++
++	RETCODE erc = dbuse(dbproc, dbname);
++	assert( erc == SUCCEED );
++
++	/* 
++	 * Create the table "xsystypes"
++	 */
++	erc = dbcmd(dbproc, drop_table );
++	assert( erc == SUCCEED );
++	execute(dbproc);
++
++	erc = dbcmd(dbproc, "BEGIN TRANSACTION ");
++	assert( erc == SUCCEED );
++	erc = dbcmd(dbproc, create_table );
++	assert( erc == SUCCEED );
++	
++	execute(dbproc);
++	
++	/* 
++	 * Prepare to write from memory
++	 */
++	erc = bcp_init( dbproc, "xsystypes", NULL, NULL, DB_IN );
++	assert( erc == SUCCEED );
++
++	buf_t buf;
++
++	LPCBYTE null_term = (BYTE*)"";
++
++	//                      addr              pre vlen term      tlen  type       col
++	erc = bcp_bind( dbproc, (LPCBYTE) buf.name,  0, -1, null_term,  1, SQLVARCHAR, 1 );
++	assert( erc == SUCCEED );
++	erc = bcp_bind( dbproc, (LPCBYTE)&buf.type,  0, -1,  0,         0, SQLINT2, 2 );
++	assert( erc == SUCCEED );
++	erc = bcp_bind( dbproc, (LPCBYTE)&buf.ftype, 0, -1,  0,         0, SQLFLT8, 3 );
++	assert( erc == SUCCEED );
++	erc = bcp_bind( dbproc, (LPCBYTE) buf.date,  0, -1, null_term,  1, SQLVARCHAR, 4 );
++	assert( erc == SUCCEED );
++
++	/* 
++	 * Send the data.
++	 */
++	for( int i=0; i < sizeof(data)/sizeof(data[0]); i++ ) {
++		buf = data[i];
++		erc = bcp_sendrow( dbproc );
++		assert( erc == SUCCEED );
++	}
++
++	cout << bcp_done(dbproc) << " rows sent" << endl;
++
++	erc = dbcmd(dbproc, "COMMIT TRANSACTION ");
++	assert( erc == SUCCEED );
++	execute(dbproc);
++	
++	/* 
++	 * Prepare to extract the data to the file "xsystypes.dat".
++	 */
++	char datafilename[] = "xsystypes.dat";
++	erc = bcp_init( dbproc, "xsystypes", datafilename, "xsystypes.err", DB_OUT );
++	assert( erc == SUCCEED );
++	
++	DBINT nrows;
++	erc = bcp_exec( dbproc, &nrows );
++	assert( erc == SUCCEED );
++	
++	cout << nrows << " rows extracted to " << datafilename << "\n";
++
++	erc = dbcmd(dbproc, "DROP TABLE xsystypes ");
++	assert( erc == SUCCEED );
++	execute(dbproc);
++	
++	/*
++	 * Print the data file.
++	 */ 
++	ifstream datafile(datafilename);
++	assert(datafile.is_open());
++	for( int i=0; i < sizeof(data)/sizeof(data[0]); i++ ) {
++		counted_string name;
++		DBDATETIME date;
++		number<int> type;
++		number<double> ftype;
++		
++		datafile >> name >> type >> ftype >> date;
++		cout << left << setw(30) << name << '\t' << type << '\t' << ftype << '\t' << date << endl;
++	}
++	
++	return 0;
++}
++
++	
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 9303dd2..6f686f7 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.181 2009/02/26 19:04:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.182 2009/03/02 05:39:45 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -94,6 +94,57 @@ static RETCODE _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_
+ static int _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci);
+ static RETCODE _bcp_get_term_var(BYTE * pdata, BYTE * term, int term_len);
+ 
++/*
++ * "If a host file is being used ... the default data formats are as follows:
++ *
++ *  > The order, type, length and number of the columns in the host file are 
++ *    assumed to be identical to the order, type and number of the columns in the database table.
++ *  > If a given database column's data is fixed-length, 
++ *    then the host file's  data column will also be fixed-length. 
++ *  > If a given database column's data is variable-length or may contain null values, 
++ *    the host file's data column will be prefixed by 
++ *	a 4-byte length value for SYBTEXT and SYBIMAGE data types, and 
++ *	a 1-byte length value for all other types.
++ *  > There are no terminators of any kind between host file columns."
++ */
++
++static void
++init_hostfile_columns(DBPROCESS *dbproc)
++{
++	const int ncols = dbproc->bcpinfo->bindinfo->num_cols;
++	RETCODE erc;
++	int icol;
++	
++	if (ncols == 0)
++		return;
++		
++	if ((erc = bcp_columns(dbproc, ncols)) != SUCCEED) {
++		assert(erc == SUCCEED);
++		return;
++	}
++		
++	for (icol = 0; icol < ncols; icol++) {
++		const TDSCOLUMN *pcol = dbproc->bcpinfo->bindinfo->columns[icol];
++		int prefixlen = 0, termlen = 0;
++		
++		switch (pcol->column_type) {
++		case SYBTEXT:
++		case SYBIMAGE:
++			prefixlen = 4;
++			break;
++		default:
++			prefixlen = dbvarylen(dbproc, icol+1)? 1 : 0;
++		}
++		
++		erc = bcp_colfmt(dbproc, icol+1, pcol->column_type, prefixlen, pcol->column_size, NULL, termlen, icol+1);
++		
++		assert(erc == SUCCEED);
++		if (erc != SUCCEED)
++			return;
++	}
++}
++
++
+ /** 
+  * \ingroup dblib_bcp
+  * \brief Prepare for bulk copy operation on a table
+@@ -152,22 +203,6 @@ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char
+ 		return (FAIL);
+ 	}
+ 
+-	if (hfile != NULL) {
+-
+-		dbproc->hostfileinfo = calloc(1, sizeof(BCP_HOSTFILEINFO));
+-
+-		if (dbproc->hostfileinfo == NULL)
+-			goto memory_error;
+-		if ((dbproc->hostfileinfo->hostfile = strdup(hfile)) == NULL)
+-			goto memory_error;
+-
+-		if (errfile != NULL)
+-			if ((dbproc->hostfileinfo->errorfile = strdup(errfile)) == NULL)
+-				goto memory_error;
+-	} else {
+-		dbproc->hostfileinfo = NULL;
+-	}
+-
+ 	/* Allocate storage */
+ 	
+ 	dbproc->bcpinfo = calloc(1, sizeof(TDSBCPINFO));
+@@ -183,10 +218,8 @@ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char
+ 	dbproc->bcpinfo->var_cols   = 0;
+ 	dbproc->bcpinfo->bind_count = 0;
+ 
+-	if (direction == DB_IN) {
+-		TDSSOCKET *tds = dbproc->tds_socket;
+-
+-		if (tds_bcp_init(tds, dbproc->bcpinfo) == TDS_FAIL) {
++	if (1 || direction == DB_IN) {
++		if (tds_bcp_init(dbproc->tds_socket, dbproc->bcpinfo) == TDS_FAIL) {
+ 			/* TODO return proper error */
+ 			/* Attempt to use Bulk Copy with a non-existent Server table (might be why ...) */
+ 			dbperror(dbproc, SYBEBCNT, 0);
+@@ -194,6 +227,26 @@ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char
+ 		}
+ 	}
+ 
++	/* Prepare default hostfile columns */
++	
++	if (hfile == NULL) {
++		dbproc->hostfileinfo = NULL;
++		return SUCCEED;
++	}
++
++	dbproc->hostfileinfo = calloc(1, sizeof(BCP_HOSTFILEINFO));
++
++	if (dbproc->hostfileinfo == NULL)
++		goto memory_error;
++	if ((dbproc->hostfileinfo->hostfile = strdup(hfile)) == NULL)
++		goto memory_error;
++
++	if (errfile != NULL)
++		if ((dbproc->hostfileinfo->errorfile = strdup(errfile)) == NULL)
++			goto memory_error;
++
++	init_hostfile_columns(dbproc);
++
+ 	return SUCCEED;
+ 
+ memory_error:
+@@ -701,36 +754,27 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 	tds = dbproc->tds_socket;
+ 	assert(tds);
+ 
+-	if (!(hostfile = fopen(dbproc->hostfileinfo->hostfile, "w"))) {
+-		dbperror(dbproc, SYBEBCUO, errno);
+-		return FAIL;
+-	}
+-
+ 	bcpdatefmt = getenv("FREEBCP_DATEFMT");
+ 	if (!bcpdatefmt)
+ 		bcpdatefmt = "%Y-%m-%d %H:%M:%S.%z";
+ 
+ 	if (dbproc->bcpinfo->direction == DB_QUERYOUT ) {
+ 		if (tds_submit_query(tds, dbproc->bcpinfo->tablename) == TDS_FAIL) {
+-			fclose(hostfile);
+ 			return FAIL;
+ 		}
+ 	} else {
+ 		/* TODO quote if needed */
+ 		if (tds_submit_queryf(tds, "select * from %s", dbproc->bcpinfo->tablename) == TDS_FAIL) {
+-			fclose(hostfile);
+ 			return FAIL;
+ 		}
+ 	}
+ 
+ 	tdsret = tds_process_tokens(tds, &result_type, NULL, TDS_TOKEN_RESULTS);
+ 	if (tdsret == TDS_FAIL || tdsret == TDS_CANCELLED) {
+-		fclose(hostfile);
+ 		return FAIL;
+ 	}
+ 	if (!tds->res_info) {
+ 		/* TODO flush/cancel to keep consistent state */
+-		fclose(hostfile);
+ 		return FAIL;
+ 	}
+ 
+@@ -861,21 +905,27 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 		hostcol->bcp_column_data->datalen = destlen;
+ 	}
+ 
+-	/* fetch a row of data from the server */
+-
+ 	/*
+ 	 * TODO above we allocate many buffer just to convert and store 
+ 	 * to file.. avoid all that passages...
+ 	 */
+ 
+-	while (tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE) == TDS_SUCCEED) {
++	if (!(hostfile = fopen(dbproc->hostfileinfo->hostfile, "w"))) {
++		dbperror(dbproc, SYBEBCUO, errno);
++		return FAIL;
++	}
++
++	/* fetch a row of data from the server */
++
++	while (tds_process_tokens(tds, &result_type, NULL, TDS_STOPAT_ROWFMT|TDS_RETURN_DONE|TDS_RETURN_ROW|TDS_RETURN_COMPUTE) 
++		== TDS_SUCCEED) {
+ 
+ 		if (result_type != TDS_ROW_RESULT && result_type != TDS_COMPUTE_RESULT)
+ 			break;
+ 
+ 		row_of_query++;
+ 
+-		/* skip rows outside of the firstrow/lastrow range , if specified */
++		/* skip rows outside of the firstrow/lastrow range, if specified */
+ 		if (dbproc->hostfileinfo->firstrow <= row_of_query && 
+ 						      row_of_query <= MAX(dbproc->hostfileinfo->lastrow, 0x7FFFFFFF)) {
+ 
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index db40841..8db9f20 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.341 2009/02/07 00:26:22 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.342 2009/03/02 05:39:45 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1097,6 +1097,8 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbopen(%p, %s, [%s])\n", login, server, msdblib? "microsoft" : "sybase");
+ 
++	CHECK_NULP(server, dbopen, 2, 0);
++	
+ 	if ((dbproc = calloc(1, sizeof(DBPROCESS))) == NULL) {
+ 		dbperror(NULL, SYBEMEM, errno);
+ 		return NULL;
+
+commit a8cb522c0e477db5f737da99e69e65d2f685a05d
+Author: freddy77 <freddy77>
+Date:   Mon Mar 2 07:59:02 2009 +0000
+
+    add needed files to vc6 project
+
+diff --git a/ChangeLog b/ChangeLog
+index 56501f3..f89e0da 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar  2 08:58:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/msvc6/libTDS.dsp: add needed files
++
+ Mon Mar  2 00:09:58 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/bcp.c src/dblib/dblib.c
+ 	* samples/bcp_test.cpp samples/Makefile.bcp_test
+@@ -1360,4 +1363,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2736 2009/03/02 05:39:44 jklowden Exp $
++$Id: ChangeLog,v 1.2737 2009/03/02 07:59:02 freddy77 Exp $
+diff --git a/win32/msvc6/libTDS.dsp b/win32/msvc6/libTDS.dsp
+index f4f87fe..ece7627 100644
+--- a/win32/msvc6/libTDS.dsp
++++ b/win32/msvc6/libTDS.dsp
+@@ -129,6 +129,10 @@ SOURCE=..\..\src\tds\md5.c
+ # End Source File
+ # Begin Source File
+ 
++SOURCE=..\..\src\tds\hmac_md5.c
++# End Source File
++# Begin Source File
++
+ SOURCE=..\..\src\tds\mem.c
+ # End Source File
+ # Begin Source File
+@@ -201,6 +205,10 @@ SOURCE=..\..\include\md5.h
+ # End Source File
+ # Begin Source File
+ 
++SOURCE=..\..\include\hmac_md5.h
++# End Source File
++# Begin Source File
++
+ SOURCE=..\..\include\replacements.h
+ # End Source File
+ # Begin Source File
+
+commit fbaed11e887067a2354f4b19a803c6a97a155617
+Author: freddy77 <freddy77>
+Date:   Tue Mar 3 07:51:33 2009 +0000
+
+    dos2unix
+
+diff --git a/samples/bcp_test.cpp b/samples/bcp_test.cpp
+index de345de..b087d58 100644
+--- a/samples/bcp_test.cpp
++++ b/samples/bcp_test.cpp
+@@ -1,346 +1,346 @@
+-#ifdef _WIN32
+-	#ifndef _CRT_SECURE_NO_WARNINGS
+-	//	define _CRT_SECURE_NO_WARNINGS
+-	#endif
+-	#ifndef _WIN32_WINNT
+-	#define _WIN32_WINNT 0x0400
+-	#endif
+-
+-	#include <windows.h>
+-#endif // _WIN32
+-
+-#include <sqlfront.h>
+-#include <sqldb.h>
+-
+-#include <cassert>
+-
+-#include <iostream>
+-#include <iomanip>
+-#include <fstream>
+-#include <sstream>
+-
+-using namespace std;
+-
+-#if defined(_INC_SQLFRONT)
+-#define MSGNO_T DBINT
+-#define MSGNO_LINE DBUSMALLINT
+-#else
+-#define MSGNO_T int
+-#define MSGNO_LINE int
+-#define LPCSTR char*
+-#define LPCBYTE unsigned char*
+-#endif	// _INC_SQLFRONT
+-
+-/*
+- * Classes for reading the native bcp data file
+- */
+-struct counted_string : public std::string
+-{};
+-
+-istream&
+-operator>>( istream& is, counted_string& output ) 
+-{
+-	unsigned char len;
+-	is.read( reinterpret_cast<char*>(&len), sizeof(len) );
+-	streamsize nread = is.gcount();
+-	assert(is.good() && nread == 1);
+-	char buf[80];
+-	if( sizeof(buf) <= len ){
+-		cerr << "error reading counted_string at offset 0x" << hex << is.tellg() << "; "
+-			 << "len = 0x" << hex << (unsigned short)len << ", should be <= 30\n";
+-			 abort();  
+-	}
+-	nread = is.readsome( buf, len );
+-	assert(len == nread);
+-	buf[len] = '\0';
+-	std::string& that(output);
+-	that = buf;
+-	return is;
+-}
+-
+-template <typename T>
+-struct number
+-{
+-	T datum;
+-	number() : datum(0) {}
+-};
+-
+-template <typename T>
+-istream&
+-operator>>( istream& is, number<T>& output ) 
+-{
+-	static const streamsize len(sizeof(T));
+-	streamsize nread = is.readsome( reinterpret_cast<char*>(&output.datum), len );
+-	assert(is.good() && len == nread);
+-	return is;
+-}
+-
+-template <typename T>
+-ostream&
+-operator<<( ostream& os, const number<T>& input ) 
+-{
+-	return os << input.datum;
+-}
+-
+-istream&
+-operator>>( istream& is, DBDATETIME& dt ) 
+-{
+-	streamsize nread = is.readsome( reinterpret_cast<char*>(&dt), sizeof(dt) );
+-	assert(is.good() && sizeof(dt) == nread);
+-	
+-	return is;
+-}
+-
+-ostream&
+-operator<<( ostream& os, DBDATETIME& dt ) 
+-{
+-	DBDATEREC date;
+-	RETCODE erc = dbdatecrack( 0, &date, &dt );
+-	assert(erc == SUCCEED);
+-
+-	os << setfill('0') << right 
+-	   << date.year 
+-	   << '-' << setw(2) << (1+date.month)
+-	   << '-' << setw(2) << date.day 
+-	   << ' ' << setw(2) << date.hour 
+-	   << ':' << setw(2) << date.minute
+-	   << setfill(' ');	
+-	return os;
+-}
+-
+-/*
+- * Error and Message handlers
+- */
+-int
+-ErrorHandler(	PDBPROCESS	dbproc 
+-			  , DBINT		severity
+-			  , DBINT		dberr 
+-			  , DBINT		oserr 
+-			  , LPCSTR		dberrstr
+-			  , LPCSTR		oserrstr
+-			  )
+-{
+-		cerr  << "DB-Library error " << dberr << " (severity " << severity << "):\n";
+-		cerr  << "dbproc:\t"		<< dbproc 			<< '\n'
+-			  << "message:\t"		<< dberrstr 	<< '\n';
+-		if( oserr ) {
+-			cerr	<< "OS error "	<< oserr 	<< ": "	<< oserrstr << '\n';
+-		}
+-		return INT_CANCEL;
+-}
+-
+-int
+-MessageHandler(	  PDBPROCESS	dbproc
+-				, MSGNO_T		msgno 
+-				, DBINT			msgstate 
+-				, DBINT			severity 
+-				, LPCSTR		msgtext 
+-				, LPCSTR		srvname 
+-				, LPCSTR		procname 
+-				, MSGNO_LINE	line 
+-				)
+-{
+-	switch(msgno) {
+-	case 5701:
+-	case 5703:
+-		return 0;
+-	} 
+-	if( msgno > 0 ) {
+-		cerr	<< "Error "		<< msgno 
+-				<< " (severity " << severity << ") " 
+-				<< "from "		<< srvname;
+-	}
+-
+-	if( procname )	// potentially empty, std::string()
+-		cerr << ".." << procname << "(line " << line << ")";
+-	cerr << '\n';
+-
+-	cerr	<< "dbproc:\t"		<< dbproc			<< '\n'
+-		<< "message:\t"		<< msgtext 	<< '\n';
+-
+-	return 0;
+-}
+-
+-/*
+- * Data and row buffer types
+- */
+-struct data_t {
+-	char *name;
+-	short type;
+-	double ftype;
+-	char *date;
+-} data[] = {
+-	  {"AddressLine", 39, 3.9, "Feb 27 2009  2:39PM" }
+-	, {"Date",        58, 5.8, "Feb 27 2009  2:39PM" }
+-	, {"DateOnly",    61, 6.1, "Feb 27 2009  2:39PM" }
+-	, {"Handle",      39, 3.9, "Feb 27 2009  2:39PM" }
+-};
+-struct buf_t : public data_t
+-{
+-	enum{ MAX_NAME = 32 };
+-	buf_t() {
+-		name = new char(MAX_NAME);
+-		date = new char(MAX_NAME);
+-	}
+-	buf_t& operator=( const data_t& that ) {
+-		assert( that.name && MAX_NAME > strlen(that.name) );
+-		assert( that.date && MAX_NAME > strlen(that.date) );
+-		strcpy( name, that.name );
+-		strcpy( date, that.date );
+-		type = that.type;
+-		ftype = that.ftype;
+-		return  *this;
+-	}
+-};
+-
+-static const char drop_table[] = 	"if object_id('xsystypes') is not NULL "
+-									"	drop table xsystypes";
+-static const char create_table[] = 	"CREATE TABLE xsystypes "
+-									"	( name varchar(30)   NOT NULL "
+-									"	, type int           NOT NULL "
+-									"	, ftype float        NOT NULL "
+-									"	, date datetime      NOT NULL "
+-									"   ) ";
+-
+-#ifdef _WIN32
+-const bool fwin32(true);
+-#else
+-const bool fwin32(false);
+-#endif
+-
+-void
+-execute( DBPROCESS * dbproc ) 
+-{
+-	RETCODE erc = dbsqlexec(dbproc);
+-	assert( erc == SUCCEED );
+-	
+-	while( (erc = dbresults(dbproc)) != NO_MORE_RESULTS ){
+-		assert( erc == SUCCEED );
+-		dbprhead(dbproc);
+-		while( (erc = dbnextrow(dbproc)) != NO_MORE_ROWS ) {
+-			assert( erc == SUCCEED );
+-			dbprrow(dbproc);
+-		}
+-	}
+-}
+-
+-int main( int argc, char *argv[] ) 
+-{
+-	cout << "initialized DB-Library: " << dbinit() << endl;
+-
+-	dberrhandle(ErrorHandler);
+-	dbmsghandle(MessageHandler);
+-
+-	LOGINREC * login = dblogin();
+-	DBSETLSECURE (login);
+-	BCP_SETL (login, 1);
+-	
+-	if( argc < 3 || argc < 5 && !fwin32 ) {
+-		cerr << "syntax: " << argv[0] << " server database [user] [password]\n";
+-		return 1;
+-	}
+-
+-	const char * server = argv[1];
+-	const char * dbname = argv[2];
+-	const char * username = argc > 3? argv[3] : NULL;
+-	const char * password = argc > 4? argv[4] : NULL;
+-
+-	if( username ) {
+-		DBSETLUSER (login, username);
+-		if( password ) 
+-			DBSETLPWD (login, password);
+-	} else {
+-		DBSETLSECURE (login);
+-	}
+-
+-	DBPROCESS *dbproc = dbopen( login, server );
+-	assert( dbproc );
+-
+-	RETCODE erc = dbuse(dbproc, dbname);
+-	assert( erc == SUCCEED );
+-
+-	/* 
+-	 * Create the table "xsystypes"
+-	 */
+-	erc = dbcmd(dbproc, drop_table );
+-	assert( erc == SUCCEED );
+-	execute(dbproc);
+-
+-	erc = dbcmd(dbproc, "BEGIN TRANSACTION ");
+-	assert( erc == SUCCEED );
+-	erc = dbcmd(dbproc, create_table );
+-	assert( erc == SUCCEED );
+-	
+-	execute(dbproc);
+-	
+-	/* 
+-	 * Prepare to write from memory
+-	 */
+-	erc = bcp_init( dbproc, "xsystypes", NULL, NULL, DB_IN );
+-	assert( erc == SUCCEED );
+-
+-	buf_t buf;
+-
+-	LPCBYTE null_term = (BYTE*)"";
+-
+-	//                      addr              pre vlen term      tlen  type       col
+-	erc = bcp_bind( dbproc, (LPCBYTE) buf.name,  0, -1, null_term,  1, SQLVARCHAR, 1 );
+-	assert( erc == SUCCEED );
+-	erc = bcp_bind( dbproc, (LPCBYTE)&buf.type,  0, -1,  0,         0, SQLINT2, 2 );
+-	assert( erc == SUCCEED );
+-	erc = bcp_bind( dbproc, (LPCBYTE)&buf.ftype, 0, -1,  0,         0, SQLFLT8, 3 );
+-	assert( erc == SUCCEED );
+-	erc = bcp_bind( dbproc, (LPCBYTE) buf.date,  0, -1, null_term,  1, SQLVARCHAR, 4 );
+-	assert( erc == SUCCEED );
+-
+-	/* 
+-	 * Send the data.
+-	 */
+-	for( int i=0; i < sizeof(data)/sizeof(data[0]); i++ ) {
+-		buf = data[i];
+-		erc = bcp_sendrow( dbproc );
+-		assert( erc == SUCCEED );
+-	}
+-
+-	cout << bcp_done(dbproc) << " rows sent" << endl;
+-
+-	erc = dbcmd(dbproc, "COMMIT TRANSACTION ");
+-	assert( erc == SUCCEED );
+-	execute(dbproc);
+-	
+-	/* 
+-	 * Prepare to extract the data to the file "xsystypes.dat".
+-	 */
+-	char datafilename[] = "xsystypes.dat";
+-	erc = bcp_init( dbproc, "xsystypes", datafilename, "xsystypes.err", DB_OUT );
+-	assert( erc == SUCCEED );
+-	
+-	DBINT nrows;
+-	erc = bcp_exec( dbproc, &nrows );
+-	assert( erc == SUCCEED );
+-	
+-	cout << nrows << " rows extracted to " << datafilename << "\n";
+-
+-	erc = dbcmd(dbproc, "DROP TABLE xsystypes ");
+-	assert( erc == SUCCEED );
+-	execute(dbproc);
+-	
+-	/*
+-	 * Print the data file.
+-	 */ 
+-	ifstream datafile(datafilename);
+-	assert(datafile.is_open());
+-	for( int i=0; i < sizeof(data)/sizeof(data[0]); i++ ) {
+-		counted_string name;
+-		DBDATETIME date;
+-		number<int> type;
+-		number<double> ftype;
+-		
+-		datafile >> name >> type >> ftype >> date;
+-		cout << left << setw(30) << name << '\t' << type << '\t' << ftype << '\t' << date << endl;
+-	}
+-	
+-	return 0;
+-}
+-
+-	
++#ifdef _WIN32
++	#ifndef _CRT_SECURE_NO_WARNINGS
++	//	define _CRT_SECURE_NO_WARNINGS
++	#endif
++	#ifndef _WIN32_WINNT
++	#define _WIN32_WINNT 0x0400
++	#endif
++
++	#include <windows.h>
++#endif // _WIN32
++
++#include <sqlfront.h>
++#include <sqldb.h>
++
++#include <cassert>
++
++#include <iostream>
++#include <iomanip>
++#include <fstream>
++#include <sstream>
++
++using namespace std;
++
++#if defined(_INC_SQLFRONT)
++#define MSGNO_T DBINT
++#define MSGNO_LINE DBUSMALLINT
++#else
++#define MSGNO_T int
++#define MSGNO_LINE int
++#define LPCSTR char*
++#define LPCBYTE unsigned char*
++#endif	// _INC_SQLFRONT
++
++/*
++ * Classes for reading the native bcp data file
++ */
++struct counted_string : public std::string
++{};
++
++istream&
++operator>>( istream& is, counted_string& output ) 
++{
++	unsigned char len;
++	is.read( reinterpret_cast<char*>(&len), sizeof(len) );
++	streamsize nread = is.gcount();
++	assert(is.good() && nread == 1);
++	char buf[80];
++	if( sizeof(buf) <= len ){
++		cerr << "error reading counted_string at offset 0x" << hex << is.tellg() << "; "
++			 << "len = 0x" << hex << (unsigned short)len << ", should be <= 30\n";
++			 abort();  
++	}
++	nread = is.readsome( buf, len );
++	assert(len == nread);
++	buf[len] = '\0';
++	std::string& that(output);
++	that = buf;
++	return is;
++}
++
++template <typename T>
++struct number
++{
++	T datum;
++	number() : datum(0) {}
++};
++
++template <typename T>
++istream&
++operator>>( istream& is, number<T>& output ) 
++{
++	static const streamsize len(sizeof(T));
++	streamsize nread = is.readsome( reinterpret_cast<char*>(&output.datum), len );
++	assert(is.good() && len == nread);
++	return is;
++}
++
++template <typename T>
++ostream&
++operator<<( ostream& os, const number<T>& input ) 
++{
++	return os << input.datum;
++}
++
++istream&
++operator>>( istream& is, DBDATETIME& dt ) 
++{
++	streamsize nread = is.readsome( reinterpret_cast<char*>(&dt), sizeof(dt) );
++	assert(is.good() && sizeof(dt) == nread);
++	
++	return is;
++}
++
++ostream&
++operator<<( ostream& os, DBDATETIME& dt ) 
++{
++	DBDATEREC date;
++	RETCODE erc = dbdatecrack( 0, &date, &dt );
++	assert(erc == SUCCEED);
++
++	os << setfill('0') << right 
++	   << date.year 
++	   << '-' << setw(2) << (1+date.month)
++	   << '-' << setw(2) << date.day 
++	   << ' ' << setw(2) << date.hour 
++	   << ':' << setw(2) << date.minute
++	   << setfill(' ');	
++	return os;
++}
++
++/*
++ * Error and Message handlers
++ */
++int
++ErrorHandler(	PDBPROCESS	dbproc 
++			  , DBINT		severity
++			  , DBINT		dberr 
++			  , DBINT		oserr 
++			  , LPCSTR		dberrstr
++			  , LPCSTR		oserrstr
++			  )
++{
++		cerr  << "DB-Library error " << dberr << " (severity " << severity << "):\n";
++		cerr  << "dbproc:\t"		<< dbproc 			<< '\n'
++			  << "message:\t"		<< dberrstr 	<< '\n';
++		if( oserr ) {
++			cerr	<< "OS error "	<< oserr 	<< ": "	<< oserrstr << '\n';
++		}
++		return INT_CANCEL;
++}
++
++int
++MessageHandler(	  PDBPROCESS	dbproc
++				, MSGNO_T		msgno 
++				, DBINT			msgstate 
++				, DBINT			severity 
++				, LPCSTR		msgtext 
++				, LPCSTR		srvname 
++				, LPCSTR		procname 
++				, MSGNO_LINE	line 
++				)
++{
++	switch(msgno) {
++	case 5701:
++	case 5703:
++		return 0;
++	} 
++	if( msgno > 0 ) {
++		cerr	<< "Error "		<< msgno 
++				<< " (severity " << severity << ") " 
++				<< "from "		<< srvname;
++	}
++
++	if( procname )	// potentially empty, std::string()
++		cerr << ".." << procname << "(line " << line << ")";
++	cerr << '\n';
++
++	cerr	<< "dbproc:\t"		<< dbproc			<< '\n'
++		<< "message:\t"		<< msgtext 	<< '\n';
++
++	return 0;
++}
++
++/*
++ * Data and row buffer types
++ */
++struct data_t {
++	char *name;
++	short type;
++	double ftype;
++	char *date;
++} data[] = {
++	  {"AddressLine", 39, 3.9, "Feb 27 2009  2:39PM" }
++	, {"Date",        58, 5.8, "Feb 27 2009  2:39PM" }
++	, {"DateOnly",    61, 6.1, "Feb 27 2009  2:39PM" }
++	, {"Handle",      39, 3.9, "Feb 27 2009  2:39PM" }
++};
++struct buf_t : public data_t
++{
++	enum{ MAX_NAME = 32 };
++	buf_t() {
++		name = new char(MAX_NAME);
++		date = new char(MAX_NAME);
++	}
++	buf_t& operator=( const data_t& that ) {
++		assert( that.name && MAX_NAME > strlen(that.name) );
++		assert( that.date && MAX_NAME > strlen(that.date) );
++		strcpy( name, that.name );
++		strcpy( date, that.date );
++		type = that.type;
++		ftype = that.ftype;
++		return  *this;
++	}
++};
++
++static const char drop_table[] = 	"if object_id('xsystypes') is not NULL "
++									"	drop table xsystypes";
++static const char create_table[] = 	"CREATE TABLE xsystypes "
++									"	( name varchar(30)   NOT NULL "
++									"	, type int           NOT NULL "
++									"	, ftype float        NOT NULL "
++									"	, date datetime      NOT NULL "
++									"   ) ";
++
++#ifdef _WIN32
++const bool fwin32(true);
++#else
++const bool fwin32(false);
++#endif
++
++void
++execute( DBPROCESS * dbproc ) 
++{
++	RETCODE erc = dbsqlexec(dbproc);
++	assert( erc == SUCCEED );
++	
++	while( (erc = dbresults(dbproc)) != NO_MORE_RESULTS ){
++		assert( erc == SUCCEED );
++		dbprhead(dbproc);
++		while( (erc = dbnextrow(dbproc)) != NO_MORE_ROWS ) {
++			assert( erc == SUCCEED );
++			dbprrow(dbproc);
++		}
++	}
++}
++
++int main( int argc, char *argv[] ) 
++{
++	cout << "initialized DB-Library: " << dbinit() << endl;
++
++	dberrhandle(ErrorHandler);
++	dbmsghandle(MessageHandler);
++
++	LOGINREC * login = dblogin();
++	DBSETLSECURE (login);
++	BCP_SETL (login, 1);
++	
++	if( argc < 3 || argc < 5 && !fwin32 ) {
++		cerr << "syntax: " << argv[0] << " server database [user] [password]\n";
++		return 1;
++	}
++
++	const char * server = argv[1];
++	const char * dbname = argv[2];
++	const char * username = argc > 3? argv[3] : NULL;
++	const char * password = argc > 4? argv[4] : NULL;
++
++	if( username ) {
++		DBSETLUSER (login, username);
++		if( password ) 
++			DBSETLPWD (login, password);
++	} else {
++		DBSETLSECURE (login);
++	}
++
++	DBPROCESS *dbproc = dbopen( login, server );
++	assert( dbproc );
++
++	RETCODE erc = dbuse(dbproc, dbname);
++	assert( erc == SUCCEED );
++
++	/* 
++	 * Create the table "xsystypes"
++	 */
++	erc = dbcmd(dbproc, drop_table );
++	assert( erc == SUCCEED );
++	execute(dbproc);
++
++	erc = dbcmd(dbproc, "BEGIN TRANSACTION ");
++	assert( erc == SUCCEED );
++	erc = dbcmd(dbproc, create_table );
++	assert( erc == SUCCEED );
++	
++	execute(dbproc);
++	
++	/* 
++	 * Prepare to write from memory
++	 */
++	erc = bcp_init( dbproc, "xsystypes", NULL, NULL, DB_IN );
++	assert( erc == SUCCEED );
++
++	buf_t buf;
++
++	LPCBYTE null_term = (BYTE*)"";
++
++	//                      addr              pre vlen term      tlen  type       col
++	erc = bcp_bind( dbproc, (LPCBYTE) buf.name,  0, -1, null_term,  1, SQLVARCHAR, 1 );
++	assert( erc == SUCCEED );
++	erc = bcp_bind( dbproc, (LPCBYTE)&buf.type,  0, -1,  0,         0, SQLINT2, 2 );
++	assert( erc == SUCCEED );
++	erc = bcp_bind( dbproc, (LPCBYTE)&buf.ftype, 0, -1,  0,         0, SQLFLT8, 3 );
++	assert( erc == SUCCEED );
++	erc = bcp_bind( dbproc, (LPCBYTE) buf.date,  0, -1, null_term,  1, SQLVARCHAR, 4 );
++	assert( erc == SUCCEED );
++
++	/* 
++	 * Send the data.
++	 */
++	for( int i=0; i < sizeof(data)/sizeof(data[0]); i++ ) {
++		buf = data[i];
++		erc = bcp_sendrow( dbproc );
++		assert( erc == SUCCEED );
++	}
++
++	cout << bcp_done(dbproc) << " rows sent" << endl;
++
++	erc = dbcmd(dbproc, "COMMIT TRANSACTION ");
++	assert( erc == SUCCEED );
++	execute(dbproc);
++	
++	/* 
++	 * Prepare to extract the data to the file "xsystypes.dat".
++	 */
++	char datafilename[] = "xsystypes.dat";
++	erc = bcp_init( dbproc, "xsystypes", datafilename, "xsystypes.err", DB_OUT );
++	assert( erc == SUCCEED );
++	
++	DBINT nrows;
++	erc = bcp_exec( dbproc, &nrows );
++	assert( erc == SUCCEED );
++	
++	cout << nrows << " rows extracted to " << datafilename << "\n";
++
++	erc = dbcmd(dbproc, "DROP TABLE xsystypes ");
++	assert( erc == SUCCEED );
++	execute(dbproc);
++	
++	/*
++	 * Print the data file.
++	 */ 
++	ifstream datafile(datafilename);
++	assert(datafile.is_open());
++	for( int i=0; i < sizeof(data)/sizeof(data[0]); i++ ) {
++		counted_string name;
++		DBDATETIME date;
++		number<int> type;
++		number<double> ftype;
++		
++		datafile >> name >> type >> ftype >> date;
++		cout << left << setw(30) << name << '\t' << type << '\t' << ftype << '\t' << date << endl;
++	}
++	
++	return 0;
++}
++
++	
+
+commit 88d21af9567e140b6c7ecaf46925753e020240f2
+Author: freddy77 <freddy77>
+Date:   Wed Mar 4 17:41:07 2009 +0000
+
+    make dblib compile
+
+diff --git a/ChangeLog b/ChangeLog
+index f89e0da..1f55bc7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar  4 18:40:56 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: make it compile
++
+ Mon Mar  2 08:58:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/msvc6/libTDS.dsp: add needed files
+ 
+@@ -1363,4 +1366,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2737 2009/03/02 07:59:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2738 2009/03/04 17:41:07 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 8db9f20..ba50091 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.342 2009/03/02 05:39:45 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.343 2009/03/04 17:41:11 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1097,7 +1097,7 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbopen(%p, %s, [%s])\n", login, server, msdblib? "microsoft" : "sybase");
+ 
+-	CHECK_NULP(server, dbopen, 2, 0);
++	CHECK_NULP(server, "dbopen", 2, NULL);
+ 	
+ 	if ((dbproc = calloc(1, sizeof(DBPROCESS))) == NULL) {
+ 		dbperror(NULL, SYBEMEM, errno);
+
+commit 022beccee6a5ea3624ce1e513bca036f40d87395
+Author: freddy77 <freddy77>
+Date:   Wed Mar 4 17:51:25 2009 +0000
+
+    remove a warning and change style
+
+diff --git a/ChangeLog b/ChangeLog
+index 1f55bc7..4c93d8e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar  4 18:51:16 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: remove a warning and change style
++
+ Wed Mar  4 18:40:56 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: make it compile
+ 
+@@ -1366,4 +1369,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2738 2009/03/04 17:41:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2739 2009/03/04 17:51:25 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index ba50091..95ec9bb 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.343 2009/03/04 17:41:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.344 2009/03/04 17:51:25 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -5557,7 +5557,7 @@ dbdatecrack(DBPROCESS * dbproc, DBDATEREC * output, DBDATETIME * datetime)
+ 	di->datesecond = dr.second;
+ 	di->datemsecond = dr.millisecond;
+ 	/* Revert to compiled-in default if dbproc can't be used to find the runtime override. */
+-	if( dbproc && dbproc->msdblib || msdblib && !dbproc  ) {
++	if (dbproc ? dbproc->msdblib : msdblib) {
+ 		++di->quarter;
+ 		++di->datemonth;
+ 		++di->datedweek;
+
+commit a2dcaea55d04bca19bbca17ca918ad52d7885740
+Author: freddy77 <freddy77>
+Date:   Fri Mar 6 01:52:20 2009 +0000
+
+    fix putdata test for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 4c93d8e..62ff05f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar  6 02:52:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: fix putdata test for Sybase
++
+ Wed Mar  4 18:51:16 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: remove a warning and change style
+ 
+@@ -1369,4 +1372,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2739 2009/03/04 17:51:25 freddy77 Exp $
++$Id: ChangeLog,v 1.2740 2009/03/06 01:52:20 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 08314cc..a1806e2 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.231 2009/02/27 10:07:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.232 2009/03/06 01:52:20 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -2882,6 +2882,9 @@ tds_put_param_as_string(TDSSOCKET * tds, TDSPARAMINFO * params, int n)
+ 	char buf[256];
+ 	int quote = 0;
+ 
++	TDS_CHAR *save_src;
++	int converted = 0;
++
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_PARAMINFO_EXTRA(params);
+ 
+@@ -2896,7 +2899,32 @@ tds_put_param_as_string(TDSSOCKET * tds, TDSPARAMINFO * params, int n)
+ 	
+ 	if (is_blob_type(curcol->column_type))
+ 		src = ((TDSBLOB *)src)->textvalue;
+-	
++
++	save_src = src;
++
++	/* TODO I don't like copy&paste too much, see above -- freddy77 */
++	/* convert string if needed */
++	if (curcol->char_conv && curcol->char_conv->flags != TDS_ENCODING_MEMCPY) {
++		size_t output_size;
++#if 0
++		/* TODO this case should be optimized */
++		/* we know converted bytes */
++		if (curcol->char_conv->client_charset.min_bytes_per_char == curcol->char_conv->client_charset.max_bytes_per_char 
++		    && curcol->char_conv->server_charset.min_bytes_per_char == curcol->char_conv->server_charset.max_bytes_per_char) {
++			converted_size = colsize * curcol->char_conv->server_charset.min_bytes_per_char / curcol->char_conv->client_charset.min_bytes_per_char;
++
++		} else {
++#endif
++		/* we need to convert data before */
++		/* TODO this can be a waste of memory... */
++		converted = 1;
++		src = (TDS_CHAR*) tds_convert_string(tds, curcol->char_conv, src, src_len, &output_size);
++		src_len = (int) output_size;
++		if (!src)
++			/* conversion error, exit with an error */
++			return TDS_FAIL;
++	}
++
+ 	/* we could try to use only tds_convert but is not good in all cases */
+ 	switch (curcol->column_type) {
+ 	/* binary/char, do conversion in line */
+@@ -2938,6 +2966,8 @@ tds_put_param_as_string(TDSSOCKET * tds, TDSPARAMINFO * params, int n)
+ 			tds_put_string(tds, "\'", 1);
+ 		free(cr.c);
+ 	}
++	if (converted)
++		tds_convert_string_free(save_src, src);
+ 	return TDS_SUCCEED;
+ }
+ 
+
+commit c11314cdc1a02456abccea200d8a5546ed5c6c62
+Author: freddy77 <freddy77>
+Date:   Fri Mar 6 02:27:13 2009 +0000
+
+    fix genparams test for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 62ff05f..9ec3362 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar  6 03:27:07 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: fix genparams test for Sybase
++
+ Fri Mar  6 02:52:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c: fix putdata test for Sybase
+ 
+@@ -1372,4 +1375,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2740 2009/03/06 01:52:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2741 2009/03/06 02:27:13 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index a1806e2..0d094f9 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.232 2009/03/06 01:52:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.233 2009/03/06 02:27:14 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1444,10 +1444,17 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	TDSBLOB *blob = NULL;
+ 	size_t colsize, size;
+ 
++	const char *s;
++	int converted = 0;
++
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
+ 	src = curcol->column_data;
++	if (is_blob_type(curcol->column_type)) {
++		blob = (TDSBLOB *) src;
++		src = (unsigned char *) blob->textvalue;
++	}
+ 
+ 	tdsdump_log(TDS_DBG_INFO1, "tds_put_data: colsize = %d\n", (int) colsize);
+ 
+@@ -1472,52 +1479,44 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 
+ 	size = tds_fix_column_size(tds, curcol);
+ 
++	s = (char *) src;
++
++	/* convert string if needed */
++	if (curcol->char_conv && curcol->char_conv->flags != TDS_ENCODING_MEMCPY) {
++		size_t output_size;
++#if 0
++		/* TODO this case should be optimized */
++		/* we know converted bytes */
++		if (curcol->char_conv->client_charset.min_bytes_per_char == curcol->char_conv->client_charset.max_bytes_per_char 
++		    && curcol->char_conv->server_charset.min_bytes_per_char == curcol->char_conv->server_charset.max_bytes_per_char) {
++			converted_size = colsize * curcol->char_conv->server_charset.min_bytes_per_char / curcol->char_conv->client_charset.min_bytes_per_char;
++
++		} else {
++#endif
++		/* we need to convert data before */
++		/* TODO this can be a waste of memory... */
++		converted = 1;
++		s = tds_convert_string(tds, curcol->char_conv, s, colsize, &output_size);
++		colsize = (TDS_INT)output_size;
++		if (!s) {
++			/* on conversion error put a empty string */
++			/* TODO on memory failure we should compute converted size and use chunks */
++			colsize = 0;
++			converted = -1;
++		}
++	}
++
+ 	/*
+ 	 * TODO here we limit data sent with MIN, should mark somewhere
+ 	 * and inform client ??
+ 	 * Test proprietary behavior
+ 	 */
+ 	if (IS_TDS7_PLUS(tds)) {
+-		const char *s;
+-		int converted = 0;
+-
+ 		tdsdump_log(TDS_DBG_INFO1, "tds_put_data: not null param varint_size = %d\n",
+ 			    curcol->column_varint_size);
+ 
+-		if (is_blob_type(curcol->column_type)) {
+-			blob = (TDSBLOB *) src;
+-			src = (unsigned char *) blob->textvalue;
+-		}
+-		s = (char *) src;
+-
+-		/* convert string if needed */
+-		if (curcol->char_conv && curcol->char_conv->flags != TDS_ENCODING_MEMCPY) {
+-			size_t output_size;
+-#if 0
+-			/* TODO this case should be optimized */
+-			/* we know converted bytes */
+-			if (curcol->char_conv->client_charset.min_bytes_per_char == curcol->char_conv->client_charset.max_bytes_per_char 
+-			    && curcol->char_conv->server_charset.min_bytes_per_char == curcol->char_conv->server_charset.max_bytes_per_char) {
+-				converted_size = colsize * curcol->char_conv->server_charset.min_bytes_per_char / curcol->char_conv->client_charset.min_bytes_per_char;
+-
+-			} else {
+-#endif
+-			/* we need to convert data before */
+-			/* TODO this can be a waste of memory... */
+-			converted = 1;
+-			s = tds_convert_string(tds, curcol->char_conv, s, colsize, &output_size);
+-			colsize = (TDS_INT)output_size;
+-			if (!s) {
+-				/* on conversion error put a empty string */
+-				/* TODO on memory failure we should compute converted size and use chunks */
+-				colsize = 0;
+-				converted = -1;
+-			}
+-		}
+-			
+ 		switch (curcol->column_varint_size) {
+ 		case 4:	/* It's a BLOB... */
+-			blob = (TDSBLOB *) curcol->column_data;
+ 			colsize = MIN(colsize, size);
+ 			/* mssql require only size */
+ 			tds_put_int(tds, colsize);
+@@ -1566,14 +1565,11 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ #endif
+ 			tds_put_n(tds, s, colsize);
+ 		}
+-		if (converted)
+-			tds_convert_string_free((char*)src, s);
+ 	} else {
+ 		/* TODO ICONV handle charset conversions for data */
+ 		/* put size of data */
+ 		switch (curcol->column_varint_size) {
+ 		case 4:	/* It's a BLOB... */
+-			blob = (TDSBLOB *) curcol->column_data;
+ 			tds_put_byte(tds, 16);
+ 			tds_put_n(tds, blob->textptr, 16);
+ 			tds_put_n(tds, blob->timestamp, 8);
+@@ -1596,29 +1592,33 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			break;
+ 		}
+ 
++		/* conversion error, exit with an error */
++		if (converted < 0)
++			return TDS_FAIL;
++
+ 		/* put real data */
+ 		if (is_numeric_type(curcol->column_type)) {
+ 			num = (TDS_NUMERIC *) src;
+ 			tds_put_n(tds, num->array, colsize);
+-		} else if (is_blob_type(curcol->column_type)) {
+-			blob = (TDSBLOB *) src;
+-			/* FIXME ICONV handle conversion when needed */
+-			tds_put_n(tds, blob->textvalue, colsize);
++		} else if (blob) {
++			tds_put_n(tds, s, colsize);
+ 		} else {
+ #ifdef WORDS_BIGENDIAN
+ 			unsigned char buf[64];
+ 
+-			if (tds->emul_little_endian && colsize < 64) {
++			if (tds->emul_little_endian && !converted && colsize < 64) {
+ 				tdsdump_log(TDS_DBG_INFO1, "swapping coltype %d\n",
+ 					    tds_get_conversion_type(curcol->column_type, colsize));
+-				memcpy(buf, src, colsize);
++				memcpy(buf, s, colsize);
+ 				tds_swap_datatype(tds_get_conversion_type(curcol->column_type, colsize), buf);
+-				src = buf;
++				s = (char *) buf;
+ 			}
+ #endif
+-			tds_put_n(tds, src, colsize);
++			tds_put_n(tds, s, colsize);
+ 		}
+ 	}
++	if (converted)
++		tds_convert_string_free((char*)src, s);
+ 	return TDS_SUCCEED;
+ }
+ 
+
+commit 0256ec8305b4a5a00e8f72da761b6f9bb117e2cb
+Author: freddy77 <freddy77>
+Date:   Fri Mar 6 09:14:09 2009 +0000
+
+    just some comments
+
+diff --git a/ChangeLog b/ChangeLog
+index 9ec3362..a32947a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar  6 10:13:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/putdata.c: just some comments
++
+ Fri Mar  6 03:27:07 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c: fix genparams test for Sybase
+ 
+@@ -1375,4 +1378,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2741 2009/03/06 02:27:13 freddy77 Exp $
++$Id: ChangeLog,v 1.2742 2009/03/06 09:14:09 freddy77 Exp $
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index 140c069..c406487 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.16 2008/12/05 08:32:48 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.17 2009/03/06 09:14:09 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -101,6 +101,7 @@ main(int argc, char *argv[])
+ 		/* check state  and reset some possible buffers */
+ 		Command("DECLARE @i INT");
+ 
++		/* use server ntext if available */
+ 		if (sql_type == SQL_LONGVARCHAR && db_is_microsoft() && db_version_int() >= 0x08000000u) {
+ 			sql_type = SQL_WLONGVARCHAR;
+ 			continue;
+@@ -152,7 +153,7 @@ main(int argc, char *argv[])
+ 
+ 	CHKFreeStmt(SQL_RESET_PARAMS, "S");
+ 
+-	/* check inserts ... */
++	/* check inserts ... there should be all equal rows */
+ 	strcpy(sql, "IF EXISTS(SELECT * FROM #putdata WHERE CONVERT(VARBINARY(255),b) <> 0x");
+ 	/* append binary */
+ 	for (i = 0; i < 254; ++i)
+
+commit c9b62f393705d44ef511bc179aba4a81ab8e9d78
+Author: freddy77 <freddy77>
+Date:   Fri Mar 6 14:32:05 2009 +0000
+
+    fix kerberos login with no freetds.conf
+
+diff --git a/ChangeLog b/ChangeLog
+index a32947a..41b1652 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar  6 15:30:58 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: fix kerberos login with no freetds.conf
++
+ Fri Mar  6 10:13:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/putdata.c: just some comments
+ 
+@@ -1378,4 +1381,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2742 2009/03/06 09:14:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2743 2009/03/06 14:32:05 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index b361510..a7979ec 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.141 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.142 2009/03/06 14:32:12 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -1010,7 +1010,7 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 
+ 	/*
+ 	 * If we still don't have the server and port then assume the user
+-	 * typed an actual server name.
++	 * typed an actual server host name.
+ 	 */
+ 	if (!found) {
+ 		char ip_addr[255];
+@@ -1048,8 +1048,10 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 		 * lookup the host
+ 		 */
+ 		tds_lookup_host(server, ip_addr);
+-		if (ip_addr[0])
++		if (ip_addr[0]) {
++			tds_dstr_copy(&connection->server_host_name, server);
+ 			tds_dstr_copy(&connection->ip_addr, ip_addr);
++		}
+ 		if (ip_port)
+ 			connection->port = ip_port;
+ 	}
+
+commit 48596392ea18df644a34fda84f0d58777b80c071
+Author: freddy77 <freddy77>
+Date:   Fri Mar 6 17:34:26 2009 +0000
+
+    add and fix test for text
+
+diff --git a/ChangeLog b/ChangeLog
+index 41b1652..ddc36d5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Mar  6 18:34:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
++	- add and fix test for text
++
+ Fri Mar  6 15:30:58 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c: fix kerberos login with no freetds.conf
+ 
+@@ -1381,4 +1385,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2743 2009/03/06 14:32:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2744 2009/03/06 17:34:26 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 25a7041..152494e 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.79 2008/11/12 10:38:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.80 2009/03/06 17:34:31 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -155,6 +155,15 @@ odbc_wstr2str(TDS_STMT * stmt, const char *src, int* len)
+ 	return out;
+ }
+ 
++static void
++_odbc_blob_free(TDSCOLUMN *col)
++{
++        if (!col->column_data)
++                return;
++
++        TDS_ZERO_FREE(col->column_data);
++}
++
+ /**
+  * Convert parameters to libtds format
+  * @return SQL_SUCCESS, SQL_ERROR or SQL_NEED_DATA
+@@ -348,11 +357,24 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 	case XSYBNVARCHAR:
+ 	case XSYBNCHAR:
+ 	case SYBNVARCHAR:
++	case SYBNTEXT:
++	case SYBTEXT:
+ 		if (!need_data && (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR)) {
+ 			if (curcol->column_data && curcol->column_data_free)
+ 				curcol->column_data_free(curcol);
+ 			curcol->column_data_free = NULL;
+-			curcol->column_data = (TDS_UCHAR*) src;
++			if (dest_type == SYBNTEXT || dest_type == SYBTEXT) {
++				TDSBLOB *blob = (TDSBLOB *) calloc(1, sizeof(TDSBLOB));
++				if (!blob) {
++					odbc_errs_add(&stmt->errs, "HY001", NULL);
++					return SQL_ERROR;
++				}
++				blob->textvalue = src;
++				curcol->column_data = (TDS_UCHAR*) blob;
++				curcol->column_data_free = _odbc_blob_free;
++			} else {
++				curcol->column_data = (TDS_UCHAR*) src;
++			}
+ 			curcol->column_size = len;
+ 			curcol->column_cur_size = len;
+ 			return SQL_SUCCESS;
+@@ -434,8 +456,9 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		if (res > curcol->column_size)
+ 			res = curcol->column_size;
+ 		break;
+-	case SYBTEXT:
+ 	case SYBNTEXT:
++		dest_type = SYBTEXT;
++	case SYBTEXT:
+ 	case SYBLONGBINARY:
+ 	case SYBIMAGE:
+ 		res = tds_convert(dbc->env->tds_ctx, src_type, src, len, dest_type, &ores);
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 75a9483..fdcce26 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -12,13 +12,13 @@
+  * (3) numeric -> *        different format
+  * (4) *       -> numeric  take precision and scale from ipd TODO
+  * (5) *       -> char     test wide
+- * (6) *       -> blob     test wchar and ntext TODO
++ * (6) *       -> blob     test wchar and ntext
+  * (7) *       -> binary   test also with wchar TODO
+  * (8) binary  -> *        test also with wchar TODO
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.38 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.39 2009/03/06 17:34:31 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -186,7 +186,12 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 		sep = "'";
+ 		if (strncmp(expected, "0x", 2) == 0)
+ 			sep = "";
+-		sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
++		if (strcmp(param_type, "TEXT") == 0)
++			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARCHAR(255), col) = CONVERT(VARCHAR(255), %s%s%s)", sep, expected, sep);
++		else if (strcmp(param_type, "NTEXT") == 0)
++			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(NVARCHAR(2000), col) = CONVERT(NVARCHAR(2000), %s%s%s)", sep, expected, sep);
++		else
++			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+ 		Command(sbuf);
+ 
+ 		CHKFetch("S");
+@@ -218,6 +223,7 @@ AllTests(void)
+ 	precision = 38;
+ 	TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
+ 	TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");
++	TestInput(SQL_C_LONG, "INTEGER", SQL_LONGVARCHAR, "TEXT", "12345");
+ 	/* MS driver behavior for output parameters is different */
+ 	if (driver_is_freetds())
+ 		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");
+@@ -277,6 +283,7 @@ AllTests(void)
+ 
+ 	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_NUMERIC, "NUMERIC(20,3)", "765432.2 -> 765432");
+ 	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_VARCHAR, "VARCHAR(20)", "578246.234 -> 578246");
++	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_LONGVARCHAR, "TEXT", "578246.234 -> 578246");
+ 
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");
+@@ -284,9 +291,12 @@ AllTests(void)
+ 	TestInput(SQL_C_DOUBLE, "MONEY", SQL_DOUBLE, "MONEY", "123.34");
+ 
+ 	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "1EasyTest");
++	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "TEXT", "1EasyTest");
+ 	TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_VARCHAR, "VARCHAR(10)", "Test 12345");
++	TestInput(SQL_C_WCHAR, "VARCHAR(10)", SQL_LONGVARCHAR, "TEXT", "Test 12345");
+ 	/* TODO use collate in syntax if available */
+ 	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_VARCHAR, "VARCHAR(20)", "me\xf4");
++	TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "TEXT", "me\xf4");
+ 
+ 	precision = 6;
+ 	/* output from char with conversions */
+@@ -299,16 +309,23 @@ AllTests(void)
+ 		TestOutput("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "test");
+ 		/* test for invalid stream due to truncation*/
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "01234567890");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "01234567890");
+ #ifdef ENABLE_DEVELOPING
+ 		check_truncation = 1;
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "012345678901234567890");
++		check_truncation = 1;
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "012345678901234567890");
+ #endif
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "\xa3h\xf9 -> 0xA3006800f900");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "\xa3h\xf9 -> 0xA3006800f900");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "0xA3006800f900 -> \xa3h\xf9");
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WLONGVARCHAR, "NTEXT", "0xA3006800f900 -> \xa3h\xf9");
+ 
+ 		TestInput(SQL_C_LONG, "INT", SQL_WVARCHAR, "NVARCHAR(100)", "45236");
++		TestInput(SQL_C_LONG, "INT", SQL_WLONGVARCHAR, "NTEXT", "45236");
+ 
+ 		precision = 6;
+ 		TestOutput("NVARCHAR(20)", "foo test", SQL_C_CHAR, SQL_WVARCHAR, "6 foo te");
+@@ -318,9 +335,13 @@ AllTests(void)
+ 		TestOutput("NVARCHAR(20)", "0xf800f900", SQL_C_CHAR, SQL_WVARCHAR, "2 \xf8\xf9");
+ 
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest2");
++		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WLONGVARCHAR, "NTEXT", "1EasyTest2");
+ 		use_nts = 1;
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WVARCHAR, "NVARCHAR(10)", "1EasyTest3");
++		use_nts = 1;
++		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_WLONGVARCHAR, "NTEXT", "1EasyTest3");
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WVARCHAR, "NVARCHAR(3)", "0xf800a300bc06");
++		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WLONGVARCHAR, "NTEXT", "0xf800a300bc06");
+ 
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");
+ 	}
+
+commit 602db800a5d245534004cd17312b018fb264c29d
+Author: freddy77 <freddy77>
+Date:   Fri Mar 6 20:18:39 2009 +0000
+
+    fix really stupid core
+
+diff --git a/ChangeLog b/ChangeLog
+index ddc36d5..ab4b9ca 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar  6 21:18:28 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: fix really stupid core
++
+ Fri Mar  6 18:34:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c:
+ 	- add and fix test for text
+@@ -1385,4 +1388,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2744 2009/03/06 17:34:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2745 2009/03/06 20:18:39 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 0d094f9..91f59e3 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008, 2009  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.233 2009/03/06 02:27:14 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.234 2009/03/06 20:18:51 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1450,12 +1450,6 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
+-	src = curcol->column_data;
+-	if (is_blob_type(curcol->column_type)) {
+-		blob = (TDSBLOB *) src;
+-		src = (unsigned char *) blob->textvalue;
+-	}
+-
+ 	tdsdump_log(TDS_DBG_INFO1, "tds_put_data: colsize = %d\n", (int) colsize);
+ 
+ 	if (curcol->column_cur_size < 0) {
+@@ -1479,6 +1473,12 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 
+ 	size = tds_fix_column_size(tds, curcol);
+ 
++	src = curcol->column_data;
++	if (is_blob_type(curcol->column_type)) {
++		blob = (TDSBLOB *) src;
++		src = (unsigned char *) blob->textvalue;
++	}
++
+ 	s = (char *) src;
+ 
+ 	/* convert string if needed */
+
+commit 8bc7a006dc051c39629d0bbac64d7b2fcf02041c
+Author: freddy77 <freddy77>
+Date:   Mon Mar 9 17:42:24 2009 +0000
+
+    *** empty log message ***
+
+diff --git a/TODO.freddy b/TODO.freddy
+index c05e367..392c4e4 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -90,3 +90,5 @@ Rebuild all test support (virtual machines, chroot, msde+mssql2005)
+ Add a test for rpm (redhat, suse?)
+ disabling thread safety don't check for thread-safe functions
+ check cross compiled odbc driver, exports, resource version (test-dist)
++
++Test SQLBindParameter with rgbPointer == NULL (SQL_NULL_DATA)
+
+commit 82f9d78e2368441dde337116136e3b8df04b01c3
+Author: freddy77 <freddy77>
+Date:   Mon Mar 9 20:35:47 2009 +0000
+
+    add test for NULL input data
+
+diff --git a/ChangeLog b/ChangeLog
+index ab4b9ca..8e2dc85 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Mar  9 21:35:38 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy src/odbc/unittests/genparams.c:
++	- add test for NULL input data
++
+ Fri Mar  6 21:18:28 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c: fix really stupid core
+ 
+@@ -1388,4 +1392,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2745 2009/03/06 20:18:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2746 2009/03/09 20:35:47 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index 392c4e4..c05e367 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -90,5 +90,3 @@ Rebuild all test support (virtual machines, chroot, msde+mssql2005)
+ Add a test for rpm (redhat, suse?)
+ disabling thread safety don't check for thread-safe functions
+ check cross compiled odbc driver, exports, resource version (test-dist)
+-
+-Test SQLBindParameter with rgbPointer == NULL (SQL_NULL_DATA)
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index fdcce26..58a8efd 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.39 2009/03/06 17:34:31 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.40 2009/03/09 20:35:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -180,7 +180,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 			CHKExecute("SNo");
+ 	}
+ 
+-	/* check is row is present */
++	/* check if row is present */
+ 	if (!check_truncation) {
+ 		ResetStatement();
+ 		sep = "'";
+@@ -202,6 +202,58 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	Command("DROP TABLE #tmp_insert");
+ }
+ 
++/* stripped down version of TestInput for NULLs */
++static void
++NullInput(SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *param_type)
++{
++	char sbuf[1024];
++	SQLLEN out_len = SQL_NULL_DATA;
++
++	ResetStatement();
++
++	/* create a table with a column of that type */
++	ResetStatement();
++	sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s NULL)", param_type);
++	Command(sbuf);
++
++	if (use_cursors) {
++		ResetStatement();
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
++		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
++	}
++
++	/* insert data using prepared statements */
++	sprintf(sbuf, "INSERT INTO #tmp_insert VALUES(?)");
++	if (exec_direct) {
++		CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, NULL, 1, &out_len, "S");
++
++		CHKExecDirect((SQLCHAR *) sbuf, SQL_NTS, "SNo");
++	} else {
++		if (prepare_before)
++			CHKPrepare((SQLCHAR *) sbuf, SQL_NTS, "S");
++
++		CHKBindParameter(1, SQL_PARAM_INPUT, out_c_type, out_sql_type, 20, 0, NULL, 1, &out_len, "S");
++
++		if (!prepare_before)
++			CHKPrepare((SQLCHAR *) sbuf, SQL_NTS, "S");
++
++		CHKExecute("SNo");
++	}
++
++	/* check if row is present */
++	ResetStatement();
++	if (!db_is_microsoft() && strcmp(param_type, "TEXT") == 0)
++		Command("SELECT * FROM #tmp_insert WHERE col LIKE ''");
++	else
++		Command("SELECT * FROM #tmp_insert WHERE col IS NULL");
++
++	CHKFetch("S");
++	CHKFetch("No");
++	CHKMoreResults("No");
++	Command("DROP TABLE #tmp_insert");
++}
++
++
+ static int big_endian = 1;
+ 
+ static void
+@@ -216,6 +268,18 @@ AllTests(void)
+ 
+ 	printf("use_cursors %d exec_direct %d prepare_before %d\n", use_cursors, exec_direct, prepare_before);
+ 
++	/* test some NULLs */
++	NullInput(SQL_C_CHAR, SQL_VARCHAR, "VARCHAR(100)");
++	NullInput(SQL_C_CHAR, SQL_LONGVARCHAR, "TEXT");
++	NullInput(SQL_C_LONG, SQL_INTEGER, "INTEGER");
++	NullInput(SQL_C_LONG, SQL_LONGVARCHAR, "TEXT");
++	NullInput(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, "DATETIME");
++	NullInput(SQL_C_FLOAT,  SQL_REAL, "FLOAT");
++	NullInput(SQL_C_NUMERIC, SQL_LONGVARCHAR, "TEXT");
++	if (db_is_microsoft() && db_version_int() >= 0x08000000u)
++		NullInput(SQL_C_BIT, SQL_BIT, "BIT");
++	NullInput(SQL_C_DOUBLE, SQL_DOUBLE, "MONEY");
++
+ 	/* FIXME why should return 38 0 as precision and scale ?? correct ?? */
+ 	precision = 18;
+ 	TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "18 0 1 7B");
+
+commit 49cd9bdba93e68dab9c23f4771372fadb62875a9
+Author: freddy77 <freddy77>
+Date:   Mon Mar 9 20:53:53 2009 +0000
+
+    add test for binary
+
+diff --git a/ChangeLog b/ChangeLog
+index 8e2dc85..b62e5ab 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar  9 21:53:46 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy src/odbc/unittests/genparams.c: add test for binary
++
+ Mon Mar  9 21:35:38 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy src/odbc/unittests/genparams.c:
+ 	- add test for NULL input data
+@@ -1392,4 +1395,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2746 2009/03/09 20:35:47 freddy77 Exp $
++$Id: ChangeLog,v 1.2747 2009/03/09 20:53:53 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index c05e367..d84a9d4 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -48,7 +48,7 @@ ODBC SQL_C_CHAR with wide
+ Check iso8859-1 for single ??
+ test to review
+ - data.c (char -> sql_c_char) DONE
+-- genparams.c
++- genparams.c DONE
+ - getdata.c DONE
+ - putdata.c DONE
+ - blob1.c (SQLGetData test with binary -> char and between chars)
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 58a8efd..27e9fda 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -13,12 +13,12 @@
+  * (4) *       -> numeric  take precision and scale from ipd TODO
+  * (5) *       -> char     test wide
+  * (6) *       -> blob     test wchar and ntext
+- * (7) *       -> binary   test also with wchar TODO
+- * (8) binary  -> *        test also with wchar TODO
++ * (7) *       -> binary   test also with wchar
++ * (8) binary  -> *        test also with wchar
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.40 2009/03/09 20:35:47 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.41 2009/03/09 20:53:53 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -190,6 +190,8 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARCHAR(255), col) = CONVERT(VARCHAR(255), %s%s%s)", sep, expected, sep);
+ 		else if (strcmp(param_type, "NTEXT") == 0)
+ 			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(NVARCHAR(2000), col) = CONVERT(NVARCHAR(2000), %s%s%s)", sep, expected, sep);
++		else if (strcmp(param_type, "IMAGE") == 0)
++			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARBINARY(255), col) = CONVERT(VARBINARY(255), %s%s%s)", sep, expected, sep);
+ 		else
+ 			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+ 		Command(sbuf);
+@@ -349,6 +351,12 @@ AllTests(void)
+ 	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_VARCHAR, "VARCHAR(20)", "578246.234 -> 578246");
+ 	TestInput(SQL_C_NUMERIC, "NUMERIC(20,3)", SQL_LONGVARCHAR, "TEXT", "578246.234 -> 578246");
+ 
++	TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
++	TestInput(SQL_C_CHAR, "TEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
++	TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_LONGVARBINARY, "IMAGE", "4145544F -> AETO");
++	TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> 4145544F");
++	TestInput(SQL_C_BINARY, "IMAGE", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> 4145544F");
++
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");
+ 
+@@ -408,6 +416,12 @@ AllTests(void)
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(3)", SQL_WLONGVARCHAR, "NTEXT", "0xf800a300bc06");
+ 
+ 		TestInput(SQL_C_WCHAR, "NVARCHAR(10)", SQL_INTEGER, "INT", " -423785  -> -423785");
++
++		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
++		TestInput(SQL_C_CHAR, "NTEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
++
++		TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4145544F -> 4145544F");
++		TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4145544F -> 4145544F");
+ 	}
+ }
+ 
+
+commit 51a56a51b00bd3f5f92b5bc498930e48e0334a0e
+Author: freddy77 <freddy77>
+Date:   Wed Mar 11 09:07:33 2009 +0000
+
+    avoid memory corruption on out of memory
+
+diff --git a/ChangeLog b/ChangeLog
+index b62e5ab..d47e6ae 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar 11 10:07:02 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: avoid memory corruption on out of memory
++
+ Mon Mar  9 21:53:46 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy src/odbc/unittests/genparams.c: add test for binary
+ 
+@@ -1395,4 +1398,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2747 2009/03/09 20:53:53 freddy77 Exp $
++$Id: ChangeLog,v 1.2748 2009/03/11 09:07:33 freddy77 Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 6f686f7..da2a3e5 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.182 2009/03/02 05:39:45 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.183 2009/03/11 09:07:33 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -388,6 +388,7 @@ bcp_colfmt(DBPROCESS * dbproc, int host_colnum, int host_type, int host_prefixle
+ 	   int host_termlen, int table_colnum)
+ {
+ 	BCP_HOSTCOLINFO *hostcol;
++	BYTE *terminator = NULL;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "bcp_colfmt(%p, %d, %d, %d, %d, %p)\n", 
+ 		    dbproc, host_colnum, host_type, host_prefixlen, (int) host_collen, host_term);
+@@ -450,18 +451,19 @@ bcp_colfmt(DBPROCESS * dbproc, int host_colnum, int host_type, int host_prefixle
+ 	hostcol = dbproc->hostfileinfo->host_columns[host_colnum - 1];
+ 
+ 	/* TODO add precision scale and join with bcp_colfmt_ps */
+-	hostcol->host_column = host_colnum;
+-	hostcol->datatype = host_type;
+-	hostcol->prefix_len = host_prefixlen;
+-	hostcol->column_len = host_collen;
+-	if (host_term && host_termlen >= 0) {
+-		free(hostcol->terminator);
+-		if ((hostcol->terminator = malloc(host_termlen)) == NULL) {
++	if (host_term && host_termlen > 0) {
++		if ((terminator = malloc(host_termlen)) == NULL) {
+ 			dbperror(dbproc, SYBEMEM, errno);
+ 			return FAIL;
+ 		}
+-		memcpy(hostcol->terminator, host_term, host_termlen);
++		memcpy(terminator, host_term, host_termlen);
+ 	}
++	hostcol->host_column = host_colnum;
++	hostcol->datatype = host_type;
++	hostcol->prefix_len = host_prefixlen;
++	hostcol->column_len = host_collen;
++	free(hostcol->terminator);
++	hostcol->terminator = terminator;
+ 	hostcol->term_len = host_termlen;
+ 	hostcol->tab_colnum = table_colnum;
+ 
+
+commit f32273e2880520e923cc4cc0d34b88761e193f55
+Author: jklowden <jklowden>
+Date:   Mon Mar 16 03:16:39 2009 +0000
+
+    minor fixes
+
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 086d4eb..0ddd85e 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.88 2009/02/28 17:38:50 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.89 2009/03/16 03:16:39 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -667,43 +667,53 @@ tds_lastpacket(TDSSOCKET * tds)
+ 
+ /**
+  * \param tds the famous socket
+- * \param p pointer to buffer
++ * \param buffer data to send
+  * \param len bytes in buffer
+  * \param last 1 if this is the last packet, else 0
+  * \return len on success, <0 on failure
+  */
+ static int
+-tds_goodwrite(TDSSOCKET * tds, const unsigned char *p, int len, unsigned char last)
++tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned char last)
+ {
+-	int remaining = len;
+-	int nput, rc, err=0;
++	const unsigned char *p = buffer;
++	int rc;
++
++	assert(tds && buffer);
+ 
+ 	/* Fix of SIGSEGV when FD_SET() called with negative fd (Sergey A. Cherukhin, 23/09/2005) */
+ 	if (TDS_IS_SOCKET_INVALID(tds->s))
+ 		return -1;
+ 
+-	while (remaining > 0) {
++	while (p - buffer < len) {
+ 		if ((rc = tds_select(tds, TDSSELWRITE, tds->query_timeout)) > 0) {
++			size_t remaining = len - (p - buffer);
+ #ifdef USE_MSGMORE
+-			nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
++			ssize_t nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
+ 			/* In case the kernel does not support MSG_MORE, try again without it */
+ 			if (nput < 0 && errno == EINVAL && !last)
+ 				nput = send(tds->s, p, remaining, MSG_NOSIGNAL);
+ #else
+-			nput = WRITESOCKET(tds->s, p, remaining);
++			ssize_t nput = WRITESOCKET(tds->s, p, remaining);
+ #endif
+-			if (nput < 0 && sock_errno == EAGAIN)
++			if (nput > 0) {
++				p += nput;
+ 				continue;
+-			/* detect connection close */
+-			if (nput <= 0) {
+-				tdserror(tds->tds_ctx, tds, nput == 0 ? TDSESEOF : TDSEWRIT, sock_errno);
+-				tds_close_socket(tds);
+-				return -1;
+- 			}
++			}
++			
++			if (0 == nput || nput < 0 && sock_errno == EAGAIN)
++				continue;
++
++			assert(nput < 0);
++			
++			tdsdump_log(TDS_DBG_NETWORK, "send(2) failed: %d (%s)\n", sock_errno, strerror(sock_errno));
++			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
++			tds_close_socket(tds);
++			return -1;
++
+ 		} else if (rc < 0) {
+ 			if (sock_errno == EAGAIN) /* shouldn't happen, but OK, retry */
+ 				continue;
+-			tdsdump_log(TDS_DBG_NETWORK, "TDS: Write failed in tds_write_packet\nError: %d (%s)\n", err, strerror(err));
++			tdsdump_log(TDS_DBG_NETWORK, "select(2) failed: %d (%s)\n", sock_errno, strerror(sock_errno));
+ 			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
+ 			tds_close_socket(tds);
+ 			return -1;
+@@ -713,9 +723,13 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *p, int len, unsigned char la
+ 			case TDS_INT_CONTINUE:
+ 				continue;
+ 			case TDS_INT_TIMEOUT:
+-				/* FIXME we are not able to send a packet and we want to send a packet ?? */
++				/* 
++				 * "Cancel the operation ... but leave the dbproc in working condition." 
++				 * We must try to send the cancel packet, else we have to abandon the dbproc.  
++				 * If it can't be done, a harder error e.g. ECONNRESET will bubble up.  
++				 */
+ 				tds_send_cancel(tds);
+-				continue; /* fixme: or return? */
++				continue; 
+ 			default:
+ 			case TDS_INT_CANCEL:
+ 				tds_close_socket(tds);
+@@ -723,9 +737,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *p, int len, unsigned char la
+ 			}
+ 			assert(0); /* not reached */
+ 		}
+-
+-		p += nput;
+-		remaining -= nput;
++		assert(0); /* not reached */
+ 	}
+ 
+ #ifdef USE_CORK
+@@ -1307,7 +1319,7 @@ tds_push_func(gnutls_transport_ptr ptr, const void* data, size_t len)
+ 	TDSSOCKET *tds = (TDSSOCKET *) ptr;
+ #else
+ static int
+-tds_ssl_write(BIO *b, const char* data, int len)
++tds_ssl_write(BIO *b, const char* data, size_t len)
+ {
+ 	TDSSOCKET *tds = (TDSSOCKET *) b->ptr;
+ #endif
+
+commit 812d9a10d9a082753db9ba123ad8050003e12fee
+Author: freddy77 <freddy77>
+Date:   Mon Mar 16 07:49:57 2009 +0000
+
+    roll back to avoid possible core in OpenSSL code
+
+diff --git a/ChangeLog b/ChangeLog
+index d47e6ae..faac559 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar 16 08:49:25 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: roll back to avoid possible core in OpenSSL code
++
+ Wed Mar 11 10:07:02 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/bcp.c: avoid memory corruption on out of memory
+ 
+@@ -1398,4 +1401,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2748 2009/03/11 09:07:33 freddy77 Exp $
++$Id: ChangeLog,v 1.2749 2009/03/16 07:49:57 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 0ddd85e..fcc44d9 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.89 2009/03/16 03:16:39 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.90 2009/03/16 07:49:57 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -1319,7 +1319,7 @@ tds_push_func(gnutls_transport_ptr ptr, const void* data, size_t len)
+ 	TDSSOCKET *tds = (TDSSOCKET *) ptr;
+ #else
+ static int
+-tds_ssl_write(BIO *b, const char* data, size_t len)
++tds_ssl_write(BIO *b, const char* data, int len)
+ {
+ 	TDSSOCKET *tds = (TDSSOCKET *) b->ptr;
+ #endif
+
+commit e01438dd50f231055ac835e2f7d4bf94ab91f76d
+Author: freddy77 <freddy77>
+Date:   Mon Mar 16 12:18:59 2009 +0000
+
+    fix for MS ODBC
+
+diff --git a/ChangeLog b/ChangeLog
+index faac559..55ac602 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Mar 16 13:18:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c: disable buffering
++	* src/odbc/unittests/const_params.c: fix for MS ODBC
++
+ Mon Mar 16 08:49:25 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: roll back to avoid possible core in OpenSSL code
+ 
+@@ -1401,4 +1405,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2749 2009/03/16 07:49:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2750 2009/03/16 12:18:59 freddy77 Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index fd4c3c0..3c1c049 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.53 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.54 2009/03/16 12:19:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -71,6 +71,9 @@ read_login_info(void)
+ 	int len;
+ #endif
+ 
++	setbuf(stdout, NULL);
++	setbuf(stderr, NULL);
++
+ 	s1 = getenv("TDSPWDFILE");
+ 	if (s1 && s1[0])
+ 		in = fopen(s1, "r");
+diff --git a/src/odbc/unittests/const_params.c b/src/odbc/unittests/const_params.c
+index 7b9b225..dd956c2 100644
+--- a/src/odbc/unittests/const_params.c
++++ b/src/odbc/unittests/const_params.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?,123,'foo')} syntax and run */
+ 
+-static char software_version[] = "$Id: const_params.c,v 1.16 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: const_params.c,v 1.17 2009/03/16 12:19:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -39,32 +39,36 @@ main(int argc, char *argv[])
+ 
+ 	if (out1 != 7654321) {
+ 		fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
+-		exit(1);
++		return 1;
+ 	}
+ 
+ 	/* just to reset some possible buffers */
+ 	Command("DECLARE @i INT");
+ 
+-	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind,  "S");
+-	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2, "S");
+-	CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1,   0, &ind3, "S");
++	/* MS ODBC don't support empty parameters altough documented so avoid this test */
++	if (driver_is_freetds()) {
+ 
+-	/* TODO use {ts ...} for date */
+-	CHKPrepare((SQLCHAR *) "{?=call const_param(?, , '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS, "S");
++		CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind,  "S");
++		CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2, "S");
++		CHKBindParameter(3, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &out1,   0, &ind3, "S");
+ 
+-	input = 13579;
+-	ind2 = sizeof(input);
+-	out1 = output = 0xdeadbeef;
+-	CHKExecute("S");
++		/* TODO use {ts ...} for date */
++		CHKPrepare((SQLCHAR *) "{?=call const_param(?, , '2004-10-15 12:09:08', 'foo', ?)}", SQL_NTS, "S");
+ 
+-	if (out1 != 7654321) {
+-		fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
+-		exit(1);
+-	}
++		input = 13579;
++		ind2 = sizeof(input);
++		out1 = output = 0xdeadbeef;
++		CHKExecute("S");
++
++		if (out1 != 7654321) {
++			fprintf(stderr, "Invalid output %d (0x%x)\n", (int) out1, (int) out1);
++			return 1;
++		}
+ 
+-	if (output != 24680) {
+-		fprintf(stderr, "Invalid result %d (0x%x) expected 24680\n", (int) output, (int) output);
+-		exit(1);
++		if (output != 24680) {
++			fprintf(stderr, "Invalid result %d (0x%x) expected 24680\n", (int) output, (int) output);
++			return 1;
++		}
+ 	}
+ 
+ 	Command("IF OBJECT_ID('const_param') IS NOT NULL DROP PROC const_param");
+
+commit 0ef3a3d2f20497a76e0a76db8508fa59554c1656
+Author: freddy77 <freddy77>
+Date:   Mon Mar 16 20:46:20 2009 +0000
+
+    fix redefinition
+
+diff --git a/ChangeLog b/ChangeLog
+index 55ac602..ddd8c48 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Mar 16 21:46:05 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/tds_sysdep_public.h:
++	- fix redefinition (due to change on Fri Feb 27 11:46:15 CET 2009)
++
+ Mon Mar 16 13:18:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/common.c: disable buffering
+ 	* src/odbc/unittests/const_params.c: fix for MS ODBC
+@@ -1405,4 +1409,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2750 2009/03/16 12:18:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2751 2009/03/16 20:46:20 freddy77 Exp $
+diff --git a/win32/tds_sysdep_public.h b/win32/tds_sysdep_public.h
+index cc65242..e1f03f8 100644
+--- a/win32/tds_sysdep_public.h
++++ b/win32/tds_sysdep_public.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_sysdep_public_h_
+ #define _tds_sysdep_public_h_
+ 
+-static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.7 2008/11/25 22:58:29 jklowden Exp $";
++static char rcsid_tds_sysdep_public_h[] = "$Id: tds_sysdep_public.h,v 1.8 2009/03/16 20:46:20 freddy77 Exp $";
+ static void *no_unused_tds_sysdep_public_h_warn[] = { rcsid_tds_sysdep_public_h, no_unused_tds_sysdep_public_h_warn };
+ 
+ #ifdef __cplusplus
+@@ -40,10 +40,6 @@ extern "C"
+ #else
+ #define tds_sysdep_intptr_type __int64	/* 64-bit int */
+ #endif
+-typedef SOCKET TDS_SYS_SOCKET;
+-#ifndef TDS_IS_SOCKET_INVALID
+-#define TDS_IS_SOCKET_INVALID(s) ((s) == INVALID_SOCKET)
+-#endif
+ 
+ #if !defined(MSDBLIB) && !defined(SYBDBLIB)
+ #define SYBDBLIB 1
+
+commit 22a6d1d98481bdec1b4d9752b84178a8e7b175c3
+Author: freddy77 <freddy77>
+Date:   Tue Mar 17 09:05:47 2009 +0000
+
+    relax some tests
+
+diff --git a/ChangeLog b/ChangeLog
+index ddd8c48..e35535a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Mar 17 10:05:23 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c src/odbc/unittests/moreandcount.c:
++	* src/odbc/unittests/typeinfo.c:
++	- relax some tests
++
+ Mon Mar 16 21:46:05 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/tds_sysdep_public.h:
+ 	- fix redefinition (due to change on Fri Feb 27 11:46:15 CET 2009)
+@@ -1409,4 +1414,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2751 2009/03/16 20:46:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2752 2009/03/17 09:05:47 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 27e9fda..acb7ecb 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.41 2009/03/09 20:53:53 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.42 2009/03/17 09:05:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -354,8 +354,8 @@ AllTests(void)
+ 	TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
+ 	TestInput(SQL_C_CHAR, "TEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
+ 	TestInput(SQL_C_CHAR, "VARCHAR(100)", SQL_LONGVARBINARY, "IMAGE", "4145544F -> AETO");
+-	TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> 4145544F");
+-	TestInput(SQL_C_BINARY, "IMAGE", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> 4145544F");
++	TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> AETO");
++	TestInput(SQL_C_BINARY, "IMAGE", SQL_VARCHAR, "VARCHAR(20)", "0x4145544F -> AETO");
+ 
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "0");
+ 	TestInput(SQL_C_BIT, "BIT", SQL_BIT, "BIT", "1");
+@@ -420,8 +420,8 @@ AllTests(void)
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
+ 		TestInput(SQL_C_CHAR, "NTEXT", SQL_VARBINARY, "VARBINARY(20)", "4145544F -> AETO");
+ 
+-		TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4145544F -> 4145544F");
+-		TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4145544F -> 4145544F");
++		TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
++		TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
+ 	}
+ }
+ 
+diff --git a/src/odbc/unittests/moreandcount.c b/src/odbc/unittests/moreandcount.c
+index db65f84..3828288 100644
+--- a/src/odbc/unittests/moreandcount.c
++++ b/src/odbc/unittests/moreandcount.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults and SQLRowCount on batch */
+ 
+-static char software_version[] = "$Id: moreandcount.c,v 1.17 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: moreandcount.c,v 1.18 2009/03/17 09:05:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -65,7 +65,8 @@ DoTest(int prepare)
+ 	CHECK_COLS(1);
+ 	if (prepare) {
+ 		/* collapse 2 recordset... after a lot of testing this is the behavior! */
+-		CHECK_ROWS(2);
++		if (driver_is_freetds())
++			CHECK_ROWS(2);
+ 	} else {
+ 		CHECK_ROWS(1);
+ 		CHKMoreResults("S");
+diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c
+index b716b65..7a28c61 100644
+--- a/src/odbc/unittests/typeinfo.c
++++ b/src/odbc/unittests/typeinfo.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: typeinfo.c,v 1.12 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: typeinfo.c,v 1.13 2009/03/17 09:05:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -49,6 +49,7 @@ CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int l
+ 	SQLLEN ind;
+ 	SQLRETURN RetCode;
+ 
++	printf("CheckType %d\n", line);
+ 	CHKBindCol(2, SQL_C_SSHORT, &out_type, 0, &ind, "SI");
+ 	CHKGetTypeInfo(type, "SI");
+ 	RetCode = CHKFetch("SNo");
+@@ -87,17 +88,22 @@ DoTest(int version3)
+ 	SQLINTEGER col_size, min_scale;
+ 	SQLLEN ind1, ind2, ind3, ind4, ind5, ind6;
+ 	int date_time_supported = 0;
++	int name_version3;
+ 
+ 	use_odbc_version3 = version3;
++	name_version3 = version3;
+ 	Connect();
+ 
+ 	printf("Using ODBC version %d\n", version3 ? 3 : 2);
+ 
+ 	/* test column name */
++	/* MS ODBC use always ODBC 3 names even in ODBC 2 mode */
++	if (!driver_is_freetds())
++		name_version3 = 1;
+ 	CHKGetTypeInfo(SQL_ALL_TYPES, "SI");
+ 	TestName(1, "TYPE_NAME");
+ 	TestName(2, "DATA_TYPE");
+-	TestName(3, version3 ? "COLUMN_SIZE" : "PRECISION");
++	TestName(3, name_version3 ? "COLUMN_SIZE" : "PRECISION");
+ 	TestName(4, "LITERAL_PREFIX");
+ 	TestName(5, "LITERAL_SUFFIX");
+ 	TestName(6, "CREATE_PARAMS");
+@@ -105,8 +111,8 @@ DoTest(int version3)
+ 	TestName(8, "CASE_SENSITIVE");
+ 	TestName(9, "SEARCHABLE");
+ 	TestName(10, "UNSIGNED_ATTRIBUTE");
+-	TestName(11, version3 ? "FIXED_PREC_SCALE" : "MONEY");
+-	TestName(12, version3 ? "AUTO_UNIQUE_VALUE" : "AUTO_INCREMENT");
++	TestName(11, name_version3 ? "FIXED_PREC_SCALE" : "MONEY");
++	TestName(12, name_version3 ? "AUTO_UNIQUE_VALUE" : "AUTO_INCREMENT");
+ 	TestName(13, "LOCAL_TYPE_NAME");
+ 	TestName(14, "MINIMUM_SCALE");
+ 	TestName(15, "MAXIMUM_SCALE");
+@@ -132,10 +138,20 @@ DoTest(int version3)
+ 
+ 	CHECK_TYPE(SQL_DATE, date_time_supported && !version3 ? SQL_DATE : SQL_UNKNOWN_TYPE);
+ 	CHECK_TYPE(SQL_TIME, date_time_supported && !version3 ? SQL_TIME : SQL_UNKNOWN_TYPE);
+-	CHECK_TYPE(SQL_TYPE_DATE, date_time_supported && version3 ? SQL_TYPE_DATE : SQL_UNKNOWN_TYPE);
+-	CHECK_TYPE(SQL_TYPE_TIME, date_time_supported && version3 ? SQL_TYPE_TIME : SQL_UNKNOWN_TYPE);
+-	CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_UNKNOWN_TYPE : SQL_TIMESTAMP);
+-	CHECK_TYPE(SQL_TYPE_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_UNKNOWN_TYPE);
++	/* MS ODBC returns S1004 (HY004), TODO support it */
++	if (driver_is_freetds() || version3) {
++		CHECK_TYPE(SQL_TYPE_DATE, date_time_supported && version3 ? SQL_TYPE_DATE : SQL_UNKNOWN_TYPE);
++		CHECK_TYPE(SQL_TYPE_TIME, date_time_supported && version3 ? SQL_TYPE_TIME : SQL_UNKNOWN_TYPE);
++	}
++	/* TODO MS ODBC handle SQL_TIMESTAMP even for ODBC 3 */
++	if (driver_is_freetds())
++		CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_UNKNOWN_TYPE : SQL_TIMESTAMP);
++	else
++		CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP);
++	/* MS ODBC returns S1004 (HY004), TODO support it */
++	if (driver_is_freetds() || version3) {
++		CHECK_TYPE(SQL_TYPE_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_UNKNOWN_TYPE);
++	}
+ 
+ 	/* TODO implement this part of test */
+ 	/* varchar/nvarchar before sysname */
+
+commit 22789cf285dada349c955a2aed2827cfd6998094
+Author: freddy77 <freddy77>
+Date:   Tue Mar 17 13:34:37 2009 +0000
+
+    fix distribution
+
+diff --git a/ChangeLog b/ChangeLog
+index e35535a..4fb20e9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Mar 17 14:34:15 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/Makefile.am: fix distribution
++
+ Tue Mar 17 10:05:23 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c src/odbc/unittests/moreandcount.c:
+ 	* src/odbc/unittests/typeinfo.c:
+@@ -1414,4 +1417,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2752 2009/03/17 09:05:47 freddy77 Exp $
++$Id: ChangeLog,v 1.2753 2009/03/17 13:34:37 freddy77 Exp $
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index add1189..3fec4e6 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.47 2009/02/11 14:40:15 freddy77 Exp $
++# $Id: Makefile.am,v 1.48 2009/03/17 13:34:39 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -18,7 +18,7 @@ SQL_DIST = 	bcp.sql dbmorecmds.sql done_handling.sql rpc.sql \
+ 		t0011.sql t0012.sql t0013.sql t0014.sql t0015.sql t0016.sql t0017.sql t0018.sql \
+ 		t0020.sql t0022.sql t0023.sql text_buffer.sql timeout.sql
+ 
+-nodist_bin_SCRIPTS	= $(SQL_DIST)
++noinst_SCRIPTS	= $(SQL_DIST)
+ 
+ t0001_SOURCES	=	t0001.c common.c common.h t0001.sql
+ t0002_SOURCES	=	t0002.c common.c common.h
+@@ -61,7 +61,7 @@ else
+ AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+ LIBS		=	../libsybdb.la ../../replacements/libreplacements.la @NETWORK_LIBS@
+-EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32) 
++EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32) $(SQL_DIST)
+ CLEANFILES	=	tdsdump.out t0013.out t0014.out t0016.out \
+ 				t0016.err t0017.err t0017.out
+ 
+
+commit e211c1bb269498942db0cbb6d284524951fc05f2
+Author: freddy77 <freddy77>
+Date:   Thu Mar 19 13:11:41 2009 +0000
+
+    make dblib tests compile with ms dblib
+
+diff --git a/ChangeLog b/ChangeLog
+index 4fb20e9..fcf10ee 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Thu Mar 19 14:11:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/dblib/unittests/common.h:
++	* src/dblib/unittests/null.c src/dblib/unittests/t0021.c:
++	* misc/prepare_win32.sh:
++	- make dblib tests compile with ms dblib
++
+ Tue Mar 17 14:34:15 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/Makefile.am: fix distribution
+ 
+@@ -1417,4 +1423,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2753 2009/03/17 13:34:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2754 2009/03/19 13:11:41 freddy77 Exp $
+diff --git a/misc/prepare_win32.sh b/misc/prepare_win32.sh
+new file mode 100755
+index 0000000..5e8e1e1
+--- /dev/null
++++ b/misc/prepare_win32.sh
+@@ -0,0 +1,325 @@
++#!/bin/bash
++
++# these commands prepare for win32 distribution
++
++errore() {
++	echo $* >&2
++	exit 1
++}
++
++NTWDBLIB=no
++TYPE=win32
++ARCHIVE='tar jcvf "freetds-$PACKAGE_VERSION.$TYPE.tar.bz2" "freetds-$PACKAGE_VERSION"'
++for param
++do
++	case $param in
++	--win64)
++		HOST=x86_64-pc-mingw32
++		TYPE=win64
++		;;
++	--zip)
++		ARCHIVE='zip -r9 "freetds-$PACKAGE_VERSION.$TYPE.zip" "freetds-$PACKAGE_VERSION"'
++		;;
++	--gzip)
++		ARCHIVE='tar zcvf "freetds-$PACKAGE_VERSION.$TYPE.tar.gz" "freetds-$PACKAGE_VERSION"'
++		;;
++	--ntwdblib)
++		NTWDBLIB=yes
++		;;
++	--help)
++		echo "Usage: $0 [OPTION]..."
++		echo '  --help          this help'
++		echo '  --win64         compile for win64'
++		echo '  --zip           compress with zip'
++		echo '  --gzip          compress with gzip'
++		echo '  --ntwdblib      use ntwdblib instead of our'
++		exit 0
++		;;
++	*)
++		echo 'Option not supported! Try --help' 1>&2
++		exit 1
++		;;
++	esac
++done
++
++if test "$TYPE" = "win32"; then
++	HOST=i386-mingw32
++	if ! $HOST-gcc --help > /dev/null 2> /dev/null; then
++		HOST=i586-mingw32msvc
++	fi
++fi
++
++PACKAGE_VERSION=
++eval `grep '^PACKAGE_VERSION=' configure`
++if test "$PACKAGE_VERSION" = ""; then
++	VERSION=
++	eval `grep '^ \?VERSION=' configure`
++	PACKAGE_VERSION="$VERSION"
++fi
++test "$PACKAGE_VERSION" != "" || errore "PACKAGE_VERSION not found"
++test -r "freetds-$PACKAGE_VERSION.tar.gz" || make dist
++test -r "freetds-$PACKAGE_VERSION.tar.gz" || errore "package not found"
++rm -rf "freetds-$PACKAGE_VERSION"
++tar zxvf "freetds-$PACKAGE_VERSION.tar.gz"
++cd "freetds-$PACKAGE_VERSION" || errore "Directory not found"
++
++if ! $HOST-gcc --help > /dev/null 2> /dev/null; then
++	echo $HOST-gcc not found >&2
++	exit 1
++fi
++
++# build
++trap 'echo Error at line $LINENO' ERR
++set -e
++CFLAGS='-O2 -g -pipe' ./configure --host=$HOST --build=i686-pc-linux-gnu
++cp libtool libtool.tmp
++cat libtool.tmp | sed -e 's,file format pe-i386,file format pe-(x86-64|i386),' > libtool
++make -j4 2> errors.txt
++TESTS_ENVIRONMENT=true make -j4 check 2>> errors.txt
++
++# compile dblib test against MS dblib
++if test "$NTWDBLIB" = "yes"; then
++	cd src/dblib
++	# generate new libsybdb.dll.a
++	[ -f .libs/libsybdb.dll.a ] || errore "library libsybdb.dll.a not found"
++
++	# replace libsybdb.dll.a
++	cat > ntwdblib.def <<"_EOF"
++EXPORTS
++SQLDebug
++abort_xact
++bcpDefaultPrefix
++bcp_batch
++bcp_bind
++bcp_colfmt
++bcp_collen
++bcp_colptr
++bcp_columns
++bcp_control
++bcp_done
++bcp_exec
++bcp_init
++bcp_moretext
++bcp_readfmt
++bcp_sendrow
++bcp_setl
++bcp_writefmt
++build_xact_string
++close_commit
++commit_xact
++dbadata
++dbadlen
++dbaltbind
++dbaltcolid
++dbaltlen
++dbaltop
++dbalttype
++dbaltutype
++dbanullbind
++dbbcmd
++dbbind
++dbbylist
++dbcancel
++dbcanquery
++dbchange
++dbclose
++dbclrbuf
++dbclropt
++dbcmd
++dbcmdrow
++dbcolbrowse
++dbcolinfo
++dbcollen
++dbcolname
++dbcolntype
++dbcolsource
++dbcoltype
++dbcolutype
++dbconnectionread
++dbconvert
++dbcount
++dbcurcmd
++dbcurrow
++dbcursor
++dbcursorbind
++dbcursorclose
++dbcursorcolinfo
++dbcursorfetch
++dbcursorfetchex
++dbcursorinfo
++dbcursorinfoex
++dbcursoropen
++dbdata
++dbdataready
++dbdatecrack
++dbdatlen
++dbdead
++dbenlisttrans
++dbenlistxatrans
++dberrhandle
++dbexit
++dbfcmd
++dbfirstrow
++dbfreebuf
++dbfreelogin
++dbfreequal
++dbgetchar
++dbgetmaxprocs
++dbgetoff
++dbgetpacket
++dbgetrow
++dbgettime
++dbgetuserdata
++dbhasretstat
++dbinit
++dbisavail
++dbiscount
++dbisopt
++dblastrow
++dblocklib
++dblogin
++dbmorecmds
++dbmoretext
++dbmsghandle
++dbname
++dbnextrow
++dbnullbind
++dbnumalts
++dbnumcols
++dbnumcompute
++dbnumorders
++dbnumrets
++dbopen
++dbordercol
++dbprhead
++dbprocerrhandle
++dbprocinfo
++dbprocmsghandle
++dbprrow
++dbprtype
++dbqual
++dbreadpage
++dbreadtext
++dbresults
++dbretdata
++dbretlen
++dbretname
++dbretstatus
++dbrettype
++dbrows
++dbrowtype
++dbrpcexec
++dbrpcinit
++dbrpcparam
++dbrpcsend
++dbrpwclr
++dbrpwset
++dbserverenum
++dbsetavail
++dbsetlname
++dbsetlogintime
++dbsetlpacket
++dbsetmaxprocs
++dbsetnull
++dbsetopt
++dbsettime
++dbsetuserdata
++dbsqlexec
++dbsqlok
++dbsqlsend
++dbstrcpy
++dbstrlen
++dbtabbrowse
++dbtabcount
++dbtabname
++dbtabsource
++dbtsnewlen
++dbtsnewval
++dbtsput
++dbtxptr
++dbtxtimestamp
++dbtxtsnewval
++dbtxtsput
++dbunlocklib
++dbupdatetext
++dbuse
++dbvarylen
++dbwillconvert
++dbwinexit
++dbwritepage
++dbwritetext
++open_commit
++remove_xact
++start_xact
++stat_xact
++_EOF
++	$HOST-dlltool --dllname ntwdblib.dll --input-def ntwdblib.def --output-lib .libs/libsybdb.dll.a
++	cd ../..
++
++	# replace includes
++	cd include
++	rm -f dblib.h sqldb.h sqlfront.h sybdb.h syberror.h sybfront.h
++	cp $HOME/cpp/freetds/dblib/sqldb.h sqldb.h
++	cp $HOME/cpp/freetds/dblib/sqlfront.h sqlfront.h
++	cd ..
++
++	# rebuild tests
++	cd src/dblib/unittests
++	rm -f *.o *.exe
++	make clean
++	perl -pi.orig -e '$_ =~ s/$/ -DDBNTWIN32/ if (/^CPPFLAGS\s*=/)' Makefile
++	TESTS_ENVIRONMENT=true make -j4 check 2>> ../../../errors.txt
++	cd ../../..
++fi
++cat errors.txt | grep -v '^.libs/lt-\|^mkdir: cannot create directory ..libs.: File exists$' | perl -ne 'if (/visibility attribute not supported in this configuration/) {$ignore=1;$_=""} else {$ignore=0} ; print $old if !$ignore; $old=$_; END { print $old }' > ../${TYPE}_errors.txt
++rm errors.txt
++
++rm -rf include doc
++find -name Makefile.in  |xargs rm
++find -name \*.in  | grep -v 'unittests\|PWD' | xargs rm
++find \( -type f -o -type l \) -a \( ! -name \*.bat -a ! -name \*.exe -a ! -name \*.def -a ! -name \*.dll -a ! -name \*.be -a ! -name \*.conf -a ! -name \*.exp -a ! -name \*.bin -a ! -name \*.in \) | xargs rm
++
++find -name \*.exe | grep '/\.libs/' | while read X; do mv "${X%/.libs/*}/.libs/${X#*/.libs/}" "${X%/.libs/*}/${X#*/.libs/}"; done
++find -type d -exec rmdir {} \; 2> /dev/null || true
++find src -name .libs -type d | while read X; do mv "$X"/* "${X%/.libs}"; done
++# copy dll inside unitests directories
++find src -name \*.dll | while read X; do D=${X%/*}; test -d "$D/unittests" && cp $X "$D/unittests"; mv $X src/apps; done
++mv src/apps/libtdsodbc-0.dll win32/FreeTDS.dll
++sed 's,Debug\\,,' < win32/installfreetds.bat > win32/installfreetds.bat.new && mv -f win32/installfreetds.bat.new win32/installfreetds.bat
++
++# remove empty directories
++find -type d -exec rmdir {} \; 2> /dev/null || true
++find -type d -exec rmdir {} \; 2> /dev/null || true
++find -type d -exec rmdir {} \; 2> /dev/null || true
++
++# strip any dll or exe
++find -name \*.dll | xargs $HOST-strip
++find -name \*.exe | xargs $HOST-strip
++
++echo '@echo off
++del err.txt ok.txt
++for %%f in (*.exe) do call :processa %%f
++goto fine
++
++:processa
++echo processing %1 ...
++echo start test %1>out.txt
++set OK=1
++%1 >> out.txt 2>&1
++if errorlevel 1 set OK=0
++echo ok %OK%
++echo end test %1>>out.txt
++echo.>>out.txt
++echo.>>out.txt
++echo.>>out.txt
++echo.>>out.txt
++
++if "%OK%"=="0" type out.txt >> err.txt
++if "%OK%"=="1" type out.txt >> ok.txt
++
++:fine
++' > src/odbc/unittests/go.bat
++unix2dos src/odbc/unittests/go.bat
++
++cd ..
++eval "$ARCHIVE"
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 2dbad1c..fc158ff 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -12,11 +12,9 @@
+ #include <sys/param.h>
+ #endif /* HAVE_SYS_PARAM_H */
+ 
+-#ifndef DBNTWIN32
+ #include "replacements.h"
+-#endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.29 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.30 2009/03/19 13:11:41 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -353,7 +351,7 @@ syb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, cha
+ 	if (dbproc != NULL) {
+ 		pexpected_msgno = (int *) dbgetuserdata(dbproc);
+ 		if (pexpected_msgno && *pexpected_msgno == msgno) {
+-			fprintf(stdout, "OK: anticipated message arrived: %d %s\n", msgno, msgtext);
++			fprintf(stdout, "OK: anticipated message arrived: %d %s\n", (int) msgno, msgtext);
+ 			*pexpected_msgno = 0;
+ 			return 0;
+ 		}
+diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h
+index b0d2e6a..1f5bcb5 100644
+--- a/src/dblib/unittests/common.h
++++ b/src/dblib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.17 2009/02/27 15:52:48 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.18 2009/03/19 13:11:41 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #if HAVE_CONFIG_H
+@@ -23,6 +23,10 @@ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_wa
+ 
+ #ifdef DBNTWIN32
+ #include <windows.h>
++/* fix MingW missing declare */
++#ifndef _WINDOWS_
++#define _WINDOWS_ 1
++#endif
+ #endif
+ 
+ #include <sqlfront.h>
+diff --git a/src/dblib/unittests/null.c b/src/dblib/unittests/null.c
+index 7563bec..b657b19 100644
+--- a/src/dblib/unittests/null.c
++++ b/src/dblib/unittests/null.c
+@@ -7,9 +7,11 @@
+ 
+ #include <unistd.h>
+ 
+-static char software_version[] = "$Id: null.c,v 1.7 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: null.c,v 1.8 2009/03/19 13:11:41 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++#ifndef DBNTWIN32
++
+ static DBPROCESS *dbproc = NULL;
+ static int failed = 0;
+ 
+@@ -181,4 +183,11 @@ main(int argc, char **argv)
+ 
+ 	return failed ? 1 : 0;
+ }
++#else
++int main(void)
++{
++	fprintf(stderr, "Not supported by MS DBLib\n");
++	return 0;
++}
++#endif
+ 
+diff --git a/src/dblib/unittests/t0021.c b/src/dblib/unittests/t0021.c
+index 2c6bac9..cfc7738 100644
+--- a/src/dblib/unittests/t0021.c
++++ b/src/dblib/unittests/t0021.c
+@@ -5,10 +5,10 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0021.c,v 1.14 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0021.c,v 1.15 2009/03/19 13:11:41 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-
++#ifndef DBNTWIN32
+ 
+ int failed = 0;
+ 
+@@ -62,3 +62,10 @@ main(int argc, char **argv)
+ 	fprintf(stdout, "%s %s\n", __FILE__, (failed ? "failed!" : "OK"));
+ 	return failed ? 1 : 0;
+ }
++#else
++int main(void)
++{
++	fprintf(stderr, "Not supported by MS DBLib\n");
++	return 0;
++}
++#endif
+
+commit 04b3dba2cd52ec87dcaedc3146f091aa4e28751f
+Author: freddy77 <freddy77>
+Date:   Thu Mar 19 13:13:21 2009 +0000
+
+    support addition in commit script
+
+diff --git a/ChangeLog b/ChangeLog
+index fcf10ee..3a42a91 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Mar 19 14:13:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/commit: support file addition
++
+ Thu Mar 19 14:11:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c src/dblib/unittests/common.h:
+ 	* src/dblib/unittests/null.c src/dblib/unittests/t0021.c:
+@@ -1423,4 +1426,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2754 2009/03/19 13:11:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2755 2009/03/19 13:13:21 freddy77 Exp $
+diff --git a/misc/commit b/misc/commit
+index 77afdf8..7dda164 100755
+--- a/misc/commit
++++ b/misc/commit
+@@ -1,6 +1,6 @@
+ #!/usr/bin/perl
+ 
+-# $Id: commit,v 1.3 2008/12/20 19:13:41 freddy77 Exp $
++# $Id: commit,v 1.4 2009/03/19 13:13:21 freddy77 Exp $
+ 
+ use strict;
+ 
+@@ -20,7 +20,7 @@ die("cvs commit message required\n") if $cvsMessage eq '';
+ die('setting local') if $?;
+ 
+ # extract file changed
+-open(CHANGES, 'cvs diff 2> /dev/null | lsdiff |') or die('getting files changed');
++open(CHANGES, 'cvs diff -N 2> /dev/null | lsdiff |') or die('getting files changed');
+ my %changes;
+ while(<CHANGES>) {
+ 	chomp;
+
+commit 21200e98cdd8824c80cb4f5c641915ff9030e3a7
+Author: freddy77 <freddy77>
+Date:   Thu Mar 19 13:36:46 2009 +0000
+
+    include sql scripts
+
+diff --git a/ChangeLog b/ChangeLog
+index 3a42a91..53c3f51 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Mar 19 14:36:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/prepare_win32.sh: include sql files
++
+ Thu Mar 19 14:13:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/commit: support file addition
+ 
+@@ -1426,4 +1429,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2755 2009/03/19 13:13:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2756 2009/03/19 13:36:46 freddy77 Exp $
+diff --git a/misc/prepare_win32.sh b/misc/prepare_win32.sh
+index 5e8e1e1..72b7a75 100755
+--- a/misc/prepare_win32.sh
++++ b/misc/prepare_win32.sh
+@@ -277,7 +277,7 @@ rm errors.txt
+ rm -rf include doc
+ find -name Makefile.in  |xargs rm
+ find -name \*.in  | grep -v 'unittests\|PWD' | xargs rm
+-find \( -type f -o -type l \) -a \( ! -name \*.bat -a ! -name \*.exe -a ! -name \*.def -a ! -name \*.dll -a ! -name \*.be -a ! -name \*.conf -a ! -name \*.exp -a ! -name \*.bin -a ! -name \*.in \) | xargs rm
++find \( -type f -o -type l \) -a \( ! -name \*.bat -a ! -name \*.exe -a ! -name \*.def -a ! -name \*.dll -a ! -name \*.be -a ! -name \*.conf -a ! -name \*.exp -a ! -name \*.bin -a ! -name \*.in -a ! -name \*.sql \) | xargs rm
+ 
+ find -name \*.exe | grep '/\.libs/' | while read X; do mv "${X%/.libs/*}/.libs/${X#*/.libs/}" "${X%/.libs/*}/${X#*/.libs/}"; done
+ find -type d -exec rmdir {} \; 2> /dev/null || true
+
+commit 9d93e9dfcfbbdab2b4b946acbd0b786086f7d1d1
+Author: freddy77 <freddy77>
+Date:   Thu Mar 19 15:09:55 2009 +0000
+
+    fix some problems under win32
+
+diff --git a/ChangeLog b/ChangeLog
+index 53c3f51..76f7e67 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Mar 19 16:09:30 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/replacements/basename.c:
++	- fix some problems under win32
++
+ Thu Mar 19 14:36:34 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/prepare_win32.sh: include sql files
+ 
+@@ -1429,4 +1433,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2756 2009/03/19 13:36:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2757 2009/03/19 15:09:55 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index fc158ff..cc5549d 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.30 2009/03/19 13:11:41 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.31 2009/03/19 15:09:56 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -111,6 +111,10 @@ read_login_info(int argc, char **argv)
+ 	struct { char *username, *password, *servername, *database; char fverbose; } options;
+ 	
+ 	BASENAME = tds_basename((char *)argv[0]);
++#ifdef WIN32
++	s1 = strrchr(BASENAME, '.');
++	if (s1) *s1 = 0;
++#endif
+ 	DIRNAME = dirname((char *)argv[0]);
+ 	
+ 	memset(&options, 0, sizeof(options));
+diff --git a/src/replacements/basename.c b/src/replacements/basename.c
+index a36088d..3dfe522 100644
+--- a/src/replacements/basename.c
++++ b/src/replacements/basename.c
+@@ -30,7 +30,13 @@
+ 
+ #if ! HAVE_BASENAME
+ 
+-TDS_RCSID(var, "$Id: basename.c,v 1.3 2008/10/02 08:08:00 freddy77 Exp $");
++TDS_RCSID(var, "$Id: basename.c,v 1.4 2009/03/19 15:09:56 freddy77 Exp $");
++
++#ifdef WIN32
++#define TDS_ISDIR_SEPARATOR(c) ((c) == '/' || (c) == '\\')
++#else
++#define TDS_ISDIR_SEPARATOR(c) ((c) == '/')
++#endif
+ 
+ char *tds_basename(char *path)
+ {
+@@ -39,12 +45,19 @@ char *tds_basename(char *path)
+ 	if (path == NULL)
+ 		return path;
+ 
+-	for (p = path + strlen(path); --p > path && *p == '/';)
++	/* remove trailing directories separators */
++	for (p = path + strlen(path); --p > path && TDS_ISDIR_SEPARATOR(*p);)
+ 		*p = '\0';
+ 
+ 	p = strrchr(path, '/');
+-
+-	return p ? p : path;
++	if (p)
++		path = p + 1;
++#ifdef WIN32
++	p = strrchr(path, '\\');
++	if (p)
++		path = p + 1;
++#endif
++	return path;
+ }
+ #endif
+ 
+
+commit bf48ad5ec0d15cb022526ad2dec0a110eea88615
+Author: freddy77 <freddy77>
+Date:   Thu Mar 19 15:12:57 2009 +0000
+
+    add --no-pack option
+
+diff --git a/ChangeLog b/ChangeLog
+index 76f7e67..136212b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Mar 19 16:12:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/prepare_win32.sh: no pack option
++
+ Thu Mar 19 16:09:30 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c src/replacements/basename.c:
+ 	- fix some problems under win32
+@@ -1433,4 +1436,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2757 2009/03/19 15:09:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2758 2009/03/19 15:12:57 freddy77 Exp $
+diff --git a/misc/prepare_win32.sh b/misc/prepare_win32.sh
+index 72b7a75..8516b3a 100755
+--- a/misc/prepare_win32.sh
++++ b/misc/prepare_win32.sh
+@@ -10,6 +10,7 @@ errore() {
+ NTWDBLIB=no
+ TYPE=win32
+ ARCHIVE='tar jcvf "freetds-$PACKAGE_VERSION.$TYPE.tar.bz2" "freetds-$PACKAGE_VERSION"'
++PACK=yes
+ for param
+ do
+ 	case $param in
+@@ -26,6 +27,9 @@ do
+ 	--ntwdblib)
+ 		NTWDBLIB=yes
+ 		;;
++	--no-pack)
++		PACK=no
++		;;
+ 	--help)
+ 		echo "Usage: $0 [OPTION]..."
+ 		echo '  --help          this help'
+@@ -33,6 +37,7 @@ do
+ 		echo '  --zip           compress with zip'
+ 		echo '  --gzip          compress with gzip'
+ 		echo '  --ntwdblib      use ntwdblib instead of our'
++		echo "  --no-pack       don't clean and pack files"
+ 		exit 0
+ 		;;
+ 	*)
+@@ -274,6 +279,11 @@ fi
+ cat errors.txt | grep -v '^.libs/lt-\|^mkdir: cannot create directory ..libs.: File exists$' | perl -ne 'if (/visibility attribute not supported in this configuration/) {$ignore=1;$_=""} else {$ignore=0} ; print $old if !$ignore; $old=$_; END { print $old }' > ../${TYPE}_errors.txt
+ rm errors.txt
+ 
++if test "$PACK" = "no"; then
++	echo "No packaging requested, exiting"
++	exit 0
++fi
++
+ rm -rf include doc
+ find -name Makefile.in  |xargs rm
+ find -name \*.in  | grep -v 'unittests\|PWD' | xargs rm
+
+commit a7704b54002e6a4a356fd15c75cdac2e5d0fccba
+Author: freddy77 <freddy77>
+Date:   Thu Mar 19 16:02:36 2009 +0000
+
+    avoid use of uninitialized variable
+
+diff --git a/ChangeLog b/ChangeLog
+index 136212b..f56790e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Mar 19 17:02:22 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c:
++	- patch from Craig A. Berry for uninitialized variable
++
+ Thu Mar 19 16:12:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/prepare_win32.sh: no pack option
+ 
+@@ -1436,4 +1440,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2758 2009/03/19 15:12:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2759 2009/03/19 16:02:36 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 91f59e3..3d227af 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.234 2009/03/06 20:18:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.235 2009/03/19 16:02:36 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1450,7 +1450,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
+-	tdsdump_log(TDS_DBG_INFO1, "tds_put_data: colsize = %d\n", (int) colsize);
++	tdsdump_log(TDS_DBG_INFO1, "tds_put_data: colsize = %d\n", (int) curcol->column_cur_size);
+ 
+ 	if (curcol->column_cur_size < 0) {
+ 		tdsdump_log(TDS_DBG_INFO1, "tds_put_data: null param\n");
+
+commit 6e6ba6f540777d372f5157c1ce00ebda13020bb6
+Author: freddy77 <freddy77>
+Date:   Mon Mar 23 13:28:15 2009 +0000
+
+    fix uninitialized data
+
+diff --git a/ChangeLog b/ChangeLog
+index f56790e..e82fe88 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar 23 14:26:46 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix uninitialized data
++
+ Thu Mar 19 17:02:22 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c:
+ 	- patch from Craig A. Berry for uninitialized variable
+@@ -1440,4 +1443,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2759 2009/03/19 16:02:36 freddy77 Exp $
++$Id: ChangeLog,v 1.2760 2009/03/23 13:28:15 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 95ec9bb..1e7a6a2 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.344 2009/03/04 17:51:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.345 2009/03/23 13:28:15 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1092,7 +1092,7 @@ init_dboptions(void)
+ DBPROCESS *
+ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ {
+-	DBPROCESS *dbproc;
++	DBPROCESS *dbproc = NULL;
+ 	TDSCONNECTION *connection;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbopen(%p, %s, [%s])\n", login, server, msdblib? "microsoft" : "sybase");
+
+commit 08e72fed69ea304fe6cd219cded533f67b531223
+Author: jklowden <jklowden>
+Date:   Tue Mar 24 01:22:13 2009 +0000
+
+    remove hard-coded #include directories
+
+diff --git a/ChangeLog b/ChangeLog
+index e82fe88..8902872 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Mon Mar 23 21:19:02 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/dbutil.c
++	* src/dblib/rpc.c src/dblib/xact.c
++	- remove hard-coded #include directories
++	* BUGS add freebcp bug from ML
++
+ Mon Mar 23 14:26:46 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: fix uninitialized data
+ 
+@@ -1443,4 +1449,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2760 2009/03/23 13:28:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2761 2009/03/24 01:22:13 jklowden Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index da2a3e5..e407004 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -45,9 +45,9 @@
+ #include <tdsiconv.h>
+ #include <tdsconvert.h>
+ #include <replacements.h>
+-#include <../../include/sybfront.h>
+-#include <../../include/sybdb.h>
+-#include <../../include/syberror.h>
++#include <sybfront.h>
++#include <sybdb.h>
++#include <syberror.h>
+ #include <dblib.h>
+ 
+ #ifdef DMALLOC
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.183 2009/03/11 09:07:33 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.184 2009/03/24 01:22:14 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 1e7a6a2..88c4215 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -66,16 +66,16 @@
+ #include <tdsthread.h>
+ #include <tdsconvert.h>
+ #include <replacements.h>
+-#include <../../include/sybfront.h>
+-#include <../../include/sybdb.h>
+-#include <../../include/syberror.h>
++#include <sybfront.h>
++#include <sybdb.h>
++#include <syberror.h>
+ #include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.345 2009/03/23 13:28:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.346 2009/03/24 01:22:14 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1095,10 +1095,20 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 	DBPROCESS *dbproc = NULL;
+ 	TDSCONNECTION *connection;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "dbopen(%p, %s, [%s])\n", login, server, msdblib? "microsoft" : "sybase");
++	tdsdump_log(TDS_DBG_FUNC, "dbopen(%p, %s, [%s])\n", login, server? server : "0x0", msdblib? "microsoft" : "sybase");
++
++	/*
++	 * Sybase supports the DSQUERY environment variable and falls back to "SYBASE" if server is NULL. 
++	 * Microsoft uses a NULL or "" server to indicate a local server.  
++	 * FIXME: support local server for win32.  
++	 */
++	if (!server && !msdblib) {
++		if ((server = getenv("TDSQUERY")) == NULL)
++			if ((server = getenv("DSQUERY")) == NULL)
++				server = "SYBASE";
++		tdsdump_log(TDS_DBG_FUNC, "servername set to %s", server);
++	}
+ 
+-	CHECK_NULP(server, "dbopen", 2, NULL);
+-	
+ 	if ((dbproc = calloc(1, sizeof(DBPROCESS))) == NULL) {
+ 		dbperror(NULL, SYBEMEM, errno);
+ 		return NULL;
+diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c
+index d48bf4b..098568e 100644
+--- a/src/dblib/dbutil.c
++++ b/src/dblib/dbutil.c
+@@ -30,15 +30,15 @@
+ #endif /* HAVE_STDLIB_H */
+ 
+ #include <tds.h>
+-#include <../../include/sybdb.h>
+-#include <../../include/syberror.h>
++#include <sybdb.h>
++#include <syberror.h>
+ #include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbutil.c,v 1.45 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: dbutil.c,v 1.46 2009/03/24 01:22:14 jklowden Exp $");
+ 
+ /*
+  * test include consistency 
+diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c
+index 7b68281..8d8947d 100644
+--- a/src/dblib/rpc.c
++++ b/src/dblib/rpc.c
+@@ -46,15 +46,15 @@
+ #include <tds.h>
+ #include <tdsconvert.h>
+ #include <replacements.h>
+-#include <../../include/sybfront.h>
+-#include <../../include/sybdb.h>
++#include <sybfront.h>
++#include <sybdb.h>
+ #include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: rpc.c,v 1.67 2009/01/31 19:13:20 jklowden Exp $");
++TDS_RCSID(var, "$Id: rpc.c,v 1.68 2009/03/24 01:22:14 jklowden Exp $");
+ 
+ static void rpc_clear(DBREMOTE_PROC * rpc);
+ static void param_clear(DBREMOTE_PROC_PARAM * pparam);
+diff --git a/src/dblib/xact.c b/src/dblib/xact.c
+index f46bc7c..d0074ae 100644
+--- a/src/dblib/xact.c
++++ b/src/dblib/xact.c
+@@ -29,15 +29,15 @@
+ #endif /* HAVE_UNISTD_H */
+ 
+ #include <tds.h>
+-#include <../../include/sybfront.h>
+-#include <../../include/sybdb.h>
++#include <sybfront.h>
++#include <sybdb.h>
+ #include <dblib.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: xact.c,v 1.13 2009/01/31 19:13:20 jklowden Exp $");
++TDS_RCSID(var, "$Id: xact.c,v 1.14 2009/03/24 01:22:14 jklowden Exp $");
+ 
+ 
+ #if defined(DBLIB_UNIMPLEMENTED)
+
+commit cd771ccb7589dff101c0961c2545e8a9efa2fc15
+Author: jklowden <jklowden>
+Date:   Tue Mar 24 01:22:20 2009 +0000
+
+    add freebcp bug from ML
+
+diff --git a/BUGS b/BUGS
+index 71bc340..4c762a1 100644
+--- a/BUGS
++++ b/BUGS
+@@ -15,5 +15,7 @@ Needs Fixing
+    this requires either an SQL parser or API modification, 
+    because the library has to determine the SQL datatype 
+    of the placeholder variable.  
++6. ML Mar 19 2009: "Error in freebcp in", spurious error. 
++
+ 
+ 
+
+commit fdd01916f65847ab31ae49eb756c1e982f6d5482
+Author: freddy77 <freddy77>
+Date:   Tue Mar 24 10:39:02 2009 +0000
+
+    style update
+
+diff --git a/ChangeLog b/ChangeLog
+index 8902872..2b9f42b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Mar 24 11:38:29 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-auto.sh: style update
++
+ Mon Mar 23 21:19:02 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/bcp.c src/dblib/dblib.c src/dblib/dbutil.c
+ 	* src/dblib/rpc.c src/dblib/xact.c
+@@ -1449,4 +1452,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2761 2009/03/24 01:22:13 jklowden Exp $
++$Id: ChangeLog,v 1.2762 2009/03/24 10:39:02 freddy77 Exp $
+diff --git a/misc/test-auto.sh b/misc/test-auto.sh
+index 14d54e6..defdb9d 100755
+--- a/misc/test-auto.sh
++++ b/misc/test-auto.sh
+@@ -4,8 +4,8 @@
+ 
+ # set -e
+ 
+-BUILD=1
+-CONFIGURE=0
++BUILD=yes
++CONFIGURE=no
+ for param
+ do
+ 	case $param in
+@@ -14,10 +14,10 @@ do
+ 		exit 0
+ 		;;
+ 	--no-build)
+-		BUILD=0
++		BUILD=no
+ 		;;
+ 	--configure)
+-		CONFIGURE=1
++		CONFIGURE=yes
+ 		;;
+ 	esac
+ done
+@@ -62,8 +62,8 @@ if gmake --help 2> /dev/null > /dev/null; then
+ fi
+ 
+ # execute configure
+-if test $CONFIGURE = 1; then
+-	BUILD=1
++if test $CONFIGURE = yes; then
++	BUILD=yes
+ 	output_save "configuration" conf ./configure --enable-extra-checks $TDS_AUTO_CONFIG
+ 	if test $RES != 0; then
+ 		echo "error during configure"
+@@ -71,7 +71,7 @@ if test $CONFIGURE = 1; then
+ 	fi
+ fi
+ 
+-if test $BUILD = 1; then
++if test $BUILD = yes; then
+ 
+ 	echo Making ...
+ 	$MAKE clean > /dev/null 2> /dev/null
+
+commit 1d90e66c4b92f38ff6270f2a5889ba4085d33fb3
+Author: freddy77 <freddy77>
+Date:   Fri Mar 27 09:22:48 2009 +0000
+
+    remove warning and check
+
+diff --git a/ChangeLog b/ChangeLog
+index 2b9f42b..791cdf8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Mar 27 10:22:22 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: remove warning and check
++
+ Tue Mar 24 11:38:29 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/test-auto.sh: style update
+ 
+@@ -1452,4 +1455,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2762 2009/03/24 10:39:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2763 2009/03/27 09:22:48 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index fcc44d9..caa0626 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.90 2009/03/16 07:49:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.91 2009/03/27 09:22:49 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -700,7 +700,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 				continue;
+ 			}
+ 			
+-			if (0 == nput || nput < 0 && sock_errno == EAGAIN)
++			if (0 == nput || sock_errno == EAGAIN)
+ 				continue;
+ 
+ 			assert(nput < 0);
+
+commit 6ffcad81759042e078f8a01b30cb7ccc3a6472dd
+Author: freddy77 <freddy77>
+Date:   Fri Mar 27 09:24:48 2009 +0000
+
+    *** empty log message ***
+
+diff --git a/misc/commit b/misc/commit
+index 7dda164..1382f88 100755
+--- a/misc/commit
++++ b/misc/commit
+@@ -1,6 +1,6 @@
+ #!/usr/bin/perl
+ 
+-# $Id: commit,v 1.4 2009/03/19 13:13:21 freddy77 Exp $
++# $Id: commit,v 1.5 2009/03/27 09:24:48 freddy77 Exp $
+ 
+ use strict;
+ 
+@@ -61,7 +61,7 @@ sub parseLine($)
+ 	print "parsing line $line\n" if $debug;
+ 
+ 	# anything after : or - is a comment
+-	if ($line =~ /(.*?)([-:])(.*)/) {
++	if ($line =~ /(.*?)(:|- )(.*)/) {
+ 		($line, $comment) = ($1, $3);
+ 		push(@lastComments, '') if $2 eq '-';
+ 		print "line $line comment $comment\n" if $debug;
+
+commit 65b193aead57466955946e00de1380934b2e887e
+Author: jklowden <jklowden>
+Date:   Thu Apr 9 01:40:25 2009 +0000
+
+    apply patch from Craig A. Berry ML 8 April 2009
+
+diff --git a/ChangeLog b/ChangeLog
+index 791cdf8..fd6fc1c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Apr  8 21:35:02 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* include/fakepoll.h src/dblib/unittests/common.c
++	* vms/config_h.vms vms/descrip_mms.template
++	- apply patch from Craig A. Berry ML 8 April 2009
++	* doc/userguide.sgml document ASA Servername
++
+ Fri Mar 27 10:22:22 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: remove warning and check
+ 
+@@ -1455,4 +1461,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2763 2009/03/27 09:22:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2764 2009/04/09 01:40:25 jklowden Exp $
+diff --git a/include/fakepoll.h b/include/fakepoll.h
+index e81f9ad..7315555 100644
+--- a/include/fakepoll.h
++++ b/include/fakepoll.h
+@@ -1,4 +1,4 @@
+-/* $Id: fakepoll.h,v 1.1 2009/01/07 02:58:32 jklowden Exp $ */
++/* $Id: fakepoll.h,v 1.2 2009/04/09 01:40:25 jklowden Exp $ */
+ #if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
+ #define _FAKE_POLL_H
+ 
+@@ -19,6 +19,10 @@
+ #include <winsock2.h>
+ #endif
+ 
++#if defined(__VMS)
++#include <time.h> /* FD_SETSIZE is in here */
++#endif
++
+ #if !defined(FD_SETSIZE)
+ # if !defined(OPEN_MAX)
+ # error cannot establish FD_SETSIZE
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index cc5549d..fc77c39 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.31 2009/03/19 15:09:56 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.32 2009/04/09 01:40:25 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -110,12 +110,25 @@ read_login_info(int argc, char **argv)
+ 	static const char *PWD = "../../../PWD";
+ 	struct { char *username, *password, *servername, *database; char fverbose; } options;
+ 	
+-	BASENAME = tds_basename((char *)argv[0]);
+-#ifdef WIN32
++#ifdef __VMS
++	{
++		/* basename expects unix format */
++		strncpy(filename, argv[0],  PATH_MAX);
++		s1 = strrchr(filename, ';'); /* trim version; extension trimmed later */
++		if (s1) *s1 = 0;
++		const char *unixspec = decc$translate_vms(filename);
++		strncpy(filename, unixspec,  PATH_MAX);
++	}
++#else
++	strncpy(filename, argv[0],  PATH_MAX);
++#endif
++	
++	BASENAME = tds_basename(filename);
++#if defined(WIN32) || defined(__VMS)
+ 	s1 = strrchr(BASENAME, '.');
+ 	if (s1) *s1 = 0;
+ #endif
+-	DIRNAME = dirname((char *)argv[0]);
++	DIRNAME = dirname(filename);
+ 	
+ 	memset(&options, 0, sizeof(options));
+ 	
+diff --git a/vms/config_h.vms b/vms/config_h.vms
+index 6b847ab..f727dd6 100644
+--- a/vms/config_h.vms
++++ b/vms/config_h.vms
+@@ -1,4 +1,4 @@
+-/* $Id: config_h.vms,v 1.9 2008/07/17 11:52:35 freddy77 Exp $ */
++/* $Id: config_h.vms,v 1.10 2009/04/09 01:40:25 jklowden Exp $ */
+ 
+ /* include/config.h.in.  Generated from configure.ac by autoheader.  */
+ /* and edited by hand for VMS */
+@@ -279,8 +279,6 @@
+ 
+ /* Additions below not originally from config.h.in */
+ 
+-#define _FREETDS_LIBRARY_SOURCE
+-
+ /* This really just needs to be the current working directory for the tests */
+ #define FREETDS_SRCDIR "."
+ 
+diff --git a/vms/descrip_mms.template b/vms/descrip_mms.template
+index 8d9fe9f..0799528 100644
+--- a/vms/descrip_mms.template
++++ b/vms/descrip_mms.template
+@@ -16,7 +16,7 @@
+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ # Boston, MA 02111-1307, USA.
+ # 
+-# $Id: descrip_mms.template,v 1.13 2008/05/22 03:53:18 jklowden Exp $
++# $Id: descrip_mms.template,v 1.14 2009/04/09 01:40:25 jklowden Exp $
+ 
+ # OpenVMS description file for FreeTDS
+ 
+@@ -71,17 +71,17 @@ CC = CC/DECC
+ .SUFFIXES : $(E) $(OLB) $(OBJ) .C .H
+ 
+ .IFDEF ODBC
+-CDEFINE = "$(TDSVER)","HAVE_CONFIG_H"=1,"UNIXODBC"
++CDEFINE = "$(TDSVER)","HAVE_CONFIG_H"=1,_FREETDS_LIBRARY_SOURCE=1,"UNIXODBC"
+ CODBCFLAGS = /NAMES=(AS_IS,SHORTENED)
+ .ELSE
+-CDEFINE = $(TDSVER),HAVE_CONFIG_H=1
++CDEFINE = $(TDSVER),HAVE_CONFIG_H=1,_FREETDS_LIBRARY_SOURCE=1
+ CODBCFLAGS = /NAMES=SHORTENED
+ .ENDIF
+ CPREFIX = ALL
+-CINCLUDE = "./","./include","./src/tds"$(ODBC_INC)
++CINCLUDE = "./","./include"$(ODBC_INC)
+ 
+ .IFDEF __DEBUG__
+-CDBGFLAGS = /DEBUG/NOOPTIMIZE/LIST=$(MMS$TARGET_NAME)/SHOW=ALL
++CDBGFLAGS = /DEBUG/NOOPTIMIZE/LIST=$(MMS$TARGET_NAME)/SHOW=(EXPANSION,INCLUDE)
+ LDBGFLAGS = /DEBUG/MAP
+ .ELSE
+ CDBGFLAGS =
+@@ -106,10 +106,10 @@ STRTOK_ROBJ = @STRTOK_ROBJ@
+ LIBICONVOBJ = @LIBICONVOBJ@
+ SNPRINTFOBJ = @SNPRINTFOBJ@
+ 
+-TDSOBJS = [.src.tds]challenge$(OBJ), [.src.tds]config$(OBJ), [.src.tds]convert$(OBJ), \
+-	[.src.tds]data$(OBJ), [.src.tds]des$(OBJ), [.src.tds]getmac$(OBJ), \
+-	[.src.tds]iconv$(OBJ), [.src.tds]locale$(OBJ), [.src.tds]login$(OBJ), \
+-	[.src.tds]md4$(OBJ), [.src.tds]mem$(OBJ), [.src.tds]numeric$(OBJ), \
++TDSOBJS = [.src.tds]bulk$(OBJ), [.src.tds]challenge$(OBJ), [.src.tds]config$(OBJ), \
++	[.src.tds]convert$(OBJ), [.src.tds]data$(OBJ), [.src.tds]des$(OBJ), [.src.tds]getmac$(OBJ), \
++	[.src.tds]gssapi$(OBJ), [.src.tds]hmac_md5$(OBJ), [.src.tds]iconv$(OBJ), [.src.tds]locale$(OBJ), \
++	[.src.tds]login$(OBJ), [.src.tds]md4$(OBJ), [.src.tds]mem$(OBJ), [.src.tds]numeric$(OBJ), \
+ 	[.src.tds]query$(OBJ), [.src.tds]read$(OBJ), [.src.tds]tdsstring$(OBJ), \
+ 	[.src.tds]threadsafe$(OBJ), [.src.tds]token$(OBJ), [.src.tds]util$(OBJ), \
+ 	[.src.tds]vstrbuild$(OBJ), [.src.tds]write$(OBJ), [.src.tds]md5$(OBJ), \
+@@ -573,7 +573,7 @@ odbctests : [.src.odbc.unittests]t0001$(E) [.src.odbc.unittests]t0002$(E) [.src.
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libtds$(OLB)/library
+ 
+ [.src.tds.unittests]convert$(OBJ) : [.src.tds.unittests]convert.c
+-	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.tds.unittests],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++	$(CC) $(CFLAGS)/NOWARN/INCLUDE=([.src.tds.unittests],$(CINCLUDE),[.src.tds]) $(CDBGFLAGS) $(MMS$SOURCE)
+ 
+ [.src.tds.unittests]dataread$(E) : [.src.tds.unittests]dataread$(OBJ) [.src.tds.unittests]common$(OBJ)
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libtds$(OLB)/library
+
+commit a35005af41048efaaf9b8ce217d022299a6361bc
+Author: jklowden <jklowden>
+Date:   Thu Apr 9 01:40:37 2009 +0000
+
+    document ASA Servername
+
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index cc88ecf..1c77454 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2009/02/11 02:41:58 $</date>
+-		<releaseinfo>$Revision: 1.121 $</releaseinfo>
++		<date>$Date: 2009/04/09 01:40:37 $</date>
++		<releaseinfo>$Revision: 1.122 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -27,6 +27,7 @@
+ 		  <year>2006</year>
+ 		  <year>2007</year>
+ 		  <year>2008</year>
++		  <year>2009</year>
+ 		  <holder>Brian Bruns and James K. Lowden</holder>
+ 		</copyright>
+ 		<legalnotice><para>
+@@ -56,9 +57,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.121 $</>
+-<member>$Date: 2009/02/11 02:41:58 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.121 2009/02/11 02:41:58 jklowden Exp $.</>
++<member>$Revision: 1.122 $</>
++<member>$Date: 2009/04/09 01:40:37 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.122 2009/04/09 01:40:37 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -568,7 +569,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2009/02/11 02:41:58 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2009/04/09 01:40:37 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -779,8 +780,8 @@ The actual name and location of <filename>freetds.conf</filename> may be specifi
+ 		<sect2 id="freetdsconfformat">
+ 			<title>What it looks like</title>
+ 			<para>
+-The <filename>freetds.conf</filename> file is composed of two types of sections: a 
+-<literal>[global]</literal> section,  and one <literal>[<replaceable>dataserver</replaceable>]</literal> section for each dataserver.  Settings in the <literal>[global]</literal> section affect all dataservers, but can be overridden in a <literal>[<replaceable>dataserver</replaceable>]</literal> section.  For example
++The <filename>freetds.conf</filename> file is composed of two types of sections: one
++<literal>[global]</literal> section,  and a <literal>[<replaceable>dataserver</replaceable>]</literal> section for each dataserver.  Settings in the <literal>[global]</literal> section affect all dataservers, but can be overridden in a <literal>[<replaceable>dataserver</replaceable>]</literal> section.  For example
+ 			</para>
+ <example id="e.g.freetdsconf">
+ <title>A <filename>freetds.conf</filename> file example</title>
+@@ -807,10 +808,7 @@ The <filename>freetds.conf</filename> file is composed of two types of sections:
+ In this example, the default  <acronym>TDS</> version for all dataservers is set to <literal>4.2</>.  It is then overridden for <literal>myserver2</literal> (a Sybase server) which uses <literal>5.0</literal>, and <literal>myserver3</literal> (a MSSQL 2000 server) which uses <literal>8.0</literal>.
+ 	</para>
+ 	<para>
+-Note that <literal>myserver3</literal> uses a named instance configuration, instead of a port number.  
+-	</para>
+-	<para>
+-Usually, it is sufficient to state the only server's hostname and TDS protocol.  Everything else can be inferred, unless your setup (or your server's) strays from the defaults.  
++Usually, it is sufficient to state just the server's hostname and TDS protocol version.  Everything else can be inferred, unless your setup (or your server's) strays from the defaults.  
+ 	<tip><para>Some people seem to feel safer using the IP address for the server, rather than its name.  We don't recommend you do that.  Use the name, and benefit from the inherent advantages.  That's why DNS was invented in the first place, you know.  </para></tip>
+ 	</para>
+ 	<para>
+@@ -888,11 +886,19 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	</row>
+ 
+ 	<row>
++	<entry>ASA database</entry>
++	<entry>valid database name</entry>
++	<entry>dataserver [<replaceable>section</>] name</entry>
++	<entry>Specifies the name of the default database when connecting to an ASA server.  A TDS 5.0 login packet has a field called <literal>lservname</>.   For most TDS servers, <literal>lservname</> is a user-defined string with no inherent meaning.  ASA servers, however, requires that <literal>lservname</>  contain a valid database name, and sets that as the default database for the connection.  FreeTDS normally fills <literal>lservname</>  with the [<replaceable>section</>]text..   This entry instead sets the database name independently of the [<replaceable>section</>] name.   </entry>
++	</row>
++
++	<row>
+ 	<entry>initial block size</entry>
+ 	<entry>multiple of 512</entry>
+ 	<entry>512</entry>
+ 	<entry>Specifies the maximum size of a protocol block.  Don't mess with unless you know what you are doing.</entry>
+ 	</row>
++
+ 	<row>
+ 	<entry>dump file</entry>
+ 	<entry>any valid file name</entry>
+
+commit c2bbd839a4e5baf037a146e4ade2717a7c37723c
+Author: freddy77 <freddy77>
+Date:   Wed Apr 15 08:00:20 2009 +0000
+
+    fix core detecting sql input file
+
+diff --git a/ChangeLog b/ChangeLog
+index fd6fc1c..4823b72 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Apr 15 09:59:47 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: fix core detecting sql input file
++
+ Wed Apr  8 21:35:02 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/fakepoll.h src/dblib/unittests/common.c
+ 	* vms/config_h.vms vms/descrip_mms.template
+@@ -1461,4 +1464,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2764 2009/04/09 01:40:25 jklowden Exp $
++$Id: ChangeLog,v 1.2765 2009/04/15 08:00:20 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index fc77c39..6e9be30 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.32 2009/04/09 01:40:25 jklowden Exp $";
++static char software_version[] = "$Id: common.c,v 1.33 2009/04/15 08:00:20 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -42,6 +42,7 @@ char DATABASE[512];
+ static char sql_file[PATH_MAX];
+ static FILE* input_file;
+ 
++static char *ARGV0 = NULL;
+ static char *DIRNAME = NULL;
+ static const char *BASENAME = NULL;
+ 
+@@ -94,6 +95,12 @@ free_file(void)
+ 		fclose(input_file);
+ 		input_file = NULL;
+ 	}
++	if (ARGV0) {
++		DIRNAME = NULL;
++		BASENAME = NULL;
++		free(ARGV0);
++		ARGV0 = NULL;
++	}
+ }
+ 
+ int
+@@ -113,22 +120,21 @@ read_login_info(int argc, char **argv)
+ #ifdef __VMS
+ 	{
+ 		/* basename expects unix format */
+-		strncpy(filename, argv[0],  PATH_MAX);
+-		s1 = strrchr(filename, ';'); /* trim version; extension trimmed later */
++		s1 = strrchr(argv[0], ';'); /* trim version; extension trimmed later */
+ 		if (s1) *s1 = 0;
+-		const char *unixspec = decc$translate_vms(filename);
+-		strncpy(filename, unixspec,  PATH_MAX);
++		const char *unixspec = decc$translate_vms(argv[0]);
++		ARGV0 = strdup(unixspec);
+ 	}
+ #else
+-	strncpy(filename, argv[0],  PATH_MAX);
++	ARGV0 = strdup(argv[0]);
+ #endif
+ 	
+-	BASENAME = tds_basename(filename);
++	BASENAME = tds_basename(ARGV0);
+ #if defined(WIN32) || defined(__VMS)
+-	s1 = strrchr(BASENAME, '.');
++	s1 = strrchr(ARGV0, '.');
+ 	if (s1) *s1 = 0;
+ #endif
+-	DIRNAME = dirname(filename);
++	DIRNAME = dirname(ARGV0);
+ 	
+ 	memset(&options, 0, sizeof(options));
+ 	
+
+commit 495c5e1c297dd32d63c733dfd3ae62907c4bce7b
+Author: freddy77 <freddy77>
+Date:   Wed Apr 15 20:55:03 2009 +0000
+
+    fix dirname for win32
+
+diff --git a/ChangeLog b/ChangeLog
+index 4823b72..f780385 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Apr 15 22:54:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: fix dirname for win32
++
+ Wed Apr 15 09:59:47 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c: fix core detecting sql input file
+ 
+@@ -1464,4 +1467,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2765 2009/04/15 08:00:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2766 2009/04/15 20:55:03 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 6e9be30..055bf6c 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.33 2009/04/15 08:00:20 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.34 2009/04/15 20:55:03 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -80,6 +80,11 @@ tds_dirname(char* path)
+ 	p2 = strrchr(p, '\\');
+ 	if (p2)
+ 		p = p2;
++	if (p == path) {
++		if (*p == '/' || *p == '\\')
++			return "\\";
++		return ".";
++	}
+ 	*p = 0;
+ 	return path;
+ }
+
+commit 3db27129183c0a9873dbc4cecb67b98dfc52031e
+Author: freddy77 <freddy77>
+Date:   Thu Apr 16 07:24:25 2009 +0000
+
+    fix extension stripping
+
+diff --git a/ChangeLog b/ChangeLog
+index f780385..c52fdae 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 16 09:23:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: fix extension stripping
++
+ Wed Apr 15 22:54:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c: fix dirname for win32
+ 
+@@ -1467,4 +1470,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2766 2009/04/15 20:55:03 freddy77 Exp $
++$Id: ChangeLog,v 1.2767 2009/04/16 07:24:25 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 055bf6c..5bc071a 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.34 2009/04/15 20:55:03 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.35 2009/04/16 07:24:25 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -136,7 +136,7 @@ read_login_info(int argc, char **argv)
+ 	
+ 	BASENAME = tds_basename(ARGV0);
+ #if defined(WIN32) || defined(__VMS)
+-	s1 = strrchr(ARGV0, '.');
++	s1 = strrchr(BASENAME, '.');
+ 	if (s1) *s1 = 0;
+ #endif
+ 	DIRNAME = dirname(ARGV0);
+
+commit 3bdf2708b51b0ab7002aaef6a02fe9325ca269cf
+Author: freddy77 <freddy77>
+Date:   Fri Apr 17 09:54:27 2009 +0000
+
+    improve dblib compatibility with windows
+
+diff --git a/ChangeLog b/ChangeLog
+index c52fdae..8d3d89f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Apr 17 11:54:00 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c: disable output buffering
++	* src/dblib/unittests/null2.c: fix for MS library
++
+ Thu Apr 16 09:23:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c: fix extension stripping
+ 
+@@ -1470,4 +1474,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2767 2009/04/16 07:24:25 freddy77 Exp $
++$Id: ChangeLog,v 1.2768 2009/04/17 09:54:27 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 5bc071a..337c4d7 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.35 2009/04/16 07:24:25 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.36 2009/04/17 09:54:27 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -121,6 +121,9 @@ read_login_info(int argc, char **argv)
+ 	char filename[PATH_MAX];
+ 	static const char *PWD = "../../../PWD";
+ 	struct { char *username, *password, *servername, *database; char fverbose; } options;
++
++	setbuf(stdout, NULL);
++	setbuf(stderr, NULL);
+ 	
+ #ifdef __VMS
+ 	{
+diff --git a/src/dblib/unittests/null2.c b/src/dblib/unittests/null2.c
+index b3b43f0..781441b 100644
+--- a/src/dblib/unittests/null2.c
++++ b/src/dblib/unittests/null2.c
+@@ -6,7 +6,7 @@
+ 
+ #include <unistd.h>
+ 
+-static char software_version[] = "$Id: null2.c,v 1.5 2008/11/25 22:58:29 jklowden Exp $";
++static char software_version[] = "$Id: null2.c,v 1.6 2009/04/17 09:54:27 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static DBPROCESS *dbproc = NULL;
+@@ -184,10 +184,14 @@ main(int argc, char **argv)
+ 	test("TEXT", 1);
+ 
+ 	test("NVARCHAR(10)", 0);
++#ifndef DBNTWIN32
+ 	test("NTEXT", 0);
++#endif
+ 
+ 	test("VARCHAR(MAX)", 0);
++#ifndef DBNTWIN32
+ 	test("NVARCHAR(MAX)", 0);
++#endif
+ 
+ 	dbexit();
+ 
+
+commit c3d1cd221354e96df4cd780b62ede2ee36e4a96c
+Author: freddy77 <freddy77>
+Date:   Fri Apr 17 14:29:37 2009 +0000
+
+    script to compile dblib unittests using Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 8d3d89f..7d3e342 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Apr 17 16:28:55 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/sybase_tests: script to compile dblib unittests using Sybase
++
+ Fri Apr 17 11:54:00 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c: disable output buffering
+ 	* src/dblib/unittests/null2.c: fix for MS library
+@@ -1474,4 +1477,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2768 2009/04/17 09:54:27 freddy77 Exp $
++$Id: ChangeLog,v 1.2769 2009/04/17 14:29:37 freddy77 Exp $
+diff --git a/misc/sybase_tests b/misc/sybase_tests
+new file mode 100755
+index 0000000..ecba840
+--- /dev/null
++++ b/misc/sybase_tests
+@@ -0,0 +1,45 @@
++#!/bin/bash
++
++# $Id: sybase_tests,v 1.1 2009/04/17 14:29:44 freddy77 Exp $
++# these commands build dblib tests using Sybase dblib
++
++errore() {
++	echo $* >&2
++	exit 1
++}
++
++test -x configure || errore "configure not found, go to main directory"
++test -d "$SYBASE" || errore "SYBASE environment not defined"
++MAINDIR="`pwd`"
++cd "$SYBASE"
++OCSDIR=`echo OCS-*`
++cd "$MAINDIR"
++test -d "$SYBASE/$OCSDIR" || errore "OCS directory not found"
++
++# build
++trap 'echo Error at line $LINENO' ERR
++set -e
++make -j4
++TESTS_ENVIRONMENT=true make -j4 check
++
++handle_exit() {
++	echo Exiting
++	if test -r "$MAINDIR/src/dblib/unittests/Makefile.no_sybase"; then
++		cp -f "$MAINDIR/src/dblib/unittests/Makefile.no_sybase" "$MAINDIR/src/dblib/unittests/Makefile" && rm -f "$MAINDIR/src/dblib/unittests/Makefile.no_sybase"
++	fi
++	rm -f "$MAINDIR/src/dblib/unittests/sqlfront.h" "$MAINDIR/src/dblib/unittests/sqldb.h"
++}
++
++# rebuild tests
++cd src/dblib/unittests
++rm -f *.o *.exe
++make clean
++trap handle_exit EXIT
++echo '#include <sybfront.h>' > sqlfront.h
++echo '#include <sybdb.h>' > sqldb.h
++perl -pi.no_sybase -e "\$_ =~ s{ -I\\\$\\(top_(build|src)dir\\)/include}{ -I$SYBASE/$OCSDIR/include -I\\\$(top_builddir)/include} if (/^(DEFAULT_INCLUDES|AM_CPPFLAGS)\s*=/);
++\$_ =~ s{../libsybdb.la}{-lsybdb -lsybunic} if (/^LIBS\s*=/);
++\$_ =~ s{-L../.libs -R \\\$\\(abs_builddir\\)/../.libs}{-L$SYBASE/$OCSDIR/lib} if (/^AM_LDFLAGS\s*=/);
++" Makefile
++TESTS_ENVIRONMENT=true make -j4 check 
++
+
+commit 21e42355c1c848af17c6a099e917be40950ea023
+Author: freddy77 <freddy77>
+Date:   Fri Apr 17 17:16:22 2009 +0000
+
+    set LD_RUN_PATH to find proper libraries
+
+diff --git a/ChangeLog b/ChangeLog
+index 7d3e342..337ae2a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Apr 17 19:16:14 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/sybase_tests: set LD_RUN_PATH to find proper libraries
++
+ Fri Apr 17 16:28:55 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/sybase_tests: script to compile dblib unittests using Sybase
+ 
+@@ -1477,4 +1480,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2769 2009/04/17 14:29:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2770 2009/04/17 17:16:22 freddy77 Exp $
+diff --git a/misc/sybase_tests b/misc/sybase_tests
+index ecba840..35c4924 100755
+--- a/misc/sybase_tests
++++ b/misc/sybase_tests
+@@ -1,6 +1,6 @@
+ #!/bin/bash
+ 
+-# $Id: sybase_tests,v 1.1 2009/04/17 14:29:44 freddy77 Exp $
++# $Id: sybase_tests,v 1.2 2009/04/17 17:16:28 freddy77 Exp $
+ # these commands build dblib tests using Sybase dblib
+ 
+ errore() {
+@@ -34,6 +34,11 @@ handle_exit() {
+ cd src/dblib/unittests
+ rm -f *.o *.exe
+ make clean
++if test "$LD_RUN_PATH" != ""; then
++	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib:$LD_RUN_PATH"
++else
++	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib"
++fi
+ trap handle_exit EXIT
+ echo '#include <sybfront.h>' > sqlfront.h
+ echo '#include <sybdb.h>' > sqldb.h
+
+commit d6f9eca495adfe10e299b5d8c0ca167fb6e8802c
+Author: freddy77 <freddy77>
+Date:   Sat Apr 18 15:21:49 2009 +0000
+
+    fix test according to vendors behavior
+
+diff --git a/ChangeLog b/ChangeLog
+index 337ae2a..6086d57 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Apr 18 17:21:15 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/timeout.c:
++	- fix test according to vendors behavior
++
+ Fri Apr 17 19:16:14 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/sybase_tests: set LD_RUN_PATH to find proper libraries
+ 
+@@ -1480,4 +1484,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2770 2009/04/17 17:16:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2771 2009/04/18 15:21:49 freddy77 Exp $
+diff --git a/src/dblib/unittests/timeout.c b/src/dblib/unittests/timeout.c
+index 1551cb6..e27c8de 100644
+--- a/src/dblib/unittests/timeout.c
++++ b/src/dblib/unittests/timeout.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <time.h>
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.7 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.8 2009/04/18 15:21:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int ntimeouts = 0, ncancels = 0;
+@@ -176,8 +176,8 @@ main(int argc, char **argv)
+ 	/* wait for it to execute */
+ 	printf("executing dbsqlok\n");
+ 	erc = dbsqlok(dbproc);
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed: dbsqlok\n");
++	if (erc != FAIL) {
++		fprintf(stderr, "dbsqlok should fail for timeout\n");
+ 		exit(1);
+ 	}
+ 
+@@ -222,8 +222,8 @@ main(int argc, char **argv)
+ 			}
+ 			break;
+ 		case FAIL:
+-			printf("OK: dbresults returned FAIL, probably caused by the timeout\n");
+-			break;
++			printf("dbresults returned FAIL\n");
++			exit(1);
+ 		default:
+ 			printf("unexpected return code %d from dbresults\n", erc);
+ 			exit(1);
+
+commit f66e6b91387458bce604701715ad77543fcda071
+Author: jklowden <jklowden>
+Date:   Sat Apr 18 19:35:38 2009 +0000
+
+    support TDSEINTF and TDSEUHST to distinguish name-lookup failures.
+
+diff --git a/ChangeLog b/ChangeLog
+index 6086d57..629cef5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Sat Apr 18 15:18:39 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* include/sybdb.h include/tds.h
++	* src/apps/bsqldb.c src/apps/tsql.c
++	* src/ctlib/ct.c src/dblib/dblib.c src/odbc/odbc.c
++	* src/tds/config.c src/tds/login.c src/tds/util.c
++	- support TDSEINTF and TDSEUHST to distinguish name-lookup failures.
++
+ Sat Apr 18 17:21:15 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/timeout.c:
+ 	- fix test according to vendors behavior
+@@ -1484,4 +1491,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2771 2009/04/18 15:21:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2772 2009/04/18 19:35:38 jklowden Exp $
+diff --git a/include/sybdb.h b/include/sybdb.h
+index fc3dd4b..d642612 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.89 2009/02/28 17:38:39 jklowden Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.90 2009/04/18 19:35:38 jklowden Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -555,7 +555,6 @@ char *dbtabname(DBPROCESS * dbprocess, int tabnum);
+ char *dbtabsoruce(DBPROCESS * dbprocess, int colnum, int *tabnum);
+ 
+ RETCODE dbsetlshort(LOGINREC * login, int value, int which);
+-#define DBSETLHIER(x,y)		dbsetlshort((x), (y), DBSETHIER)
+ 
+ RETCODE dbsendpassthru(DBPROCESS * dbprocess, DBVOIDPTR bufp);
+ RETCODE dbrecvpassthru(DBPROCESS * dbprocess, DBVOIDPTR * bufp);
+@@ -1113,8 +1112,10 @@ RETCODE dbsetlversion (LOGINREC * login, BYTE version);
+ #define DBSETPWD		3
+ #define DBSETLPWD(x,y)		dbsetlname((x), (y), DBSETPWD)
+ #define dbsetlpwd(x,y)		dbsetlname((x), (y), DBSETPWD)
+-#define DBSETHID		4	/* not implemented */
+-#define DBSETLHID(x,y)		dbsetlname((x), (y), DBSETHID)
++#if defined(DBLIB_UNIMPLEMENTED)
++# define DBSETHID		4	/* not implemented */
++# define DBSETLHID(x,y)		dbsetlname((x), (y), DBSETHID)
++#endif
+ #define DBSETAPP		5
+ #define DBSETLAPP(x,y)		dbsetlname((x), (y), DBSETAPP)
+ #define dbsetlapp(x,y)		dbsetlname((x), (y), DBSETAPP)
+@@ -1124,9 +1125,12 @@ RETCODE dbsetlversion (LOGINREC * login, BYTE version);
+ #define DBSETNATLANG		7	
+ #define DBSETLNATLANG(x,y)	dbsetlname((x), (y), DBSETNATLANG)
+ #define dbsetlnatlang(x,y)	dbsetlname((x), (y), DBSETNATLANG)
+-#define DBSETNOSHORT		8	/* not implemented */
+-#define DBSETLNOSHORT(x,y)	dbsetlbool((x), (y), DBSETNOSHORT)
+-#define DBSETHIER		9	/* not implemented */
++#if defined(DBLIB_UNIMPLEMENTED)
++# define DBSETNOSHORT		8	/* not implemented */
++# define DBSETLNOSHORT(x,y)	dbsetlbool((x), (y), DBSETNOSHORT)
++# define DBSETHIER		9	/* not implemented */
++# define DBSETLHIER(x,y)	dbsetlshort((x), (y), DBSETHIER)
++#endif
+ #define DBSETCHARSET		10
+ #define DBSETLCHARSET(x,y)	dbsetlname((x), (y), DBSETCHARSET)
+ #define DBSETPACKET		11
+diff --git a/include/tds.h b/include/tds.h
+index 8f7d4b5..9b31c4f 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.312 2009/02/28 17:38:50 jklowden Exp $ */
++/* $Id: tds.h,v 1.313 2009/04/18 19:35:38 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -296,6 +296,8 @@ typedef enum {	TDSEOK    = TDS_SUCCEED,
+ 		TDSESOCK = 20008, 
+ 		TDSECONN = 20009, 
+ 		TDSEMEM  = 20010,
++		TDSEINTF = 20012,	/* Server name not found in interface file */
++		TDSEUHST = 20013,	/* Unknown host machine name. */
+ 		TDSEPWD  = 20014, 
+ 		TDSESEOF = 20017, 
+ 		TDSERPND = 20019, 
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 00e8a8e..630bda4 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -45,7 +45,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.34 2009/01/12 08:15:52 freddy77 Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.35 2009/04/18 19:35:38 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+@@ -112,16 +112,15 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 	
++	/* Install our error and message handlers */
++	dberrhandle(err_handler);
++	dbmsghandle(msg_handler);
+ 
+ 	memset(&options, 0, sizeof(options));
+ 	options.headers = stderr;
+ 	login = get_login(argc, argv, &options); /* get command-line parameters and call dblogin() */
+ 	assert(login != NULL);
+ 
+-	/* Install our error and message handlers */
+-	dberrhandle(err_handler);
+-	dbmsghandle(msg_handler);
+-
+ 	/* 
+ 	 * Override stdin, stdout, and stderr, as required 
+ 	 */
+@@ -163,8 +162,8 @@ main(int argc, char *argv[])
+ 	/* 
+ 	 * Connect to the server 
+ 	 */
+-	dbproc = dbopen(login, options.servername);
+-	assert(dbproc != NULL);
++	if ((dbproc = dbopen(login, options.servername)) == NULL)
++		return 1;
+ 	
+ 	/* Switch to the specified database, if any */
+ 	if (options.database)
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 455bf2d..0e86a68 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.126 2009/01/12 08:09:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.127 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -697,8 +697,9 @@ main(int argc, char **argv)
+ 
+ 	/* Try to open a connection */
+ 	tds = tds_alloc_socket(context, 512);
++	assert(tds);
+ 	tds_set_parent(tds, NULL);
+-	connection = tds_read_config_info(NULL, login, context->locale);
++	connection = tds_read_config_info(tds, login, context->locale);
+ 
+ 	if (opt_default_db) {
+ 		tds_dstr_copy(&connection->database, opt_default_db);
+@@ -707,8 +708,7 @@ main(int argc, char **argv)
+ 
+ 	/* 
+ 	 * If we're able to establish an ip address for the server, we'll try to connect to it. 
+-	 * If that machine is currently unreachable
+-	 * show a timer connecting to the server 
++	 * If that machine is currently unreachable, show a timer connecting to the server. 
+ 	 */
+ #if HAVE_FORK
+ 	if (connection && !QUIET) {
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 46c3dea..bc7d306 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.185 2008/12/19 10:37:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.186 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -586,7 +586,7 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 	if (!(con->tds_socket = tds_alloc_socket(ctx->tds_ctx, 512)))
+ 		return CS_FAIL;
+ 	tds_set_parent(con->tds_socket, (void *) con);
+-	if (!(connection = tds_read_config_info(NULL, con->tds_login, ctx->tds_ctx->locale))) {
++	if (!(connection = tds_read_config_info(con->tds_socket, con->tds_login, ctx->tds_ctx->locale))) {
+ 		tds_free_socket(con->tds_socket);
+ 		con->tds_socket = NULL;
+ 		return CS_FAIL;
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 88c4215..4561669 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.346 2009/03/24 01:22:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.347 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -747,6 +747,11 @@ dbsetlname(LOGINREC * login, const char *value, int which)
+ 		return FAIL;
+ 	}
+ 
++	if (TDS_MAX_LOGIN_STR_SZ < strlen(value)) {
++		dbperror(NULL, SYBENTLL, 0);
++		return FAIL;
++	}
++
+ 	switch (which) {
+ 	case DBSETHOST:
+ 		tds_set_host(login->tds_login, value);
+@@ -772,7 +777,6 @@ dbsetlname(LOGINREC * login, const char *value, int which)
+ 		tds_set_language(login->tds_login, value);
+ 		return SUCCEED;
+ 		break;
+-	case DBSETHID:
+ 	default:
+ 		dbperror(NULL, SYBEASUL, 0); /* Attempt to set unknown LOGINREC field */
+ 		return FAIL;
+@@ -862,7 +866,6 @@ dbsetlbool(LOGINREC * login, int value, int which)
+ 		tds_set_bulk(login->tds_login, (TDS_TINYINT) value);
+ 		return SUCCEED;
+ 		break;
+-	case DBSETNOSHORT:
+ 	case DBSETENCRYPT:
+ 	case DBSETLABELED:
+ 	default:
+@@ -1127,7 +1130,11 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 
+ 	tds_set_server(login->tds_login, server);
+ 
+-	dbproc->tds_socket = tds_alloc_socket(dblib_get_tds_ctx(), 512);
++	if ((dbproc->tds_socket = tds_alloc_socket(dblib_get_tds_ctx(), 512)) == NULL ){
++		dbperror(NULL, SYBEMEM, 0);
++		return NULL;
++	}
++	
+ 
+ 	tds_set_parent(dbproc->tds_socket, dbproc);
+ 	dbproc->tds_socket->option_flag2 &= ~0x02;	/* we're not an ODBC driver */
+@@ -1136,7 +1143,7 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 	dbproc->dbcurdb[0] = '\0';
+ 	dbproc->servcharset[0] = '\0';
+ 
+-	connection = tds_read_config_info(NULL, login->tds_login, g_dblib_ctx.tds_ctx->locale);
++	connection = tds_read_config_info(dbproc->tds_socket, login->tds_login, g_dblib_ctx.tds_ctx->locale);
+ 	if (!connection) {
+ 		dbclose(dbproc);
+ 		return NULL;
+@@ -7626,7 +7633,7 @@ static const DBLIB_ERROR_MESSAGE dblib_error_messages[] =
+ 	, { SYBEIMCL,       EXCONSISTENCY,	"Illegal money column length returned by Adaptive Server. Legal money lengths are 4 "
+ 						"and 8 bytes\0" }
+ 	, { SYBEINLN,              EXUSER,	"Interface file: unexpected end-of-line\0" }
+-	, { SYBEINTF,              EXUSER,	"Server name not found in interface file\0" }
++	, { SYBEINTF,              EXUSER,	"Server name not found in configuration files\0" }
+ 	, { SYBEINUMCL,     EXCONSISTENCY,	"Invalid numeric column length returned by the server\0" }
+ 	, { SYBEIPV,               EXINFO,	"%1! is an illegal value for the %2! parameter of %3!\0%d %s %s" }
+ 	, { SYBEISOI,       EXCONSISTENCY,	"International Release: Invalid sort-order information found\0" }
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 04a556b..2ab668a 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.509 2009/02/23 16:08:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.510 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -1871,7 +1871,7 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 	}
+ 	drec = &ird->records[icol - 1];
+ 
+-	tdsdump_log(TDS_DBG_INFO1, "odbc:SQLColAttribute: fDescType is %d\n", fDescType);
++	tdsdump_log(TDS_DBG_INFO1, "SQLColAttribute: fDescType is %d\n", fDescType);
+ 
+ 	switch (fDescType) {
+ 	case SQL_DESC_AUTO_UNIQUE_VALUE:
+@@ -2021,7 +2021,7 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 		IOUT(SQLSMALLINT, drec->sql_desc_updatable);
+ 		break;
+ 	default:
+-		tdsdump_log(TDS_DBG_INFO2, "odbc:SQLColAttribute: fDescType %d not catered for...\n", fDescType);
++		tdsdump_log(TDS_DBG_INFO2, "SQLColAttribute: fDescType %d not catered for...\n", fDescType);
+ 		odbc_errs_add(&stmt->errs, "HY091", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 		break;
+@@ -2352,7 +2352,7 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 		ODBC_RETURN(desc, SQL_NO_DATA);
+ 	drec = &desc->records[icol - 1];
+ 
+-	tdsdump_log(TDS_DBG_INFO1, "odbc:SQLGetDescField: fDescType is %d\n", fDescType);
++	tdsdump_log(TDS_DBG_INFO1, "SQLGetDescField: fDescType is %d\n", fDescType);
+ 
+ 	switch (fDescType) {
+ 	case SQL_DESC_AUTO_UNIQUE_VALUE:
+@@ -2567,7 +2567,7 @@ SQLSetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 	}
+ 	drec = &desc->records[icol - 1];
+ 
+-	tdsdump_log(TDS_DBG_INFO1, "odbc:SQLColAttributes: fDescType is %d\n", fDescType);
++	tdsdump_log(TDS_DBG_INFO1, "SQLColAttributes: fDescType is %d\n", fDescType);
+ 
+ 	switch (fDescType) {
+ 	case SQL_DESC_AUTO_UNIQUE_VALUE:
+@@ -3860,7 +3860,7 @@ _SQLFreeStmt(SQLHSTMT hstmt, SQLUSMALLINT fOption, int force)
+ 
+ 	/* check if option correct */
+ 	if (fOption != SQL_DROP && fOption != SQL_CLOSE && fOption != SQL_UNBIND && fOption != SQL_RESET_PARAMS) {
+-		tdsdump_log(TDS_DBG_ERROR, "odbc:SQLFreeStmt: Unknown option %d\n", fOption);
++		tdsdump_log(TDS_DBG_ERROR, "SQLFreeStmt: Unknown option %d\n", fOption);
+ 		odbc_errs_add(&stmt->errs, "HY092", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -4874,7 +4874,7 @@ SQLGetFunctions(SQLHDBC hdbc, SQLUSMALLINT fFunction, SQLUSMALLINT FAR * pfExist
+ #endif
+ 
+ 	case SQL_API_ALL_FUNCTIONS:
+-		tdsdump_log(TDS_DBG_FUNC, "odbc:SQLGetFunctions: " "fFunction is SQL_API_ALL_FUNCTIONS\n");
++		tdsdump_log(TDS_DBG_FUNC, "SQLGetFunctions: " "fFunction is SQL_API_ALL_FUNCTIONS\n");
+ 		for (i = 0; i < 100; ++i) {
+ 			pfExists[i] = SQL_FALSE;
+ 		}
+@@ -6671,7 +6671,7 @@ odbc_log_unimplemented_type(const char function_name[], int fType)
+ 		break;
+ 	}
+ 
+-	tdsdump_log(TDS_DBG_INFO1, "odbc: not implemented: %s: option/type %d(%s) [category %s]\n", function_name, fType, name,
++	tdsdump_log(TDS_DBG_INFO1, "not implemented: %s: option/type %d(%s) [category %s]\n", function_name, fType, name,
+ 		    category);
+ 
+ 	return;
+diff --git a/src/tds/config.c b/src/tds/config.c
+index a7979ec..8baab11 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.142 2009/03/06 14:32:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.143 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -84,7 +84,7 @@ static void tds_config_env_tdsver(TDSCONNECTION * connection);
+ static void tds_config_env_tdsport(TDSCONNECTION * connection);
+ static void tds_config_env_tdshost(TDSCONNECTION * connection);
+ static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
+-static void tds_read_interfaces(const char *server, TDSCONNECTION * connection);
++static int tds_read_interfaces(const char *server, TDSCONNECTION * connection);
+ static int tds_config_boolean(const char *value);
+ static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
+ static int tds_lookup_port(const char *portname);
+@@ -192,7 +192,11 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 	if (!tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name))) {
+ 		/* fallback to interfaces file */
+ 		tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file.  Trying interface files.\n");
+-		tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection);
++		if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) {
++			tdsdump_log(TDS_DBG_INFO1, "Failed to find [%s] in configuration files; trying '%s' instead.\n", 
++						   tds_dstr_cstr(&login->server_name), tds_dstr_cstr(&connection->server_name));
++			tdserror(tds->tds_ctx, tds, TDSEINTF, 0);
++		}
+ 	}
+ 
+ 	/* Override config file settings with environment variables. */
+@@ -200,7 +204,7 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 
+ 	/* And finally apply anything from the login structure */
+ 	tds_config_login(connection, login);
+-
++	
+ 	if (opened) {
+ 		tdsdump_log(TDS_DBG_INFO1, "Final connection parameters:\n");
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_name", tds_dstr_cstr(&connection->server_name));
+@@ -235,6 +239,16 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 
+ 		tdsdump_close();
+ 	}
++
++	/*
++	 * If a dump file has been specified, start logging
++	 */
++	if (!tds_dstr_isempty(&connection->dump_file) && !tdsdump_isopen()) {
++		if (connection->debug_flags)
++			tds_debug_flags = connection->debug_flags;
++		tdsdump_open(tds_dstr_cstr(&connection->dump_file));
++	}
++
+ 	return connection;
+ }
+ 
+@@ -744,8 +758,9 @@ tds_set_interfaces_file_loc(const char *interf)
+ }
+ 
+ /**
+- * Given a servername lookup the hostname. The server ip will be stored 
+- * in the string 'ip' in dotted-decimal notation.
++ * Get the IP address for a hostname. Store server's IP address 
++ * in the string 'ip' in dotted-decimal notation.  (The "hostname" might itself
++ * be a dotted-decimal address.  
+  *
+  * If we can't determine the IP address then 'ip' will be set to empty
+  * string.
+@@ -765,8 +780,8 @@ tds_lookup_host(const char *servername,	/* (I) name of the server
+ 	int h_errnop;
+ 
+ 	/*
+-	 * Only call gethostbyname if servername is not an ip address. 
+-	 * This call take a while and is useless for an ip address.
++	 * Call gethostbyname(3) only if servername is not an ip address. 
++	 * This call takes a while and is useless for an ip address.
+ 	 * mlilback 3/2/02
+ 	 */
+ 	ip_addr = inet_addr(servername);
+@@ -783,7 +798,7 @@ tds_lookup_host(const char *servername,	/* (I) name of the server
+ 
+ 		tds_inet_ntoa_r(*ptr, ip, 17);
+ 	}
+-}				/* tds_lookup_host()  */
++}
+ 
+ /**
+  * Given a portname lookup the port.
+@@ -952,7 +967,7 @@ search_interface_file(TDSCONNECTION * connection, const char *dir, const char *f
+  *
+  * @note This function uses only the interfaces file and is deprecated.
+  */
+-static void
++static int
+ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ {
+ 	int found = 0;
+@@ -1045,7 +1060,7 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 			tdsdump_log(TDS_DBG_INFO1, "Setting 'ip_port' to %d as a guess.\n", ip_port);
+ 
+ 		/*
+-		 * lookup the host
++		 * look up the host
+ 		 */
+ 		tds_lookup_host(server, ip_addr);
+ 		if (ip_addr[0]) {
+@@ -1055,6 +1070,8 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 		if (ip_port)
+ 			connection->port = ip_port;
+ 	}
++
++	return found;
+ }
+ 
+ /**
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 8da8d10..ccaa74b 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.182 2009/02/28 17:38:50 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.183 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -426,6 +426,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	/* verify that ip_addr is not empty */
+ 	if (tds_dstr_isempty(&connection->ip_addr)) {
++		tdserror(tds->tds_ctx, tds, TDSEUHST, 0 );
+ 		tdsdump_log(TDS_DBG_ERROR, "IP address pointer is empty\n");
+ 		if (!tds_dstr_isempty(&connection->server_name)) {
+ 			tdsdump_log(TDS_DBG_ERROR, "Server %s not found!\n", tds_dstr_cstr(&connection->server_name));
+diff --git a/src/tds/util.c b/src/tds/util.c
+index 679c404..6b6cd48 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.85 2008/12/16 09:21:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.86 2009/04/18 19:35:38 jklowden Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -268,8 +268,10 @@ static const TDS_ERROR_MESSAGE tds_error_messages[] =
+ 	, { TDSEREAD,              EXCOMM,	"Read from the server failed" }
+ 	, { TDSETIME,              EXTIME,	"Adaptive Server connection timed out" }
+ 	, { TDSESEOF,              EXCOMM,	"Unexpected EOF from the server" }
++	, { TDSEINTF,          	   EXUSER,	"Server name not found in configuration files." }
+ 	, { TDSESOCK,              EXCOMM,	"Unable to open socket" }
+ 	, { TDSESYNC,              EXCOMM,	"Read attempted while out of synchronization with Adaptive Server" }
++	, { TDSEUHST,	           EXUSER,	"Unknown host machine name." }
+ 	, { TDSEUMSG,              EXCOMM,	"Unknown message-id in MSG datastream" }
+ 	, { TDSEUSCT,              EXCOMM,	"Unable to set communications timer" }
+ 	, { TDSEUTDS,              EXCOMM,	"Unrecognized TDS version received from the server" }
+
+commit 1539dc8b8239e465008d677821e2e74c7a0692b2
+Author: freddy77 <freddy77>
+Date:   Mon Apr 20 08:56:17 2009 +0000
+
+    fix dblib timeout test
+
+diff --git a/ChangeLog b/ChangeLog
+index 629cef5..9188644 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Apr 20 10:55:17 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix timeout test
++
+ Sat Apr 18 15:18:39 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/sybdb.h include/tds.h
+ 	* src/apps/bsqldb.c src/apps/tsql.c
+@@ -1491,4 +1494,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2772 2009/04/18 19:35:38 jklowden Exp $
++$Id: ChangeLog,v 1.2773 2009/04/20 08:56:17 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 4561669..eece52d 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.347 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.348 2009/04/20 08:56:18 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4547,8 +4547,6 @@ RETCODE
+ dbsqlok(DBPROCESS * dbproc)
+ {
+ 	TDSSOCKET *tds;
+-
+-	unsigned char marker;
+ 	int done = 0, done_flags;
+ 	TDS_INT result_type;
+ 
+@@ -4572,14 +4570,6 @@ dbsqlok(DBPROCESS * dbproc)
+ 	 * We're looking for a result token or a done token.
+          */
+ 	while (!done) {
+-		marker = tds_peek(tds);
+-
+-		/* If we hit a result token, then we know everything is OK.  */
+-		if (is_result_token(marker)) {
+-			tdsdump_log(TDS_DBG_FUNC, "dbsqlok() exits on result token 0x%x\n", marker);
+-			return SUCCEED;
+-		}
+-
+ 		/* 
+ 		 * If we hit an end token -- e.g. if the command
+ 		 * submitted returned no data (like an insert) -- then
+@@ -4591,6 +4581,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 			return SUCCEED;
+ 			break;
+ 
++		case TDS_CANCELLED:
+ 		case TDS_FAIL:
+ 			return FAIL;
+ 			break;
+
+commit df67f05ccef39b01f83d6d445f5d0192b635db85
+Author: freddy77 <freddy77>
+Date:   Tue Apr 21 09:44:30 2009 +0000
+
+    added windows batch for dblib tests
+
+diff --git a/ChangeLog b/ChangeLog
+index 9188644..5785f93 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Apr 21 11:43:31 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/prepare_win32.sh: batch for dblib tests
++
+ Mon Apr 20 10:55:17 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: fix timeout test
+ 
+@@ -1494,4 +1497,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2773 2009/04/20 08:56:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2774 2009/04/21 09:44:30 freddy77 Exp $
+diff --git a/misc/prepare_win32.sh b/misc/prepare_win32.sh
+index 8516b3a..519e6ba 100755
+--- a/misc/prepare_win32.sh
++++ b/misc/prepare_win32.sh
+@@ -330,6 +330,7 @@ if "%OK%"=="1" type out.txt >> ok.txt
+ :fine
+ ' > src/odbc/unittests/go.bat
+ unix2dos src/odbc/unittests/go.bat
++ln src/odbc/unittests/go.bat src/dblib/unittests/go.bat
+ 
+ cd ..
+ eval "$ARCHIVE"
+
+commit ced4e9e45fb2b59bf9d86cdb0412ee5225901514
+Author: freddy77 <freddy77>
+Date:   Tue Apr 21 13:41:05 2009 +0000
+
+    improve sybase build script
+
+diff --git a/ChangeLog b/ChangeLog
+index 5785f93..1eadb31 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Apr 21 15:39:35 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/sybase_tests: improve
++
+ Tue Apr 21 11:43:31 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/prepare_win32.sh: batch for dblib tests
+ 
+@@ -1497,4 +1500,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2774 2009/04/21 09:44:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2775 2009/04/21 13:41:05 freddy77 Exp $
+diff --git a/misc/sybase_tests b/misc/sybase_tests
+index 35c4924..1bb59d9 100755
+--- a/misc/sybase_tests
++++ b/misc/sybase_tests
+@@ -1,6 +1,6 @@
+ #!/bin/bash
+ 
+-# $Id: sybase_tests,v 1.2 2009/04/17 17:16:28 freddy77 Exp $
++# $Id: sybase_tests,v 1.3 2009/04/21 13:41:07 freddy77 Exp $
+ # these commands build dblib tests using Sybase dblib
+ 
+ errore() {
+@@ -22,29 +22,24 @@ set -e
+ make -j4
+ TESTS_ENVIRONMENT=true make -j4 check
+ 
+-handle_exit() {
+-	echo Exiting
+-	if test -r "$MAINDIR/src/dblib/unittests/Makefile.no_sybase"; then
+-		cp -f "$MAINDIR/src/dblib/unittests/Makefile.no_sybase" "$MAINDIR/src/dblib/unittests/Makefile" && rm -f "$MAINDIR/src/dblib/unittests/Makefile.no_sybase"
+-	fi
+-	rm -f "$MAINDIR/src/dblib/unittests/sqlfront.h" "$MAINDIR/src/dblib/unittests/sqldb.h"
+-}
+-
+ # rebuild tests
+ cd src/dblib/unittests
+-rm -f *.o *.exe
+-make clean
++if test ! -r Makefile.no_sybase -o Makefile -nt Makefile.no_sybase; then
++	rm -f Makefile.no_sybase
++	echo '#include <sybfront.h>' > sqlfront.h
++	echo '#include <sybdb.h>' > sqldb.h
++	perl -pi.no_sybase -e "\$_ =~ s{ -I\\\$\\(top_(build|src)dir\\)/include}{ -I$SYBASE/$OCSDIR/include -I\\\$(top_builddir)/include} if (/^(DEFAULT_INCLUDES|AM_CPPFLAGS)\s*=/);
++\$_ =~ s{../libsybdb.la}{-lsybdb -lsybunic} if (/^LIBS\s*=/);
++\$_ =~ s{-L../.libs -R \\\$\\(abs_builddir\\)/../.libs}{-L$SYBASE/$OCSDIR/lib} if (/^AM_LDFLAGS\s*=/);
++" Makefile
++	touch Makefile.no_sybase
++	rm -f *.o *.exe
++	make clean
++fi
+ if test "$LD_RUN_PATH" != ""; then
+ 	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib:$LD_RUN_PATH"
+ else
+ 	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib"
+ fi
+-trap handle_exit EXIT
+-echo '#include <sybfront.h>' > sqlfront.h
+-echo '#include <sybdb.h>' > sqldb.h
+-perl -pi.no_sybase -e "\$_ =~ s{ -I\\\$\\(top_(build|src)dir\\)/include}{ -I$SYBASE/$OCSDIR/include -I\\\$(top_builddir)/include} if (/^(DEFAULT_INCLUDES|AM_CPPFLAGS)\s*=/);
+-\$_ =~ s{../libsybdb.la}{-lsybdb -lsybunic} if (/^LIBS\s*=/);
+-\$_ =~ s{-L../.libs -R \\\$\\(abs_builddir\\)/../.libs}{-L$SYBASE/$OCSDIR/lib} if (/^AM_LDFLAGS\s*=/);
+-" Makefile
+ TESTS_ENVIRONMENT=true make -j4 check 
+ 
+
+commit 5361c48b49c4f484de93adadbc973d24f5de1668
+Author: freddy77 <freddy77>
+Date:   Wed Apr 22 15:11:20 2009 +0000
+
+    fix dblib t0008 test
+
+diff --git a/ChangeLog b/ChangeLog
+index 1eadb31..0e43c5e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Apr 22 17:11:00 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0008.c: fix test
++
+ Tue Apr 21 15:39:35 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/sybase_tests: improve
+ 
+@@ -1500,4 +1503,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2775 2009/04/21 13:41:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2776 2009/04/22 15:11:20 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0008.c b/src/dblib/unittests/t0008.c
+index f054dca..6a7ea84 100644
+--- a/src/dblib/unittests/t0008.c
++++ b/src/dblib/unittests/t0008.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0008.c,v 1.18 2009/02/01 22:29:39 jklowden Exp $";
++static char software_version[] = "$Id: t0008.c,v 1.19 2009/04/22 15:11:20 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -13,7 +13,7 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int
+ main(int argc, char **argv)
+ {
+-	const int rows_to_add = 50;
++	const int rows_to_add = 48;
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+ 	int i;
+@@ -69,7 +69,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	fprintf(stdout, "insert\n");
+-	for (i = 1; i < rows_to_add; i++) {
++	for (i = 1; i <= rows_to_add; i++) {
+ 	char cmd[1024];
+ 
+ 		sprintf(cmd, "insert into #dblib0008 values (%d, 'row %03d')", i, i);
+@@ -107,7 +107,7 @@ main(int argc, char **argv)
+ 
+ 	add_bread_crumb();
+ 
+-	for (i = 1; i < rows_to_add; i++) {
++	for (i = 1; i <= rows_to_add; i++) {
+ 	char expected[1024];
+ 
+ 		sprintf(expected, "row %03d", i);
+@@ -159,8 +159,8 @@ main(int argc, char **argv)
+ 	dbexit();
+ 	add_bread_crumb();
+ 
+-	fprintf(stdout, "%s %s (last_read: %d)\n", __FILE__, ((last_read != rows_to_add - 1)? "failed!" : "OK"), (int) last_read);
++	fprintf(stdout, "%s %s (last_read: %d)\n", __FILE__, ((last_read != rows_to_add)? "failed!" : "OK"), (int) last_read);
+ 
+ 	free_bread_crumb();
+-	return (last_read == rows_to_add - 1) ? 0 : 1;
++	return (last_read == rows_to_add) ? 0 : 1;
+ }
+
+commit 7b9d2616719f7ad8d0be41536a001cc1e0246de8
+Author: freddy77 <freddy77>
+Date:   Thu Apr 23 09:36:26 2009 +0000
+
+    fix t0002 dblib test
+
+diff --git a/ChangeLog b/ChangeLog
+index 0e43c5e..005a697 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 23 11:36:05 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0002.c: fix test
++
+ Wed Apr 22 17:11:00 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0008.c: fix test
+ 
+@@ -1503,4 +1506,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2776 2009/04/22 15:11:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2777 2009/04/23 09:36:26 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0002.c b/src/dblib/unittests/t0002.c
+index aaba66b..e9e674d 100644
+--- a/src/dblib/unittests/t0002.c
++++ b/src/dblib/unittests/t0002.c
+@@ -10,7 +10,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.24 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.25 2009/04/23 09:36:26 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int failed = 0;
+@@ -44,6 +44,7 @@ main(int argc, char **argv)
+ 	STATUS rc;
+ 	int i, iresults;
+ 	char teststr[1024];
++	int rows_in_buffer, limit_rows;
+ 
+ 	const int buffer_count = 10;
+ 	const int rows_to_add = 50;
+@@ -129,6 +130,7 @@ main(int argc, char **argv)
+ 				fprintf(stderr, "Buffering with multiple resultsets is broken.\n");
+ 			exit(1);
+ 		}
++		rows_in_buffer = 0;
+ 		add_bread_crumb();
+ 
+ 		for (i = 1; i <= dbnumcols(dbproc); i++) {
+@@ -144,11 +146,21 @@ main(int argc, char **argv)
+ 		add_bread_crumb();
+ 
+ 		/* Fetch a result set */
+-		/* Second resultset stops at row 40 */
+-		for (i=0; i < rows_to_add - (iresults == 2 ? buffer_count : 0);) {
++		/* Second resultset stops at row 46 */
++		limit_rows = rows_to_add - (iresults == 2 ? 4 : 0);
++		for (i=0; i < limit_rows;) {
+ 
+-			fprintf(stdout, "clearing %d rows from buffer\n", buffer_count);
++			fprintf(stdout, "clearing %d rows from buffer\n", rows_in_buffer ? buffer_count - 1 : buffer_count);
++#ifdef MICROSOFT_DBLIB
++			if (i == 0) {
++				rc = dbnextrow(dbproc);
++				assert(rc == REG_ROW);
++				++i;
++				rows_in_buffer = 1;
++			}
++#endif
+ 			dbclrbuf(dbproc, buffer_count);
++			rows_in_buffer = rows_in_buffer ? 1 : 0;
+ 
+ 			do {
+ 				int rc;
+@@ -162,15 +174,15 @@ main(int argc, char **argv)
+ 						fprintf(stderr, "Failed: dbnextrow returned BUF_FULL (%d).  Fix dbclrbuf.\n", rc);
+ 					exit(1);
+ 				}
++				++rows_in_buffer;
+ 				add_bread_crumb();
+ 				verify(i, testint, teststr);
+-			} while (i % buffer_count);
++			} while (rows_in_buffer < buffer_count && i < limit_rows);
+ 
+-			if (iresults == 1 && i == rows_to_add) {
++			if (rows_in_buffer == buffer_count) {
+ 				/* The buffer should be full */
+ 				assert(BUF_FULL == dbnextrow(dbproc));
+ 			}
+-				
+ 		}
+ 		if (iresults == 1) {
+ 			fprintf(stdout, "clearing %d rows from buffer\n", buffer_count);
+@@ -180,10 +192,11 @@ main(int argc, char **argv)
+ 			}
+ 		}
+ 	}
++	printf("\n");
+ 
+ 	/* 
+ 	 * Now test the buffered rows.  
+-	 * Should be operating on rows 31-40 of 2nd resultset 
++	 * Should be operating on rows 37-46 of 2nd resultset 
+ 	 */
+ 	rc = dbgetrow(dbproc, 1);
+ 	add_bread_crumb();
+@@ -191,50 +204,50 @@ main(int argc, char **argv)
+ 		fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc);
+ 	assert(rc == NO_MORE_ROWS);
+ 
+-	rc = dbgetrow(dbproc, 31);
++	rc = dbgetrow(dbproc, 37);
+ 	add_bread_crumb();
+ 	if(rc != REG_ROW)
+ 		fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc);
+ 	assert(rc == REG_ROW);
+-	verify(31, testint, teststr);	/* first buffered row should be 31 */
++	verify(37, testint, teststr);	/* first buffered row should be 37 */
+ 
+ 	rc = dbnextrow(dbproc);
+ 	add_bread_crumb();
+ 	if(rc != REG_ROW)
+ 		fprintf(stderr, "Failed: dbgetrow returned %d.\n", rc);
+ 	assert(rc == REG_ROW);
+-	verify(32, testint, teststr);	/* next buffered row should be 32 */
++	verify(38, testint, teststr);	/* next buffered row should be 38 */
+ 
+ 	rc = dbgetrow(dbproc, 11);
+ 	add_bread_crumb();
+ 	assert(rc == NO_MORE_ROWS);	/* only 10 (not 11) rows buffered */
+ 
+-	rc = dbgetrow(dbproc, 40);
++	rc = dbgetrow(dbproc, 46);
+ 	add_bread_crumb();
+ 	assert(rc == REG_ROW);
+-	verify(40, testint, teststr);	/* last buffered row should be 40 */
++	verify(46, testint, teststr);	/* last buffered row should be 46 */
+ 
+ 	/* Attempt dbnextrow when buffer has no space (10 out of 10 in use). */
+ 	rc = dbnextrow(dbproc);
+ 	assert(rc == BUF_FULL);
+ 
+-	dbclrbuf(dbproc, 3);		/* remove rows 31, 32, and 33 */
++	dbclrbuf(dbproc, 3);		/* remove rows 37, 38, and 39 */
+ 
+ 	rc = dbnextrow(dbproc);
+ 	add_bread_crumb();
+ 	assert(rc == REG_ROW);
+-	verify(41, testint, teststr);	/* fetch row from database, should be 41 */
++	verify(47, testint, teststr);	/* fetch row from database, should be 47 */
+ 
+ 	rc = dbnextrow(dbproc);
+ 	add_bread_crumb();
+ 	assert(rc == REG_ROW);
+-	verify(42, testint, teststr);	/* fetch row from database, should be 42 */
++	verify(48, testint, teststr);	/* fetch row from database, should be 48 */
+ 
+-	/* buffer contains 9 rows (34-42) try removing 10 rows */
++	/* buffer contains 8 rows (40-47) try removing 10 rows */
+ 	dbclrbuf(dbproc, buffer_count);
+ 
+ 	while (dbnextrow(dbproc) != NO_MORE_ROWS) {
+-		/* waste rows 43-50 */
++		/* waste rows 49-50 */
+ 	}
+ 
+ 	dbclose(dbproc); /* close while buffer not cleared: OK */
+
+commit 21f3111a1211a7468845494125a86723bbcdefae
+Author: freddy77 <freddy77>
+Date:   Thu Apr 23 09:41:08 2009 +0000
+
+    fix sybase_tests rebuild
+
+diff --git a/ChangeLog b/ChangeLog
+index 005a697..54e5d3b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 23 11:40:43 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/sybase_tests: fix rebuild
++
+ Thu Apr 23 11:36:05 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0002.c: fix test
+ 
+@@ -1506,4 +1509,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2777 2009/04/23 09:36:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2778 2009/04/23 09:41:08 freddy77 Exp $
+diff --git a/misc/sybase_tests b/misc/sybase_tests
+index 1bb59d9..1d13d16 100755
+--- a/misc/sybase_tests
++++ b/misc/sybase_tests
+@@ -1,6 +1,6 @@
+ #!/bin/bash
+ 
+-# $Id: sybase_tests,v 1.3 2009/04/21 13:41:07 freddy77 Exp $
++# $Id: sybase_tests,v 1.4 2009/04/23 09:41:08 freddy77 Exp $
+ # these commands build dblib tests using Sybase dblib
+ 
+ errore() {
+@@ -16,6 +16,12 @@ OCSDIR=`echo OCS-*`
+ cd "$MAINDIR"
+ test -d "$SYBASE/$OCSDIR" || errore "OCS directory not found"
+ 
++if test "$LD_RUN_PATH" != ""; then
++	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib:$LD_RUN_PATH"
++else
++	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib"
++fi
++
+ # build
+ trap 'echo Error at line $LINENO' ERR
+ set -e
+@@ -36,10 +42,5 @@ if test ! -r Makefile.no_sybase -o Makefile -nt Makefile.no_sybase; then
+ 	rm -f *.o *.exe
+ 	make clean
+ fi
+-if test "$LD_RUN_PATH" != ""; then
+-	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib:$LD_RUN_PATH"
+-else
+-	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib"
+-fi
+ TESTS_ENVIRONMENT=true make -j4 check 
+ 
+
+commit 53bd723bde835997d324142a1ddb8413c1ae7286
+Author: freddy77 <freddy77>
+Date:   Thu Apr 23 13:12:42 2009 +0000
+
+    fix row buffering
+
+diff --git a/ChangeLog b/ChangeLog
+index 54e5d3b..9f9f9d8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Thu Apr 23 15:12:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/buffering.h src/dblib/dblib.c:
++	- add internal test for buffering
++	- clear row number if deleted
++	- fix buffer_delete_rows
++	- fix dbclrbuf not clearing all rows
++
+ Thu Apr 23 11:40:43 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/sybase_tests: fix rebuild
+ 
+@@ -1509,4 +1516,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2778 2009/04/23 09:41:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2779 2009/04/23 13:12:42 freddy77 Exp $
+diff --git a/src/dblib/buffering.h b/src/dblib/buffering.h
+index 30526dc..4c9bf7b 100644
+--- a/src/dblib/buffering.h
++++ b/src/dblib/buffering.h
+@@ -13,6 +13,71 @@ static void buffer_struct_print(const DBPROC_ROWBUF *buf);
+ static int buffer_save_row(DBPROCESS *dbproc);
+ static DBLIB_BUFFER_ROW* buffer_row_address(const DBPROC_ROWBUF * buf, int idx);
+ 
++#if ENABLE_EXTRA_CHECKS
++static void buffer_check(const DBPROC_ROWBUF *buf)
++{
++	int i;
++
++	/* no buffering */
++	if (buf->capacity == 0 || buf->capacity == 1) {
++		assert(buf->head == 0);
++		assert(buf->tail == 0);
++		assert(buf->rows == NULL);
++		return;
++	}
++
++	assert(buf->capacity > 0);
++	assert(buf->head >= 0);
++	assert(buf->tail >= 0);
++	assert(buf->head < buf->capacity);
++	assert(buf->tail <= buf->capacity);
++
++	/* check empty */
++	if (buf->tail == buf->capacity) {
++		assert(buf->head == 0);
++		for (i = 0; buf->rows && i < buf->capacity; ++i) {
++			assert(buf->rows[i].resinfo == NULL);
++			assert(buf->rows[i].row_data == NULL);
++			assert(buf->rows[i].sizes == NULL);
++			assert(buf->rows[i].row == 0);
++		}
++		return;
++	}
++
++	if (buf->rows == NULL)
++		return;
++
++	/* check filled part */
++	i = buf->tail;
++	do {
++		assert(i >= 0 && i < buf->capacity);
++		assert(buf->rows[i].resinfo != NULL);
++		assert(buf->rows[i].row > 0);
++		assert(buf->rows[i].row <= buf->received);
++		++i;
++		if (i == buf->capacity)
++			i = 0;
++	} while (i != buf->head);
++
++	/* check empty part */
++	if (buf->head != buf->tail) {
++		i = buf->head;
++		do {
++			assert(i >= 0 && i < buf->capacity);
++			assert(buf->rows[i].resinfo == NULL);
++			assert(buf->rows[i].row_data == NULL);
++			assert(buf->rows[i].sizes == NULL);
++			assert(buf->rows[i].row == 0);
++			++i;
++			if (i == buf->capacity)
++				i = 0;
++		} while (i != buf->tail);
++	}
++}
++#define BUFFER_CHECK(buf) buffer_check(buf)
++#else
++#define BUFFER_CHECK(buf) do {} while(0)
++#endif
+ /** 
+  * A few words on the buffering design.
+  *
+@@ -45,6 +110,7 @@ static DBLIB_BUFFER_ROW* buffer_row_address(const DBPROC_ROWBUF * buf, int idx);
+ static int
+ buffer_count(const DBPROC_ROWBUF *buf)
+ {
++	BUFFER_CHECK(buf);
+ 	return (buf->head > buf->tail) ?
+ 		buf->head - buf->tail :				/* |...TddddH....| */
+ 		buf->capacity - (buf->tail - buf->head); 	/* |ddddH....Tddd| */
+@@ -56,6 +122,7 @@ buffer_count(const DBPROC_ROWBUF *buf)
+ static int
+ buffer_is_full(const DBPROC_ROWBUF *buf)
+ {
++	BUFFER_CHECK(buf);
+ 	return buf->capacity == buffer_count(buf) && buf->capacity > 1;
+ }
+ 
+@@ -63,6 +130,7 @@ buffer_is_full(const DBPROC_ROWBUF *buf)
+ static int
+ buffer_index_valid(const DBPROC_ROWBUF *buf, int idx)
+ {
++	BUFFER_CHECK(buf);
+ 	if (buf->tail <= buf->head)
+ 		if (buf->head <= idx && idx <= buf->tail)
+ 			return 1;
+@@ -91,6 +159,7 @@ buffer_free_row(DBLIB_BUFFER_ROW *row)
+ 	}
+ 	tds_free_results(row->resinfo);
+ 	row->resinfo = NULL;
++	row->row = 0;
+ }
+  
+ /*
+@@ -106,23 +175,26 @@ buffer_free_row(DBLIB_BUFFER_ROW *row)
+ static void
+ buffer_free(DBPROC_ROWBUF *buf)
+ {
++	BUFFER_CHECK(buf);
+ 	if (buf->rows != NULL) {
+ 		int i;
+ 		for (i = 0; i < buf->capacity; ++i)
+ 			buffer_free_row(&buf->rows[i]);
+ 		TDS_ZERO_FREE(buf->rows);
+ 	}
++	BUFFER_CHECK(buf);
+ }
+ 
+ /*
+  * When no rows are currently buffered (and the buffer is allocated)
+- * set the indices to their initial postions.
++ * set the indices to their initial positions.
+  */
+ static void
+ buffer_reset(DBPROC_ROWBUF *buf)
+ {
+ 	buf->head = 0;
+ 	buf->current = buf->tail = buf->capacity;
++	BUFFER_CHECK(buf);
+ }
+ 
+ static int
+@@ -141,13 +213,13 @@ buffer_idx_increment(const DBPROC_ROWBUF *buf, int idx)
+ static DBLIB_BUFFER_ROW*
+ buffer_row_address(const DBPROC_ROWBUF * buf, int idx)
+ {
+-	if (!(idx >= 0 && idx < buf->capacity)) {
++	BUFFER_CHECK(buf);
++	if (idx < 0 || idx >= buf->capacity) {
+ 		printf("idx is %d:\n", idx);
+ 		buffer_struct_print(buf);
+-		assert(idx >= 0);
+-		assert(idx < buf->capacity);
++		return NULL;
+ 	}
+-	
++
+ 	return &(buf->rows[idx]);
+ }
+ 
+@@ -157,6 +229,7 @@ buffer_row_address(const DBPROC_ROWBUF * buf, int idx)
+ static DBINT
+ buffer_idx2row(const DBPROC_ROWBUF *buf, int idx)
+ {
++	BUFFER_CHECK(buf);
+ 	return buffer_row_address(buf, idx)->row;
+ }
+ 
+@@ -167,7 +240,8 @@ static int
+ buffer_row2idx(const DBPROC_ROWBUF *buf, int row_number)
+ {
+ 	int i, ii, idx = -1;
+-	
++
++	BUFFER_CHECK(buf);
+ 	if (buf->tail == buf->capacity) {
+ 		assert (buf->head == 0);
+ 		return -1;	/* no rows buffered */
+@@ -189,26 +263,26 @@ buffer_row2idx(const DBPROC_ROWBUF *buf, int row_number)
+ }
+ 
+ /**
+- * Deleting a row doesn't from the buffer doesn't affect 
+- * memory allocation.  It just makes the space available 
+- * for a different row.  
++ * Deleting a row from the buffer doesn't affect memory allocation.
++ * It just makes the space available for a different row.
+  */
+ static void
+ buffer_delete_rows(DBPROC_ROWBUF * buf,	int count)
+ {
+ 	int i;
+ 
++	BUFFER_CHECK(buf);
+ 	if (count < 0 || count > buffer_count(buf)) {
+ 		count = buffer_count(buf);
+ 	}
+ 
+ 	for (i=0; i < count; i++) {
+ 		if (buf->tail < buf->capacity)
+-			buffer_free_row(&buf->rows[i]);
++			buffer_free_row(&buf->rows[buf->tail]);
+ 		buf->tail = buffer_idx_increment(buf, buf->tail);
+ 		/* 
+ 		 * If deleting rows from the buffer catches the tail to the head, 
+-		 * return to the initial postion.  Otherwise, it will look full.
++		 * return to the initial position.  Otherwise, it will look full.
+ 		 */
+ 		if (buf->tail == buf->head) {
+ 			buffer_reset(buf);
+@@ -218,6 +292,7 @@ buffer_delete_rows(DBPROC_ROWBUF * buf,	int count)
+ #if 0
+ 	buffer_struct_print(buf);
+ #endif
++	BUFFER_CHECK(buf);
+ }
+ 
+ static void
+@@ -229,6 +304,7 @@ buffer_transfer_bound_data(DBPROC_ROWBUF *buf, TDS_INT res_type, TDS_INT compute
+ 	const DBLIB_BUFFER_ROW *row;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "buffer_transfer_bound_data(%p %d %d %p %d)\n", buf, res_type, compute_id, dbproc, idx);
++	BUFFER_CHECK(buf);
+ 	assert(buffer_index_valid(buf, idx));
+ 
+ 	row = buffer_row_address(buf, idx);
+@@ -408,13 +484,6 @@ buffer_add_row(DBPROCESS *dbproc, TDSRESULTINFO *resinfo)
+ 	if (buffer_is_full(buf))
+ 		return -1;
+ 
+-	/* initial condition is head == 0 and tail == capacity */
+-	if (buf->tail == buf->capacity) {
+-		/* bumping this tail will set it to zero */
+-		assert(buf->head == 0);
+-		buf->tail = buffer_idx_increment(buf, buf->tail);
+-	}
+-
+ 	row = buffer_row_address(buf, buf->head);
+ 
+ 	/* bump the row number, write it, and move the data to head */
+@@ -432,6 +501,13 @@ buffer_add_row(DBPROCESS *dbproc, TDSRESULTINFO *resinfo)
+ 	for (i = 0; i < resinfo->num_cols; ++i)
+ 		row->sizes[i] = resinfo->columns[i]->column_cur_size;
+ 
++	/* initial condition is head == 0 and tail == capacity */
++	if (buf->tail == buf->capacity) {
++		/* bumping this tail will set it to zero */
++		assert(buf->head == 0);
++		buf->tail = 0;
++	}
++
+ 	/* update current, bump the head */
+ 	buf->current = buf->head;
+ 	buf->head = buffer_idx_increment(buf, buf->head);
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index eece52d..c268aa6 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.348 2009/04/20 08:56:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.349 2009/04/23 13:12:43 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -2723,6 +2723,10 @@ dbclrbuf(DBPROCESS * dbproc, DBINT n)
+ 		return;
+ 
+ 	if (dbproc->dbopts[DBBUFFER].factive) {
++		DBPROC_ROWBUF * buf = &(dbproc->row_buf);
++		int count = buffer_count(buf);
++		if (n >= count)
++			n = count - 1;
+ 		buffer_delete_rows(&(dbproc->row_buf), n);
+ 	}
+ }
+
+commit 01246f2b79b46a6dea3435b044c1ba5146816d8a
+Author: freddy77 <freddy77>
+Date:   Thu Apr 23 13:29:40 2009 +0000
+
+    small script fix
+
+diff --git a/ChangeLog b/ChangeLog
+index 9f9f9d8..e0d4b45 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 23 15:29:30 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/commit: small fix
++
+ Thu Apr 23 15:12:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/buffering.h src/dblib/dblib.c:
+ 	- add internal test for buffering
+@@ -1516,4 +1519,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2779 2009/04/23 13:12:42 freddy77 Exp $
++$Id: ChangeLog,v 1.2780 2009/04/23 13:29:40 freddy77 Exp $
+diff --git a/misc/commit b/misc/commit
+index 1382f88..2bcfba0 100755
+--- a/misc/commit
++++ b/misc/commit
+@@ -1,6 +1,6 @@
+ #!/usr/bin/perl
+ 
+-# $Id: commit,v 1.5 2009/03/27 09:24:48 freddy77 Exp $
++# $Id: commit,v 1.6 2009/04/23 13:29:40 freddy77 Exp $
+ 
+ use strict;
+ 
+@@ -63,7 +63,7 @@ sub parseLine($)
+ 	# anything after : or - is a comment
+ 	if ($line =~ /(.*?)(:|- )(.*)/) {
+ 		($line, $comment) = ($1, $3);
+-		push(@lastComments, '') if $2 eq '-';
++		push(@lastComments, '') if $2 eq '- ';
+ 		print "line $line comment $comment\n" if $debug;
+ 	}
+ 
+
+commit 5d261e80208340fa67a7c724150dd8b57b2c2243
+Author: freddy77 <freddy77>
+Date:   Thu Apr 30 06:48:49 2009 +0000
+
+    notes and updates
+
+diff --git a/ChangeLog b/ChangeLog
+index e0d4b45..c94f79d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr 30 08:48:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/check_symbols.txt misc/order_coverage.pl: notes and updates
++
+ Thu Apr 23 15:29:30 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/commit: small fix
+ 
+@@ -1519,4 +1522,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2780 2009/04/23 13:29:40 freddy77 Exp $
++$Id: ChangeLog,v 1.2781 2009/04/30 06:48:49 freddy77 Exp $
+diff --git a/misc/check_symbols.txt b/misc/check_symbols.txt
+index 90419ee..c902c46 100644
+--- a/misc/check_symbols.txt
++++ b/misc/check_symbols.txt
+@@ -158,7 +158,7 @@ tds_quote_string
+ tds_read_conf_file
+ tds_read_conf_section
+ tds_read_config_info
+-tds_read_packet
++!tds_read_packet
+ tds_realloc_socket
+ tds_release_cursor
+ tds_send_cancel
+diff --git a/misc/order_coverage.pl b/misc/order_coverage.pl
+index 4afa2e3..a219485 100755
+--- a/misc/order_coverage.pl
++++ b/misc/order_coverage.pl
+@@ -1,6 +1,7 @@
+ #!/usr/bin/perl
+ 
+-# $Id: order_coverage.pl,v 1.1 2008/08/28 09:34:46 freddy77 Exp $
++# $Id: order_coverage.pl,v 1.2 2009/04/30 06:48:50 freddy77 Exp $
++# This utility create some sorted version of GCOV results
+ 
+ %processed = ();
+ @to_process = ();
+
+commit e0be8f2abff27c28b9c59b2836d00c07f0b6bbb9
+Author: jklowden <jklowden>
+Date:   Sun May 3 19:32:56 2009 +0000
+
+    better ct-lib logging
+
+diff --git a/BUGS b/BUGS
+index 4c762a1..f454d77 100644
+--- a/BUGS
++++ b/BUGS
+@@ -15,7 +15,7 @@ Needs Fixing
+    this requires either an SQL parser or API modification, 
+    because the library has to determine the SQL datatype 
+    of the placeholder variable.  
+-6. ML Mar 19 2009: "Error in freebcp in", spurious error. 
++6. ML Mar 21 2009: "freebcp error HINT -b doesnt work", freebcp -n broken. 
+ 
+ 
+ 
+diff --git a/ChangeLog b/ChangeLog
+index c94f79d..ef05c21 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Sun May  3 15:26:26 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/blk.c src/ctlib/cs.c src/ctlib/ct.c
++	* src/ctlib/ctutil.c src/ctlib/unittests/common.c
++	* src/dblib/dbutil.c BUGS
++	- better ct-lib logging
++
+ Thu Apr 30 08:48:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/check_symbols.txt misc/order_coverage.pl: notes and updates
+ 
+@@ -1522,4 +1528,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2781 2009/04/30 06:48:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2782 2009/05/03 19:32:56 jklowden Exp $
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 7d0a25b..d0eb7d9 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,7 +38,7 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.49 2008/12/19 10:37:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.50 2009/05/03 19:32:57 jklowden Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+@@ -48,7 +48,7 @@ static CS_RETCODE _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS
+ CS_RETCODE
+ blk_alloc(CS_CONNECTION * connection, CS_INT version, CS_BLKDESC ** blk_pointer)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "blk_alloc()\n");
++	tdsdump_log(TDS_DBG_FUNC, "blk_alloc(%p, %d, %p)\n", connection, version, blk_pointer);
+ 
+ 	*blk_pointer = (CS_BLKDESC *) malloc(sizeof(CS_BLKDESC));
+ 	memset(*blk_pointer, '\0', sizeof(CS_BLKDESC));
+@@ -68,7 +68,7 @@ blk_bind(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buff
+ 	CS_INT bind_count;
+ 	int i;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "blk_bind()\n");
++	tdsdump_log(TDS_DBG_FUNC, "blk_bind(%p, %d, %p, %p, %p, %p)\n", blkdesc, item, datafmt, buffer, datalen, indicator);
+ 
+ 	if (!blkdesc) {
+ 		return CS_FAIL;
+@@ -155,6 +155,9 @@ blk_colval(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp, CS_INT
+ 	   CS_INT * outlenp)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "blk_colval(%p, %p, %p, %d, %p, %d, %p)\n", 
++				srvproc, blkdescp, rowp, colnum, valuep, valuelen, outlenp);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_colval()\n");
+ 	return CS_FAIL;
+ }
+@@ -163,6 +166,8 @@ CS_RETCODE
+ blk_default(CS_BLKDESC * blkdesc, CS_INT colnum, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "blk_default(%p, %d, %p, %d, %p)\n", blkdesc, colnum, buffer, buflen, outlen);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_default()\n");
+ 	return CS_FAIL;
+ }
+@@ -173,7 +178,7 @@ blk_describe(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt)
+ 	TDSCOLUMN *curcol;
+ 	int len;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "blk_describe()\n");
++	tdsdump_log(TDS_DBG_FUNC, "blk_describe(%p, %d, %p)\n", blkdesc, item, datafmt);
+ 
+ 	if (item < 1 || item > blkdesc->bcpinfo.bindinfo->num_cols) {
+ 		_ctclient_msg(blkdesc->con, "blk_describe", 2, 5, 1, 141, "%s, %d", "colnum", item);
+@@ -220,7 +225,8 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow)
+ 	TDSSOCKET *tds;
+ 	int rows_copied;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "blk_done()\n");
++	tdsdump_log(TDS_DBG_FUNC, "blk_done(%p, %d, %p)\n", blkdesc, type, outrow);
++
+ 	tds = blkdesc->con->tds_socket;
+ 
+ 	switch (type) {
+@@ -276,6 +282,8 @@ blk_done(CS_BLKDESC * blkdesc, CS_INT type, CS_INT * outrow)
+ CS_RETCODE
+ blk_drop(CS_BLKDESC * blkdesc)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_drop(%p)\n", blkdesc);
++
+ 	if (!blkdesc)
+ 		return CS_SUCCEED;
+ 
+@@ -290,6 +298,7 @@ blk_drop(CS_BLKDESC * blkdesc)
+ CS_RETCODE
+ blk_getrow(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_getrow(%p, %p, %p)\n", srvproc, blkdescp, rowp);
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_getrow()\n");
+ 	return CS_FAIL;
+@@ -299,6 +308,8 @@ CS_RETCODE
+ blk_gettext(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp, CS_INT bufsize, CS_INT * outlenp)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "blk_gettext(%p, %p, %p, %d, %p)\n", srvproc, blkdescp, rowp, bufsize, outlenp);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_gettext()\n");
+ 	return CS_FAIL;
+ }
+@@ -306,7 +317,7 @@ blk_gettext(SRV_PROC * srvproc, CS_BLKDESC * blkdescp, CS_BLK_ROW * rowp, CS_INT
+ CS_RETCODE
+ blk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tnamelen)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "blk_init()\n");
++	tdsdump_log(TDS_DBG_FUNC, "blk_init(%p, %d, %p, %d)\n", blkdesc, direction, tablename, tnamelen);
+ 
+ 	if (!blkdesc) {
+ 		return CS_FAIL;
+@@ -365,9 +376,9 @@ blk_init(CS_BLKDESC * blkdesc, CS_INT direction, CS_CHAR * tablename, CS_INT tna
+ CS_RETCODE
+ blk_props(CS_BLKDESC * blkdesc, CS_INT action, CS_INT property, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen)
+ {
++	int retval, intval;
+ 
+-	int retval;
+-	int intval;
++	tdsdump_log(TDS_DBG_FUNC, "blk_props(%p, %d, %d, %p, %d, %p)\n", blkdesc, action, property, buffer, buflen, outlen);
+ 
+ 	switch (property) {
+ 	case BLK_IDENTITY: 
+@@ -407,6 +418,7 @@ blk_props(CS_BLKDESC * blkdesc, CS_INT action, CS_INT property, CS_VOID * buffer
+ CS_RETCODE
+ blk_rowalloc(SRV_PROC * srvproc, CS_BLK_ROW ** row)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_rowalloc(%p, %p)\n", srvproc, row);
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_rowalloc()\n");
+ 	return CS_FAIL;
+@@ -415,6 +427,7 @@ blk_rowalloc(SRV_PROC * srvproc, CS_BLK_ROW ** row)
+ CS_RETCODE
+ blk_rowdrop(SRV_PROC * srvproc, CS_BLK_ROW * row)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_rowdrop(%p, %p)\n", srvproc, row);
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_rowdrop()\n");
+ 	return CS_FAIL;
+@@ -425,6 +438,8 @@ blk_rowxfer(CS_BLKDESC * blkdesc)
+ {
+ 	CS_INT row_count = 1;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "blk_rowxfer(%p)\n", blkdesc);
++
+ 	return blk_rowxfer_mult(blkdesc, &row_count);
+ }
+ 
+@@ -435,7 +450,7 @@ blk_rowxfer_mult(CS_BLKDESC * blkdesc, CS_INT * row_count)
+ 	CS_INT rows_xferred = 0;
+ 	CS_RETCODE ret;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "blk_rowxfer_mult()\n");
++	tdsdump_log(TDS_DBG_FUNC, "blk_rowxfer_mult(%p, %p)\n", blkdesc, row_count);
+ 
+ 	if (!row_count || *row_count == 0 )
+ 		rows_to_xfer = blkdesc->bcpinfo.bind_count;
+@@ -457,6 +472,8 @@ CS_RETCODE
+ blk_sendrow(CS_BLKDESC * blkdesc, CS_BLK_ROW * row)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "blk_sendrow(%p, %p)\n", blkdesc, row);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_sendrow()\n");
+ 	return CS_FAIL;
+ }
+@@ -464,6 +481,7 @@ blk_sendrow(CS_BLKDESC * blkdesc, CS_BLK_ROW * row)
+ CS_RETCODE
+ blk_sendtext(CS_BLKDESC * blkdesc, CS_BLK_ROW * row, CS_BYTE * buffer, CS_INT buflen)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_sendtext(%p, %p, %p, %d)\n", blkdesc, row, buffer, buflen);
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_sendtext()\n");
+ 	return CS_FAIL;
+@@ -472,6 +490,7 @@ blk_sendtext(CS_BLKDESC * blkdesc, CS_BLK_ROW * row, CS_BYTE * buffer, CS_INT bu
+ CS_RETCODE
+ blk_srvinit(SRV_PROC * srvproc, CS_BLKDESC * blkdescp)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_srvinit(%p, %p)\n", srvproc, blkdescp);
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_srvinit()\n");
+ 	return CS_FAIL;
+@@ -480,6 +499,7 @@ blk_srvinit(SRV_PROC * srvproc, CS_BLKDESC * blkdescp)
+ CS_RETCODE
+ blk_textxfer(CS_BLKDESC * blkdesc, CS_BYTE * buffer, CS_INT buflen, CS_INT * outlen)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "blk_textxfer(%p, %p, %d, %p)\n", blkdesc, buffer, buflen, outlen);
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED blk_textxfer()\n");
+ 	return CS_FAIL;
+@@ -488,7 +508,6 @@ blk_textxfer(CS_BLKDESC * blkdesc, CS_BYTE * buffer, CS_INT buflen, CS_INT * out
+ static CS_RETCODE
+ _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred)
+ {
+-
+ 	TDSSOCKET *tds;
+ 	TDS_INT result_type;
+ 	TDS_INT ret;
+@@ -496,7 +515,7 @@ _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferre
+ 	TDS_INT row_of_query;
+ 	TDS_INT rows_written;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "blk_rowxfer_out()\n");
++	tdsdump_log(TDS_DBG_FUNC, "_blk_rowxfer_out(%p, %d, %p)\n", blkdesc, rows_to_xfer, rows_xferred);
+ 
+ 	if (!blkdesc || !blkdesc->con)
+ 		return CS_FAIL;
+@@ -569,10 +588,11 @@ _blk_rowxfer_out(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferre
+ static CS_RETCODE
+ _blk_rowxfer_in(CS_BLKDESC * blkdesc, CS_INT rows_to_xfer, CS_INT * rows_xferred)
+ {
+-
+ 	TDSSOCKET *tds;
+ 	TDS_INT each_row;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_blk_rowxfer_in(%p, %d, %p)\n", blkdesc, rows_to_xfer, rows_xferred);
++
+ 	if (!blkdesc)
+ 		return CS_FAIL;
+ 
+@@ -613,6 +633,9 @@ static void
+ _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset)
+ {
+ 	CS_BLKDESC *blkdesc = (CS_BLKDESC *) bcpinfo->parent;
++
++	tdsdump_log(TDS_DBG_FUNC, "_blk_null_error(%p, %d, %d)\n", bcpinfo, index, offset);
++
+ 	_ctclient_msg(blkdesc->con, "blk_rowxfer", 2, 7, 1, 142, "%d, %d",  index + 1, offset + 1);
+ }
+ 
+@@ -620,9 +643,7 @@ static int
+ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset)
+ {
+ 	int result = 0;
+-
+ 	CS_INT null_column = 0;
+-	
+ 	unsigned char *src = NULL;
+ 
+ 	CS_INT      srctype = 0;
+@@ -634,13 +655,13 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset)
+ 	CS_CONTEXT *ctx = blkdesc->con->ctx;
+ 	CS_DATAFMT srcfmt, destfmt;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_blk_get_col_data(%p, %p, %d)\n", bulk, bindcol, offset);
++
+ 	/*
+-	 * retrieve the initial bound column_varaddress
++	 * Retrieve the initial bound column_varaddress
+ 	 * and increment it if offset specified
+ 	 */
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_blk_get_col_data(%p, %p, %d)\n", bulk, bindcol, offset);
+-
+ 	src = (unsigned char *) bindcol->column_varaddr;
+ 	src += offset * bindcol->column_bindlen;
+ 	
+@@ -654,8 +675,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset)
+ 	}
+ 
+ 	if (src) {
+-	
+-		srctype = bindcol->column_bindtype; 		/* used to pass to cs_convert */
++		srctype = bindcol->column_bindtype; 		/* passes to cs_convert */
+ 
+ 		tdsdump_log(TDS_DBG_INFO1, "blk_get_col_data srctype = %d \n", srctype);
+ 		tdsdump_log(TDS_DBG_INFO1, "blk_get_col_data datalen = %d \n", *datalen);
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index fd99aae..3646016 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.69 2008/12/10 14:56:26 freddy77 Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.70 2009/05/03 19:32:57 jklowden Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -63,6 +63,8 @@ cs_prretcode(int retcode)
+ {
+ 	static char unknown[24];
+ 	
++	tdsdump_log(TDS_DBG_FUNC, "cs_prretcode(%d)\n", retcode);
++
+ 	switch(retcode) {
+ 	case CS_SUCCEED:	return "CS_SUCCEED";
+ 	case CS_FAIL:		return "CS_FAIL";
+@@ -98,6 +100,8 @@ cs_prretcode(int retcode)
+ static int 
+ _cs_datatype_length(int dtype)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_datatype_length(%d)\n", dtype);
++
+ 	switch (dtype) {
+ 		case SYBINT1:
+ 			return 1;
+@@ -129,6 +133,8 @@ _cs_datatype_length(int dtype)
+ static const char *
+ _cs_get_layer(int layer)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_get_layer(%d)\n", layer);
++
+ 	switch (layer) {
+ 	case 2:
+ 		return "cslib user api layer";
+@@ -142,6 +148,8 @@ _cs_get_layer(int layer)
+ static const char *
+ _cs_get_origin(int origin)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_get_origin(%d)\n", origin);
++
+ 	switch (origin) {
+ 	case 1:
+ 		return "external error";
+@@ -164,6 +172,8 @@ _cs_get_origin(int origin)
+ static const char *
+ _cs_get_user_api_layer_error(int error)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_get_user_api_layer_error(%d)\n", error);
++
+ 	switch (error) {
+ 	case 3:
+ 		return "Memory allocation failure.";
+@@ -188,6 +198,8 @@ _cs_get_msgstr(const char *funcname, int layer, int origin, int severity, int nu
+ {
+ 	char *m;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_cs_get_msgstr(%s, %d, %d, %d, %d)\n", funcname, layer, origin, severity, number);
++
+ 	if (asprintf(&m, "%s: %s: %s: %s", funcname, _cs_get_layer(layer), _cs_get_origin(origin), (layer == 2)
+ 		     ? _cs_get_user_api_layer_error(number)
+ 		     : "unrecognized error") < 0) {
+@@ -203,6 +215,8 @@ _csclient_msg(CS_CONTEXT * ctx, const char *funcname, int layer, int origin, int
+ 	CS_CLIENTMSG cm;
+ 	char *msgstr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_csclient_msg(%p, %s, %d, %d, %d, %d, %s)\n", ctx, funcname, layer, origin, severity, number, fmt);
++
+ 	va_start(ap, fmt);
+ 
+ 	if (ctx->_cslibmsg_cb) {
+@@ -234,12 +248,16 @@ _csclient_msg(CS_CONTEXT * ctx, const char *funcname, int layer, int origin, int
+ static CS_LOCALE *
+ _cs_locale_alloc(void)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_locale_alloc()\n");
++
+ 	return (CS_LOCALE *) calloc(1, sizeof(CS_LOCALE));
+ }
+ 
+ static void
+ _cs_locale_free_contents(CS_LOCALE *locale)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_locale_free_contents(%p)\n", locale);
++
+ 	/* free strings */
+ 	free(locale->language);
+ 	locale->language = NULL;
+@@ -254,6 +272,8 @@ _cs_locale_free_contents(CS_LOCALE *locale)
+ void 
+ _cs_locale_free(CS_LOCALE *locale)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_locale_free(%p)\n", locale);
++
+ 	/* free contents */
+ 	_cs_locale_free_contents(locale);
+ 
+@@ -265,6 +285,8 @@ _cs_locale_free(CS_LOCALE *locale)
+ int
+ _cs_locale_copy_inplace(CS_LOCALE *new_locale, CS_LOCALE *orig)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_cs_locale_copy_inplace(%p, %p)\n", new_locale, orig);
++
+ 	_cs_locale_free_contents(new_locale);
+ 	if (orig->language) {
+ 		new_locale->language = strdup(orig->language);
+@@ -303,6 +325,8 @@ _cs_locale_copy(CS_LOCALE *orig)
+ {
+ 	CS_LOCALE *new_locale;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_cs_locale_copy(%p)\n", orig);
++
+ 	new_locale = _cs_locale_alloc();
+ 	if (!new_locale)
+ 		return NULL;
+@@ -341,7 +365,9 @@ Cleanup:
+ CS_RETCODE
+ cs_ctx_alloc(CS_INT version, CS_CONTEXT ** ctx)
+ {
+-TDSCONTEXT *tds_ctx;
++	TDSCONTEXT *tds_ctx;
++
++	tdsdump_log(TDS_DBG_FUNC, "cs_ctx_alloc(%d, %p)\n", version, ctx);
+ 
+ 	*ctx = (CS_CONTEXT *) malloc(sizeof(CS_CONTEXT));
+ 	memset(*ctx, '\0', sizeof(CS_CONTEXT));
+@@ -361,7 +387,9 @@ TDSCONTEXT *tds_ctx;
+ CS_RETCODE
+ cs_ctx_global(CS_INT version, CS_CONTEXT ** ctx)
+ {
+-static CS_CONTEXT *global_cs_ctx = NULL;
++	static CS_CONTEXT *global_cs_ctx = NULL;
++
++	tdsdump_log(TDS_DBG_FUNC, "cs_ctx_global(%d, %p)\n", version, ctx);
+ 
+ 	if (global_cs_ctx != NULL) {
+ 		*ctx = global_cs_ctx;
+@@ -377,6 +405,8 @@ static CS_CONTEXT *global_cs_ctx = NULL;
+ CS_RETCODE
+ cs_ctx_drop(CS_CONTEXT * ctx)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "cs_ctx_drop(%p)\n", ctx);
++
+ 	if (ctx) {
+ 		_ct_diag_clearmsg(ctx, CS_ALLMSG_TYPE);
+ 		free(ctx->userdata);
+@@ -390,8 +420,9 @@ cs_ctx_drop(CS_CONTEXT * ctx)
+ CS_RETCODE
+ cs_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen)
+ {
+-/* declared  for - CS_USERDATA changes - swapna*/
+-CS_INT maxcp;
++	CS_INT maxcp;	/* declared  for - CS_USERDATA changes - swapna*/
++
++	tdsdump_log(TDS_DBG_FUNC, "cs_config(%p, %d, %d, %p, %d, %p)\n", ctx, action, property, buffer, buflen, outlen);
+ 
+ 	if (action == CS_GET) {
+ 		if (buffer == NULL) {
+@@ -483,7 +514,6 @@ CS_INT maxcp;
+ CS_RETCODE
+ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT * destfmt, CS_VOID * destdata, CS_INT * resultlen)
+ {
+-
+ 	int src_type, src_len, desttype, destlen, len, i = 0;
+ 	CONV_RESULT cres;
+ 	unsigned char *dest;
+@@ -849,6 +879,8 @@ cs_dt_crack(CS_CONTEXT * ctx, CS_INT datetype, CS_VOID * dateval, CS_DATEREC * d
+ 	TDS_DATETIME4 *dt4;
+ 	TDSDATEREC dr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_dt_crack(%p, %d, %p, %p)\n", ctx, datetype, dateval, daterec);
++
+ 	if (datetype == CS_DATETIME_TYPE) {
+ 		dt = (TDS_DATETIME *) dateval;
+ 		tds_datecrack(SYBDATETIME, dt, &dr);
+@@ -877,6 +909,8 @@ cs_loc_alloc(CS_CONTEXT * ctx, CS_LOCALE ** locptr)
+ {
+ 	CS_LOCALE *tds_csloc;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_loc_alloc(%p, %p)\n", ctx, locptr);
++
+ 	tds_csloc = _cs_locale_alloc();
+ 	if (!tds_csloc)
+ 		return CS_FAIL;
+@@ -888,6 +922,8 @@ cs_loc_alloc(CS_CONTEXT * ctx, CS_LOCALE ** locptr)
+ CS_RETCODE
+ cs_loc_drop(CS_CONTEXT * ctx, CS_LOCALE * locale)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "cs_loc_drop(%p, %p)\n", ctx, locale);
++
+ 	if (!locale)
+ 		return CS_FAIL;
+ 
+@@ -900,6 +936,8 @@ cs_locale(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_V
+ {
+ 	CS_RETCODE code = CS_FAIL;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_locale(%p, %d, %p, %d, %p, %d, %p)\n", ctx, action, locale, type, buffer, buflen, outlen);
++
+ 	if (action == CS_SET) {
+ 		switch (type) {
+ 		case CS_LC_ALL:
+@@ -1082,6 +1120,9 @@ CS_RETCODE
+ cs_dt_info(CS_CONTEXT * ctx, CS_INT action, CS_LOCALE * locale, CS_INT type, CS_INT item, CS_VOID * buffer, CS_INT buflen,
+ 	   CS_INT * outlen)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "cs_dt_info(%p, %d, %p, %d, %d, %p, %d, %p)\n", 
++				ctx, action, locale, type, item, buffer, buflen, outlen);
++
+ 	if (action == CS_SET) {
+ 		switch (type) {
+ 		case CS_DT_CONVFMT:
+@@ -1098,6 +1139,9 @@ cs_strbuild(CS_CONTEXT * ctx, CS_CHAR * buffer, CS_INT buflen, CS_INT * resultle
+ 	va_list ap;
+ 	CS_RETCODE rc;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_strbuild(%p, %p, %d, %p, %p, %d, %p, %d)\n", 
++				ctx, buffer, buflen, resultlen, text, textlen, formats, formatlen);
++
+ 	va_start(ap, formatlen);
+ 	rc = tds_vstrbuild(buffer, buflen, resultlen, text, textlen, formats, formatlen, ap);
+ 	va_end(ap);
+@@ -1108,6 +1152,8 @@ CS_RETCODE
+ cs_calc(CS_CONTEXT * ctx, CS_INT op, CS_INT datatype, CS_VOID * var1, CS_VOID * var2, CS_VOID * dest)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_calc(%p, %d, %d, %p, %p, %p)\n", ctx, op, datatype, var1, var2, dest);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_calc()\n");
+ 	return CS_FAIL;
+ }
+@@ -1116,6 +1162,8 @@ CS_RETCODE
+ cs_cmp(CS_CONTEXT * ctx, CS_INT datatype, CS_VOID * var1, CS_VOID * var2, CS_INT * result)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_cmp(%p, %d, %p, %p, %p)\n", ctx, datatype, var1, var2, result);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_cmp()\n");
+ 	return CS_FAIL;
+ }
+@@ -1124,6 +1172,8 @@ CS_RETCODE
+ cs_conv_mult(CS_CONTEXT * ctx, CS_LOCALE * srcloc, CS_LOCALE * destloc, CS_INT * conv_multiplier)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_conv_mult(%p, %p, %p, %p)\n", ctx, srcloc, destloc, conv_multiplier);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_conv_mult()\n");
+ 	return CS_FAIL;
+ }
+@@ -1131,6 +1181,8 @@ cs_conv_mult(CS_CONTEXT * ctx, CS_LOCALE * srcloc, CS_LOCALE * destloc, CS_INT *
+ CS_RETCODE
+ cs_diag(CS_CONTEXT * ctx, CS_INT operation, CS_INT type, CS_INT idx, CS_VOID * buffer)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "cs_diag(%p, %d, %d, %d, %p)\n", ctx, operation, type, idx, buffer);
++
+ 	switch (operation) {
+ 
+ 		case CS_INIT:
+@@ -1189,6 +1241,9 @@ cs_manage_convert(CS_CONTEXT * ctx, CS_INT action, CS_INT srctype, CS_CHAR * src
+ 		  CS_CHAR * destname, CS_INT destnamelen, CS_INT * conv_multiplier, CS_CONV_FUNC * func)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_manage_convert(%p, %d, %d, %p, %d, %d, %p, %d, %p, %p)\n", 
++				ctx, action, srctype, srcname, srcnamelen, desttype, destname, destnamelen, conv_multiplier, func);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_manage_convert()\n");
+ 	return CS_FAIL;
+ }
+@@ -1197,6 +1252,8 @@ CS_RETCODE
+ cs_objects(CS_CONTEXT * ctx, CS_INT action, CS_OBJNAME * objname, CS_OBJDATA * objdata)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_objects(%p, %d, %p, %p)\n", ctx, action, objname, objdata);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_objects()\n");
+ 	return CS_FAIL;
+ }
+@@ -1205,6 +1262,8 @@ CS_RETCODE
+ cs_set_convert(CS_CONTEXT * ctx, CS_INT action, CS_INT srctype, CS_INT desttype, CS_CONV_FUNC * func)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_set_convert(%p, %d, %d, %d, %p)\n", ctx, action, srctype, desttype, func);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_set_convert()\n");
+ 	return CS_FAIL;
+ }
+@@ -1213,6 +1272,8 @@ CS_RETCODE
+ cs_setnull(CS_CONTEXT * ctx, CS_DATAFMT * datafmt, CS_VOID * buffer, CS_INT buflen)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_setnull(%p, %p, %p, %d)\n", ctx, datafmt, buffer, buflen);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_setnull()\n");
+ 	return CS_FAIL;
+ }
+@@ -1222,6 +1283,9 @@ cs_strcmp(CS_CONTEXT * ctx, CS_LOCALE * locale, CS_INT type, CS_CHAR * str1, CS_
+ 	  CS_INT * result)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_strcmp(%p, %p, %d, %p, %d, %p, %d, %p)\n", 
++					ctx, locale, type, str1, len1, str2, len2, result);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_strcmp()\n");
+ 	return CS_FAIL;
+ }
+@@ -1230,6 +1294,8 @@ CS_RETCODE
+ cs_time(CS_CONTEXT * ctx, CS_LOCALE * locale, CS_VOID * buffer, CS_INT buflen, CS_INT * outlen, CS_DATEREC * daterec)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_time(%p, %p, %p, %d, %p, %p)\n", ctx, locale, buffer, buflen, outlen, daterec);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED cs_time()\n");
+ 	return CS_FAIL;
+ }
+@@ -1238,6 +1304,8 @@ CS_RETCODE
+ cs_will_convert(CS_CONTEXT * ctx, CS_INT srctype, CS_INT desttype, CS_BOOL * result)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "cs_will_convert(%p, %d, %d, %p)\n", ctx, srctype, desttype, result);
++
+ 	*result = (tds_willconvert(srctype, desttype) ? CS_TRUE : CS_FALSE);
+ 	return CS_SUCCEED;
+ }
+@@ -1245,9 +1313,10 @@ cs_will_convert(CS_CONTEXT * ctx, CS_INT srctype, CS_INT desttype, CS_BOOL * res
+ static CS_INT 
+ cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message)
+ {
++	struct cs_diag_msg **curptr;
++	CS_INT msg_count = 0;
+ 
+-struct cs_diag_msg **curptr;
+-CS_INT msg_count = 0;
++	tdsdump_log(TDS_DBG_FUNC, "cs_diag_storemsg(%p, %p)\n", context, message);
+ 
+ 	curptr = &(context->msgstore);
+ 
+@@ -1286,9 +1355,10 @@ CS_INT msg_count = 0;
+ static CS_INT 
+ cs_diag_getmsg(CS_CONTEXT *context, CS_INT idx, CS_CLIENTMSG *message)
+ {
++	struct cs_diag_msg *curptr;
++	CS_INT msg_count = 0, msg_found = 0;
+ 
+-struct cs_diag_msg *curptr;
+-CS_INT msg_count = 0, msg_found = 0;
++	tdsdump_log(TDS_DBG_FUNC, "cs_diag_getmsg(%p, %d, %p)\n", context, idx, message);
+ 
+ 	curptr = context->msgstore;
+ 
+@@ -1314,8 +1384,9 @@ CS_INT msg_count = 0, msg_found = 0;
+ static CS_INT 
+ cs_diag_clearmsg(CS_CONTEXT *context, CS_INT type)
+ {
++	struct cs_diag_msg *curptr, *freeptr;
+ 
+-struct cs_diag_msg *curptr, *freeptr;
++	tdsdump_log(TDS_DBG_FUNC, "cs_diag_clearmsg(%p, %d)\n", context, type);
+ 
+ 	curptr = context->msgstore;
+ 	context->msgstore = NULL;
+@@ -1332,8 +1403,10 @@ struct cs_diag_msg *curptr, *freeptr;
+ static CS_INT 
+ cs_diag_countmsg(CS_CONTEXT *context, CS_INT *count)
+ {
+-struct cs_diag_msg *curptr;
+-CS_INT msg_count = 0;
++	struct cs_diag_msg *curptr;
++	CS_INT msg_count = 0;
++
++	tdsdump_log(TDS_DBG_FUNC, "cs_diag_countmsg(%p, %p)\n", context, count);
+ 
+ 	curptr = context->msgstore;
+ 
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index bc7d306..b1f5438 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.186 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.187 2009/05/03 19:32:57 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -89,6 +89,8 @@ static CS_DYNAMIC * _ct_locate_dynamic(CS_CONNECTION * con, char *id, int idlen)
+ static const char *
+ _ct_get_layer(int layer)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_ct_get_layer(%d)\n", layer);
++
+ 	switch (layer) {
+ 	case 1:
+ 		return "user api layer";
+@@ -105,6 +107,8 @@ _ct_get_layer(int layer)
+ static const char *
+ _ct_get_origin(int origin)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_ct_get_origin(%d)\n", origin);
++
+ 	switch (origin) {
+ 	case 1:
+ 		return "external error";
+@@ -133,6 +137,8 @@ _ct_get_origin(int origin)
+ static const char *
+ _ct_get_user_api_layer_error(int error)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_ct_get_user_api_layer_error(%d)\n", error);
++
+ 	switch (error) {
+ 	case 137:
+ 		return  "A bind count of %1! is not consistent with the count supplied for existing binds. "
+@@ -170,6 +176,8 @@ _ct_get_msgstr(const char *funcname, int layer, int origin, int severity, int nu
+ {
+ 	char *m;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_get_msgstr(%s, %d, %d, %d, %d)\n", funcname, layer, origin, severity, number);
++
+ 	if (asprintf(&m,
+ 		     "%s: %s: %s: %s", funcname, _ct_get_layer(layer), _ct_get_origin(origin), _ct_get_user_api_layer_error(number)
+ 	    ) < 0) {
+@@ -186,6 +194,8 @@ _ctclient_msg(CS_CONNECTION * con, const char *funcname, int layer, int origin,
+ 	CS_CLIENTMSG cm;
+ 	char *msgstr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ctclient_msg(%p, %s, %d, %d, %d, %d, %s)\n", con, funcname, layer, origin, severity, number, fmt);
++
+ 	va_start(ap, fmt);
+ 
+ 	if (ctx->_clientmsg_cb) {
+@@ -211,11 +221,11 @@ _ctclient_msg(CS_CONNECTION * con, const char *funcname, int layer, int origin,
+ }
+ 
+ static CS_RETCODE
+-ct_set_command_state(CS_COMMAND *cmd, CS_INT state) {
+-
+-	tdsdump_log(TDS_DBG_FUNC, "setting command state from %s to %s\n",
+-		    ct_describe_cmd_state(cmd->command_state),
+-		    ct_describe_cmd_state(state));
++ct_set_command_state(CS_COMMAND *cmd, CS_INT state) 
++{
++	tdsdump_log(TDS_DBG_FUNC, "setting command state to %s (from %s)\n",
++		    ct_describe_cmd_state(state),
++		    ct_describe_cmd_state(cmd->command_state));
+ 
+ 	cmd->command_state = state;
+ 
+@@ -223,7 +233,10 @@ ct_set_command_state(CS_COMMAND *cmd, CS_INT state) {
+ }
+ 
+ static char *
+-ct_describe_cmd_state(CS_INT state) {
++ct_describe_cmd_state(CS_INT state) 
++{
++	tdsdump_log(TDS_DBG_FUNC, "ct_describe_cmd_state(%d)\n", state);
++
+ 	switch (state) {
+ 	case _CS_COMMAND_IDLE:
+ 		return "IDLE";
+@@ -240,7 +253,8 @@ ct_describe_cmd_state(CS_INT state) {
+ CS_RETCODE
+ ct_exit(CS_CONTEXT * ctx, CS_INT unused)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "ct_exit()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_exit(%p, %d)\n", ctx, unused);
++
+ 	return CS_SUCCEED;
+ }
+ 
+@@ -249,9 +263,11 @@ ct_init(CS_CONTEXT * ctx, CS_INT version)
+ {
+ 	/* uncomment the next line to get pre-login trace */
+ 	/* tdsdump_open("/tmp/tds2.log"); */
+-	tdsdump_log(TDS_DBG_FUNC, "ct_init()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_init(%p, %d)\n", ctx, version);
++	
+ 	ctx->tds_ctx->msg_handler = _ct_handle_server_message;
+ 	ctx->tds_ctx->err_handler = _ct_handle_client_message;
++
+ 	return CS_SUCCEED;
+ }
+ 
+@@ -260,7 +276,8 @@ ct_con_alloc(CS_CONTEXT * ctx, CS_CONNECTION ** con)
+ {
+ 	TDSLOGIN *login;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_con_alloc()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_con_alloc(%p, %p)\n", ctx, con);
++
+ 	login = tds_alloc_login();
+ 	if (!login)
+ 		return CS_FAIL;
+@@ -286,6 +303,8 @@ ct_callback(CS_CONTEXT * ctx, CS_CONNECTION * con, CS_INT action, CS_INT type, C
+ {
+ 	int (*funcptr) (void *, void *, void *) = (int (*)(void *, void *, void *)) func;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_callback(%p, %p, %d, %d, %p)\n", ctx, con, action, type, func);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_callback() action = %s\n", CS_GET ? "CS_GET" : "CS_SET");
+ 	/* one of these has to be defined */
+ 	if (!ctx && !con)
+@@ -331,6 +350,8 @@ ct_con_props(CS_CONNECTION * con, CS_INT action, CS_INT property, CS_VOID * buff
+ 	TDSLOGIN *tds_login;
+ 	char *set_buffer = NULL;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_con_props(%p, %d, %d, %p, %d, %p)\n", con, action, property, buffer, buflen, out_len);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_con_props() action = %s property = %d\n", CS_GET ? "CS_GET" : "CS_SET", property);
+ 
+ 	tds = con->tds_socket;
+@@ -565,7 +586,7 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 	CS_CONTEXT *ctx;
+ 	TDSCONNECTION *connection;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_connect() servername = %s\n", servername ? servername : "NULL");
++	tdsdump_log(TDS_DBG_FUNC, "ct_connect(%p, %s, %d)\n", con, servername ? servername : "NULL", snamelen);
+ 
+ 	if (!tds_dstr_isempty(&con->tds_login->server_addr)) {
+ 		server = tds_dstr_buf(&con->tds_login->server_addr);
+@@ -635,6 +656,8 @@ CS_RETCODE
+ ct_cmd_alloc(CS_CONNECTION * con, CS_COMMAND ** cmd)
+ {
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_alloc(%p, %p)\n", con, cmd);
++
+ 	CS_COMMAND_LIST *command_list;
+ 	CS_COMMAND_LIST *pcommand;
+ 
+@@ -676,10 +699,9 @@ ct_cmd_alloc(CS_CONNECTION * con, CS_COMMAND ** cmd)
+ CS_RETCODE
+ ct_command(CS_COMMAND * cmd, CS_INT type, const CS_VOID * buffer, CS_INT buflen, CS_INT option)
+ {
+-	int query_len;
+-	int current_query_len;
++	int query_len, current_query_len;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_command()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_command(%p, %d, %p, %d, %d)\n", cmd, type, buffer, buflen, option);
+ 
+ 	/* Unless we are in the process of building a CS_LANG_CMD   */
+ 	/* type command, then clear everything, ready to start anew */
+@@ -821,6 +843,8 @@ _ct_initialise_cmd(CS_COMMAND *cmd)
+ 	free(cmd->query);
+ 	cmd->query = NULL;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_initialise_cmd(%p)\n", cmd);
++
+ 	if (cmd->input_params) {
+ 		param_clear(cmd->input_params);
+ 		cmd->input_params = NULL;
+@@ -841,6 +865,8 @@ ct_send(CS_COMMAND * cmd)
+ 	TDSCURSOR *cursor;
+ 	TDSDYNAMIC *tdsdyn;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_send(%p)\n", cmd);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_send() command_type = %d\n", cmd->command_type);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+@@ -1091,12 +1117,11 @@ ct_results(CS_COMMAND * cmd, CS_INT * result_type)
+ {
+ 	TDSSOCKET *tds;
+ 	CS_CONTEXT *context;
+-
+ 	int tdsret;
+ 	CS_INT res_type;
+ 	CS_INT done_flags;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_results()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_results(%p, %p)\n", cmd, result_type);
+ 
+ 	if (cmd->cancel_state == _CS_CANCEL_PENDING) {
+ 		_ct_cancel_cleanup(cmd);
+@@ -1431,6 +1456,8 @@ ct_bind(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt, CS_VOID * buffer, C
+ 	CS_CONNECTION *con = cmd->con;
+ 	CS_INT bind_count;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_bind(%p, %d, %p, %p, %p, %p)\n", cmd, item, datafmt, buffer, copied, indicator);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_bind() datafmt count = %d column_number = %d\n", datafmt->count, item);
+ 
+ 	if (!con || !con->tds_socket)
+@@ -1606,7 +1633,7 @@ _ct_fetch_cursor(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS
+ 	TDS_INT done_flags;
+ 	TDS_INT rows_this_fetch = 0;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_ct_fetch_cursor()\n");
++	tdsdump_log(TDS_DBG_FUNC, "_ct_fetch_cursor(%p, %d, %d, %d, %p)\n", cmd, type, offset, option, rows_read);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+@@ -1694,18 +1721,15 @@ _ct_fetch_cursor(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS
+ int
+ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo, CS_INT offset)
+ {
+-	int i;
+-	TDSCOLUMN *curcol;
+-	TDSCOLUMN *bindcol;
+-	unsigned char *src;
+-	unsigned char *dest, *temp_add;
+-	int result = 0;
++	TDSCOLUMN *curcol, *bindcol;
++	unsigned char *src, *dest, *temp_add;
++	int i, result = 0;
+ 	TDS_INT srctype, srclen, desttype;
+ 	CS_DATAFMT srcfmt, destfmt;
+ 	TDS_INT datalen_dummy, *pdatalen = &datalen_dummy;
+ 	TDS_SMALLINT nullind_dummy, *nullind = &nullind_dummy;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_ct_bind_data()\n");
++	tdsdump_log(TDS_DBG_FUNC, "_ct_bind_data(%p, %p, %p, %d)\n", ctx, resinfo, bindinfo, offset);
+ 
+ 	for (i = 0; i < resinfo->num_cols; i++) {
+ 
+@@ -1781,6 +1805,9 @@ CS_RETCODE
+ ct_cmd_drop(CS_COMMAND * cmd)
+ {
+ 	CS_RETCODE ret;
++
++	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_drop(%p)\n", cmd);
++
+ 	ret = _ct_cmd_drop(cmd, 1);
+ 	return ret;
+ }
+@@ -1793,7 +1820,8 @@ _ct_cmd_drop(CS_COMMAND * cmd, CS_INT free_conn_ref)
+ 	CS_COMMAND_LIST *next = NULL;
+ 	CS_CONNECTION *con;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_drop()\n");
++	tdsdump_log(TDS_DBG_FUNC, "_ct_cmd_drop(%p, %d)\n", cmd, free_conn_ref);
++
+ 	if (cmd) {
+ 		free(cmd->query);
+ 		if (cmd->input_params)
+@@ -1847,7 +1875,8 @@ _ct_cmd_drop(CS_COMMAND * cmd, CS_INT free_conn_ref)
+ CS_RETCODE
+ ct_close(CS_CONNECTION * con, CS_INT option)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "ct_close()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_close(%p, %d)\n", con, option);
++
+ 	tds_free_socket(con->tds_socket);
+ 	con->tds_socket = NULL;
+ 	return CS_SUCCEED;
+@@ -1856,10 +1885,10 @@ ct_close(CS_CONNECTION * con, CS_INT option)
+ CS_RETCODE
+ ct_con_drop(CS_CONNECTION * con)
+ {
+-	CS_COMMAND_LIST *currptr;
+-	CS_COMMAND_LIST *freeptr;
++	CS_COMMAND_LIST *currptr, *freeptr;
++
++	tdsdump_log(TDS_DBG_FUNC, "ct_con_drop(%p)\n", con);
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_con_drop()\n");
+ 	if (con) {
+ 		free(con->userdata);
+ 		if (con->tds_login)
+@@ -1885,6 +1914,7 @@ int
+ _ct_get_client_type(int datatype, int usertype, int size)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "_ct_get_client_type(type %d, user %d, size %d)\n", datatype, usertype, size);
++
+ 	switch (datatype) {
+ 	case SYBBIT:
+ 	case SYBBITN:
+@@ -2037,7 +2067,7 @@ ct_cancel(CS_CONNECTION * conn, CS_COMMAND * cmd, CS_INT type)
+ 	CS_COMMAND *conn_cmd;
+ 	CS_CONNECTION *cmd_conn;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_cancel()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_cancel(%p, %p, %d)\n", conn, cmd, type);
+ 
+ 	/*
+ 	 * Comments taken from Sybase ct-library reference manual
+@@ -2239,6 +2269,8 @@ _ct_cancel_cleanup(CS_COMMAND * cmd)
+ {
+ 	CS_CONNECTION * con;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_cancel_cleanup(%p)\n", cmd);
++
+ 	con = cmd->con;
+ 
+ 	if (con && !IS_TDSDEAD(con->tds_socket))
+@@ -2258,7 +2290,7 @@ ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt)
+ 	TDSCOLUMN *curcol;
+ 	int len;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_describe()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_describe(%p, %d, %p)\n", cmd, item, datafmt);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+@@ -2314,7 +2346,7 @@ ct_res_info(CS_COMMAND * cmd, CS_INT type, CS_VOID * buffer, CS_INT buflen, CS_I
+ 	CS_INT int_val;
+ 	int i;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_res_info()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_res_info(%p, %d, %p, %d, %p)\n", cmd, type, buffer, buflen, out_len);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+@@ -2357,6 +2389,8 @@ ct_config(CS_CONTEXT * ctx, CS_INT action, CS_INT property, CS_VOID * buffer, CS
+ 	CS_RETCODE ret = CS_SUCCEED;
+ 	CS_INT *buf = (CS_INT *) buffer;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_config(%p, %d, %d, %p, %d, %p)\n", ctx, action, property, buffer, buflen, outlen);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_config() action = %s property = %d\n",
+ 		    CS_GET ? "CS_GET" : CS_SET ? "CS_SET" : CS_SUPPORTED ? "CS_SUPPORTED" : "CS_CLEAR", property);
+ 
+@@ -2443,6 +2477,8 @@ ct_cmd_props(CS_COMMAND * cmd, CS_INT action, CS_INT property, CS_VOID * buffer,
+ 	TDSCURSOR *cursor;
+ 	int maxcp;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_props(%p, %d, %d, %p, %d, %p)\n", cmd, action, property, buffer, buflen, outlen);
++
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+ 
+@@ -2534,6 +2570,8 @@ ct_compute_info(CS_COMMAND * cmd, CS_INT type, CS_INT colnum, CS_VOID * buffer,
+ 	TDS_SMALLINT *src_by_col_ptr;
+ 	int i;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_compute_info(%p, %d, %d, %p, %d, %p)\n", cmd, type, colnum, buffer, buflen, outlen);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_compute_info() type = %d, colnum = %d\n", type, colnum);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+@@ -2616,6 +2654,8 @@ ct_get_data(CS_COMMAND * cmd, CS_INT item, CS_VOID * buffer, CS_INT buflen, CS_I
+ 	unsigned char *src;
+ 	TDS_INT srclen;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_get_data(%p, %d, %p, %d, %p)\n", cmd, item, buffer, buflen, outlen);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_get_data() item = %d buflen = %d\n", item, buflen);
+ 
+ 	if (cmd->cancel_state == _CS_CANCEL_PENDING) {
+@@ -2734,6 +2774,8 @@ ct_send_data(CS_COMMAND * cmd, CS_VOID * buffer, CS_INT buflen)
+ {
+ 	TDSSOCKET *tds;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_send_data(%p, %p, %d)\n", cmd, buffer, buflen);
++
+ 	char textptr_string[35];	/* 16 * 2 + 2 (0x) + 1 */
+ 	char timestamp_string[19];	/* 8 * 2 + 2 (0x) + 1 */
+ 	char *c;
+@@ -2799,14 +2841,14 @@ ct_data_info(CS_COMMAND * cmd, CS_INT action, CS_INT colnum, CS_IODESC * iodesc)
+ 	TDSSOCKET *tds;
+ 	TDSRESULTINFO *resinfo;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_data_info(%p, %d, %d, %p)\n", cmd, action, colnum, iodesc);
++
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+ 
+ 	tds = cmd->con->tds_socket;
+ 	resinfo = tds->current_results;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_data_info() colnum %d\n", colnum);
+-
+ 	switch (action) {
+ 	case CS_SET:
+ 
+@@ -2865,7 +2907,8 @@ ct_capability(CS_CONNECTION * con, CS_INT action, CS_INT type, CS_INT capability
+ 	unsigned char bitmask = 0;
+ 	unsigned char *mask;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_capability()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_capability(%p, %d, %d, %d, %p)\n", con, action, type, capability, value);
++
+ 	login = (TDSLOGIN *) con->tds_login;
+ 	mask = login->capabilities;
+ 
+@@ -3036,13 +3079,14 @@ ct_dynamic(CS_COMMAND * cmd, CS_INT type, CS_CHAR * id, CS_INT idlen, CS_CHAR *
+ 	CS_CONNECTION *con;
+ 	CS_DYNAMIC *dyn;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_dynamic(%p, %d, %p, %d, %p, %d)\n", cmd, type, id, idlen, buffer, buflen);
++
+ 	if (!cmd->con)
+ 		return CS_FAIL;
+ 
+ 	cmd->command_type = CS_DYNAMIC_CMD;
+ 	cmd->dynamic_cmd = type;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_dynamic(%d)\n", type);
+ 	con = cmd->con;
+ 
+ 	switch (type) {
+@@ -3101,8 +3145,8 @@ ct_param(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT datalen,
+ 	CS_PARAM **pparam;
+ 	CS_PARAM *param;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_param(%p, %p, %p, %d, %hd)\n", cmd, datafmt, data, datalen, indicator);
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_param()\n");
+ 	tdsdump_log(TDS_DBG_INFO1, "ct_param() data addr = %p data length = %d\n", data, datalen);
+ 
+ 	if (cmd == NULL)
+@@ -3203,6 +3247,8 @@ ct_setparam(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT * dat
+ 	CS_PARAM *param;
+ 	CS_DYNAMIC *dyn;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_setparam(%p, %p, %p, %p, %p)\n", cmd, datafmt, data, datalen, indicator);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_setparam() command type = %d, data type = %d\n", cmd->command_type, datafmt->datatype);
+ 
+ 	/* Code changed for RPC functionality - SUHA */
+@@ -3318,6 +3364,8 @@ ct_options(CS_CONNECTION * con, CS_INT action, CS_INT option, CS_VOID * param, C
+ 	TDS_INT tds_argsize = 0;
+ 	TDSSOCKET *tds;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_options(%p, %d, %d, %p, %d, %p)\n", con, action, option, param, paramlen, outlen);
++
+ 	const char *action_string = NULL;
+ 	int i;
+ 
+@@ -3629,6 +3677,9 @@ ct_poll(CS_CONTEXT * ctx, CS_CONNECTION * connection, CS_INT milliseconds, CS_CO
+ 	CS_INT * compid, CS_INT * compstatus)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "UNIMPLEMENTED ct_poll()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_poll(%p, %p, %d, %p, %p, %p, %p)\n", 
++				ctx, connection, milliseconds, compconn, compcmd, compid, compstatus);
++
+ 	return CS_FAIL;
+ }
+ 
+@@ -3638,6 +3689,8 @@ ct_cursor(CS_COMMAND * cmd, CS_INT type, CS_CHAR * name, CS_INT namelen, CS_CHAR
+ 	TDSSOCKET *tds;
+ 	TDSCURSOR *cursor;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_cursor(%p, %d, %p, %d, %p, %d, %d)\n", cmd, type, name, namelen, text, tlen, option);
++
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+ 
+@@ -3766,6 +3819,8 @@ ct_cursor(CS_COMMAND * cmd, CS_INT type, CS_CHAR * name, CS_INT namelen, CS_CHAR
+ static int
+ _ct_fetchable_results(CS_COMMAND * cmd)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "_ct_fetchable_results(%p)\n", cmd);
++
+ 	switch (cmd->curr_result_type) {
+ 	case CS_COMPUTE_RESULT:
+ 	case CS_CURSOR_RESULT:
+@@ -3784,8 +3839,9 @@ _ct_process_return_status(TDSSOCKET * tds)
+ 	TDSCOLUMN *curcol;
+ 	TDS_INT saved_status;
+ 
+-	enum
+-	{ num_cols = 1 };
++	tdsdump_log(TDS_DBG_FUNC, "_ct_process_return_status(%p)\n", tds);
++
++	enum { num_cols = 1 };
+ 
+ 	assert(tds);
+ 	saved_status = tds->ret_status;
+@@ -3825,8 +3881,7 @@ paramrowalloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *va
+ 	const void *row = tds_alloc_param_data(curcol);
+ 
+ 	tdsdump_log(TDS_DBG_INFO1, "paramrowalloc, size = %d, data = %p, row_size = %d\n",
+-				size, curcol->column_data,
+-				params->row_size);
++				size, curcol->column_data, params->row_size);
+ 	if (!row)
+ 		return NULL;
+ 
+@@ -3873,6 +3928,7 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ 	CS_INT temp_datalen;
+ 	int param_is_null;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "paraminfoalloc(%p, %p)\n", tds, first_param);
+ 
+ 	/* sanity */
+ 	if (first_param == NULL)
+@@ -4017,6 +4073,8 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ static void
+ rpc_clear(CSREMOTE_PROC * rpc)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "rpc_clear(%p)\n", rpc);
++
+ 	if (rpc == NULL)
+ 		return;
+ 
+@@ -4032,6 +4090,8 @@ rpc_clear(CSREMOTE_PROC * rpc)
+ static void
+ param_clear(CS_PARAM * pparam)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "param_clear(%p)\n", pparam);
++
+ 	if (pparam == NULL)
+ 		return;
+ 
+@@ -4063,6 +4123,9 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *d
+ {
+ 	int param_is_null = 0;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_fill_param(%d, %p, %p, %p, %p, %p, %x)\n", 
++				cmd_type, param, datafmt, data, datalen, indicator, byvalue);
++
+ 	if (cmd_type == CS_DYNAMIC_CMD) {
+ 		param->name = NULL;
+ 	} else {
+@@ -4199,6 +4262,8 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *d
+ CS_RETCODE
+ ct_diag(CS_CONNECTION * conn, CS_INT operation, CS_INT type, CS_INT idx, CS_VOID * buffer)
+ {
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag(%p, %d, %d, %d, %p)\n", conn, operation, type, idx, buffer);
++
+ 	switch (operation) {
+ 	case CS_INIT:
+ 		if (conn->ctx->cs_errhandletype == _CS_ERRHAND_CB) {
+@@ -4287,14 +4352,15 @@ ct_diag_storeclientmsg(CS_CONTEXT * context, CS_CONNECTION * conn, CS_CLIENTMSG
+ 	struct cs_diag_msg_client **curptr;
+ 	struct cs_diag_msg_svr **scurptr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_storeclientmsg(%p, %p, %p)\n", context, conn, message);
++
+ 	CS_INT msg_count = 0;
+ 
+ 	curptr = &(conn->ctx->clientstore);
+ 
+ 	scurptr = &(conn->ctx->svrstore);
+ 
+-	/* if we already have a list of messages, */
+-	/* go to the end of the list...           */
++	/* if we already have a list of messages, go to the end of the list... */
+ 
+ 	while (*curptr != NULL) {
+ 		msg_count++;
+@@ -4343,13 +4409,14 @@ ct_diag_storeservermsg(CS_CONTEXT * context, CS_CONNECTION * conn, CS_SERVERMSG
+ 	struct cs_diag_msg_svr **curptr;
+ 	struct cs_diag_msg_client **ccurptr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_storeservermsg(%p, %p, %p)\n", context, conn, message);
++
+ 	CS_INT msg_count = 0;
+ 
+ 	curptr = &(conn->ctx->svrstore);
+ 	ccurptr = &(conn->ctx->clientstore);
+ 
+-	/* if we already have a list of messages, */
+-	/* go to the end of the list...           */
++	/* if we already have a list of messages, go to the end of the list...  */
+ 
+ 	while (*curptr != NULL) {
+ 		msg_count++;
+@@ -4398,10 +4465,11 @@ ct_diag_getclientmsg(CS_CONTEXT * context, CS_INT idx, CS_CLIENTMSG * message)
+ 	struct cs_diag_msg_client *curptr;
+ 	CS_INT msg_count = 0, msg_found = 0;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_getclientmsg(%p, %d, %p)\n", context, idx, message);
++
+ 	curptr = context->clientstore;
+ 
+-	/* if we already have a list of messages, */
+-	/* go to the end of the list...           */
++	/* if we already have a list of messages, go to the end of the list...  */
+ 
+ 	while (curptr != NULL) {
+ 		msg_count++;
+@@ -4425,10 +4493,11 @@ ct_diag_getservermsg(CS_CONTEXT * context, CS_INT idx, CS_SERVERMSG * message)
+ 	struct cs_diag_msg_svr *curptr;
+ 	CS_INT msg_count = 0, msg_found = 0;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_getservermsg(%p, %d, %p)\n", context, idx, message);
++
+ 	curptr = context->svrstore;
+ 
+-	/* if we already have a list of messages, */
+-	/* go to the end of the list...           */
++	/* if we already have a list of messages, go to the end of the list...  */
+ 
+ 	while (curptr != NULL) {
+ 		msg_count++;
+@@ -4453,6 +4522,8 @@ _ct_diag_clearmsg(CS_CONTEXT * context, CS_INT type)
+ 	struct cs_diag_msg_client *curptr, *freeptr;
+ 	struct cs_diag_msg_svr *scurptr, *sfreeptr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_diag_clearmsg(%p, %d)\n", context, type);
++
+ 	if (type == CS_CLIENTMSG_TYPE || type == CS_ALLMSG_TYPE) {
+ 		curptr = context->clientstore;
+ 		context->clientstore = NULL;
+@@ -4485,6 +4556,8 @@ ct_diag_countmsg(CS_CONTEXT * context, CS_INT type, CS_INT * count)
+ 	struct cs_diag_msg_client *curptr;
+ 	struct cs_diag_msg_svr *scurptr;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_countmsg(%p, %d, %p)\n", context, type, count);
++
+ 	CS_INT msg_count = 0;
+ 
+ 	if (type == CS_CLIENTMSG_TYPE || type == CS_ALLMSG_TYPE) {
+@@ -4518,6 +4591,8 @@ _ct_allocate_dynamic(CS_CONNECTION * con, char *id, int idlen)
+ 	CS_DYNAMIC **pdyn;
+ 	int id_len;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_allocate_dynamic(%p, %p, %d)\n", con, id, idlen);
++
+ 	dyn = (CS_DYNAMIC *) malloc(sizeof(CS_DYNAMIC));
+ 
+ 	if (idlen == CS_NULLTERM)
+@@ -4552,6 +4627,8 @@ _ct_locate_dynamic(CS_CONNECTION * con, char *id, int idlen)
+ 	CS_DYNAMIC *dyn;
+ 	int id_len;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_locate_dynamic(%p, %p, %d)\n", con, id, idlen);
++
+ 	if (idlen == CS_NULLTERM)
+ 		id_len = strlen(id);
+ 	else
+@@ -4577,6 +4654,8 @@ _ct_deallocate_dynamic(CS_CONNECTION * con, CS_DYNAMIC *dyn)
+ 	TDSDYNAMIC *tdsdyn;
+ 	char myid[256];
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_deallocate_dynamic(%p, %p)\n", con, dyn);
++
+ 	strcpy(myid,"");
+ 
+ 	victim = con->dynlist;
+diff --git a/src/ctlib/ctutil.c b/src/ctlib/ctutil.c
+index c2bf5f5..900d55e 100644
+--- a/src/ctlib/ctutil.c
++++ b/src/ctlib/ctutil.c
+@@ -32,7 +32,7 @@
+ /* #include "fortify.h" */
+ 
+ 
+-TDS_RCSID(var, "$Id: ctutil.c,v 1.29 2008/08/17 07:44:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ctutil.c,v 1.30 2009/05/03 19:32:57 jklowden Exp $");
+ 
+ /*
+  * test include consistency 
+@@ -98,6 +98,8 @@ _ct_handle_client_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG
+ 	CS_CONTEXT *ctx = NULL;
+ 	int ret = (int) CS_SUCCEED;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_handle_client_message(%p, %p, %p)\n", ctx_tds, tds, msg);
++
+ 	if (tds && tds->parent) {
+ 		con = (CS_CONNECTION *) tds->parent;
+ 	}
+@@ -150,6 +152,8 @@ _ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG
+ 	CS_CONTEXT *ctx = NULL;
+ 	int ret = (int) CS_SUCCEED;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_handle_server_message(%p, %p, %p)\n", ctx_tds, tds, msg);
++
+ 	if (tds && tds->parent) {
+ 		con = (CS_CONNECTION *) tds->parent;
+ 	}
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index 8139c04..b563131 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -24,7 +24,7 @@
+ #include "common.h"
+ #include "ctlib.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.21 2008/12/10 14:56:26 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.22 2009/05/03 19:32:57 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -264,6 +264,9 @@ continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd,
+ 		}
+ 		return ret;
+ 	}
++	
++	printf("connecting as %s to %s.%s\n", USER, SERVER, DATABASE);
++	
+ 	ret = ct_connect(*conn, SERVER, CS_NULLTERM);
+ 	if (ret != CS_SUCCEED) {
+ 		if (verbose) {
+diff --git a/src/dblib/dbutil.c b/src/dblib/dbutil.c
+index 098568e..c3f879b 100644
+--- a/src/dblib/dbutil.c
++++ b/src/dblib/dbutil.c
+@@ -38,7 +38,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbutil.c,v 1.46 2009/03/24 01:22:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: dbutil.c,v 1.47 2009/05/03 19:32:57 jklowden Exp $");
+ 
+ /*
+  * test include consistency 
+@@ -209,7 +209,7 @@ _dblib_check_and_handle_interrupt(void * vdbproc)
+ 	if (dbproc->chkintr == NULL || dbproc->hndlintr == NULL)
+ 		return INT_CONTINUE;
+ 		
+-	tdsdump_log(TDS_DBG_FUNC, "tds_int_handler %p [%p, %p]", dbproc, dbproc->chkintr, dbproc->hndlintr);
++	tdsdump_log(TDS_DBG_FUNC, "_dblib_check_and_handle_interrupt %p [%p, %p]\n", dbproc, dbproc->chkintr, dbproc->hndlintr);
+ 
+ 	if (dbproc->chkintr(dbproc)){
+ 		switch (ret = dbproc->hndlintr(dbproc)) {
+
+commit bb3b8fd5bd8e5c034526c04976e8e1c314a1f888
+Author: freddy77 <freddy77>
+Date:   Mon May 11 07:25:24 2009 +0000
+
+    remove warnings and duplicate logs
+
+diff --git a/ChangeLog b/ChangeLog
+index ef05c21..eeda3fe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon May 11 09:24:40 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: remove warnings and duplicate logs
++
+ Sun May  3 15:26:26 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/ctlib/blk.c src/ctlib/cs.c src/ctlib/ct.c
+ 	* src/ctlib/ctutil.c src/ctlib/unittests/common.c
+@@ -1528,4 +1531,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2782 2009/05/03 19:32:56 jklowden Exp $
++$Id: ChangeLog,v 1.2783 2009/05/11 07:25:24 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index b1f5438..86629cd 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.187 2009/05/03 19:32:57 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.188 2009/05/11 07:25:25 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -655,13 +655,10 @@ Cleanup:
+ CS_RETCODE
+ ct_cmd_alloc(CS_CONNECTION * con, CS_COMMAND ** cmd)
+ {
+-
+-	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_alloc(%p, %p)\n", con, cmd);
+-
+ 	CS_COMMAND_LIST *command_list;
+ 	CS_COMMAND_LIST *pcommand;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_alloc()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_alloc(%p, %p)\n", con, cmd);
+ 
+ 	*cmd = (CS_COMMAND *) malloc(sizeof(CS_COMMAND));
+ 	if (!*cmd)
+@@ -2774,15 +2771,13 @@ ct_send_data(CS_COMMAND * cmd, CS_VOID * buffer, CS_INT buflen)
+ {
+ 	TDSSOCKET *tds;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_send_data(%p, %p, %d)\n", cmd, buffer, buflen);
+-
+ 	char textptr_string[35];	/* 16 * 2 + 2 (0x) + 1 */
+ 	char timestamp_string[19];	/* 8 * 2 + 2 (0x) + 1 */
+ 	char *c;
+ 	int s;
+ 	char hex2[3];
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_send_data()\n");
++	tdsdump_log(TDS_DBG_FUNC, "ct_send_data(%p, %p, %d)\n", cmd, buffer, buflen);
+ 
+ 	if (!cmd->con || !cmd->con->tds_socket)
+ 		return CS_FAIL;
+@@ -3364,8 +3359,6 @@ ct_options(CS_CONNECTION * con, CS_INT action, CS_INT option, CS_VOID * param, C
+ 	TDS_INT tds_argsize = 0;
+ 	TDSSOCKET *tds;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_options(%p, %d, %d, %p, %d, %p)\n", con, action, option, param, paramlen, outlen);
+-
+ 	const char *action_string = NULL;
+ 	int i;
+ 
+@@ -3392,6 +3385,8 @@ ct_options(CS_CONNECTION * con, CS_INT action, CS_INT option, CS_VOID * param, C
+ 		, { CS_OPT_STATS_TIME,     TDS_OPT_STAT_TIME      }
+ 	};
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_options(%p, %d, %d, %p, %d, %p)\n", con, action, option, param, paramlen, outlen);
++
+ 	if (param == NULL)
+ 		return CS_FAIL;
+ 
+@@ -3839,10 +3834,10 @@ _ct_process_return_status(TDSSOCKET * tds)
+ 	TDSCOLUMN *curcol;
+ 	TDS_INT saved_status;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_ct_process_return_status(%p)\n", tds);
+-
+ 	enum { num_cols = 1 };
+ 
++	tdsdump_log(TDS_DBG_FUNC, "_ct_process_return_status(%p)\n", tds);
++
+ 	assert(tds);
+ 	saved_status = tds->ret_status;
+ 	tds_free_all_results(tds);
+@@ -4352,10 +4347,10 @@ ct_diag_storeclientmsg(CS_CONTEXT * context, CS_CONNECTION * conn, CS_CLIENTMSG
+ 	struct cs_diag_msg_client **curptr;
+ 	struct cs_diag_msg_svr **scurptr;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_diag_storeclientmsg(%p, %p, %p)\n", context, conn, message);
+-
+ 	CS_INT msg_count = 0;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_storeclientmsg(%p, %p, %p)\n", context, conn, message);
++
+ 	curptr = &(conn->ctx->clientstore);
+ 
+ 	scurptr = &(conn->ctx->svrstore);
+@@ -4409,10 +4404,10 @@ ct_diag_storeservermsg(CS_CONTEXT * context, CS_CONNECTION * conn, CS_SERVERMSG
+ 	struct cs_diag_msg_svr **curptr;
+ 	struct cs_diag_msg_client **ccurptr;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_diag_storeservermsg(%p, %p, %p)\n", context, conn, message);
+-
+ 	CS_INT msg_count = 0;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_storeservermsg(%p, %p, %p)\n", context, conn, message);
++
+ 	curptr = &(conn->ctx->svrstore);
+ 	ccurptr = &(conn->ctx->clientstore);
+ 
+@@ -4556,10 +4551,10 @@ ct_diag_countmsg(CS_CONTEXT * context, CS_INT type, CS_INT * count)
+ 	struct cs_diag_msg_client *curptr;
+ 	struct cs_diag_msg_svr *scurptr;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "ct_diag_countmsg(%p, %d, %p)\n", context, type, count);
+-
+ 	CS_INT msg_count = 0;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "ct_diag_countmsg(%p, %d, %p)\n", context, type, count);
++
+ 	if (type == CS_CLIENTMSG_TYPE || type == CS_ALLMSG_TYPE) {
+ 		curptr = context->clientstore;
+ 
+
+commit 2b473c6dbd8735a59409c18b5aac72cefe355451
+Author: freddy77 <freddy77>
+Date:   Mon May 11 07:53:26 2009 +0000
+
+    fix row buffering checks
+
+diff --git a/ChangeLog b/ChangeLog
+index eeda3fe..39db555 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon May 11 09:52:26 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/buffering.h: fix a test
++	* src/dblib/unittests/t0013.c src/dblib/unittests/t0013.sql:
++	- remove table if exixts
++
+ Mon May 11 09:24:40 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c: remove warnings and duplicate logs
+ 
+@@ -1531,4 +1536,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2783 2009/05/11 07:25:24 freddy77 Exp $
++$Id: ChangeLog,v 1.2784 2009/05/11 07:53:26 freddy77 Exp $
+diff --git a/src/dblib/buffering.h b/src/dblib/buffering.h
+index 4c9bf7b..d07c32b 100644
+--- a/src/dblib/buffering.h
++++ b/src/dblib/buffering.h
+@@ -21,8 +21,8 @@ static void buffer_check(const DBPROC_ROWBUF *buf)
+ 	/* no buffering */
+ 	if (buf->capacity == 0 || buf->capacity == 1) {
+ 		assert(buf->head == 0);
+-		assert(buf->tail == 0);
+-		assert(buf->rows == NULL);
++		assert(buf->tail == 0 || buf->tail == 1);
++		assert(buf->capacity == 1 || buf->rows == NULL);
+ 		return;
+ 	}
+ 
+@@ -432,12 +432,14 @@ buffer_set_capacity(DBPROCESS *dbproc, int nrows)
+ 
+ 	if (0 == nrows) {
+ 		buf->capacity = 1;
++		BUFFER_CHECK(buf);
+ 		return;
+ 	}
+ 
+ 	assert(0 < nrows);
+ 
+ 	buf->capacity = nrows;
++	BUFFER_CHECK(buf);
+ }
+ 
+ /*
+diff --git a/src/dblib/unittests/t0013.c b/src/dblib/unittests/t0013.c
+index 6f88015..a939907 100644
+--- a/src/dblib/unittests/t0013.c
++++ b/src/dblib/unittests/t0013.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0013.c,v 1.29 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: t0013.c,v 1.30 2009/05/11 07:53:26 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define BLOB_BLOCK_SIZE 4096
+@@ -106,6 +106,8 @@ main(int argc, char **argv)
+ 	fread((void *) blob, isiz, 1, fp);
+ 	fclose(fp);
+ 
++	drop_table();
++
+ 	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	while (dbresults(dbproc) != NO_MORE_RESULTS) {
+diff --git a/src/dblib/unittests/t0013.sql b/src/dblib/unittests/t0013.sql
+index 9f976c2..4cbebf5 100644
+--- a/src/dblib/unittests/t0013.sql
++++ b/src/dblib/unittests/t0013.sql
+@@ -1,3 +1,5 @@
++if object_id('freetds_dblib_t0013') is not null drop table freetds_dblib_t0013
++go
+ create table freetds_dblib_t0013 (i int not null, PigTure image not null)
+ go
+ insert into freetds_dblib_t0013 values (1, '')
+
+commit 50797347d598b12739407b61f0f76c67224af5de
+Author: freddy77 <freddy77>
+Date:   Mon May 11 09:05:11 2009 +0000
+
+    fix reading empty packets
+
+diff --git a/ChangeLog b/ChangeLog
+index 39db555..2c07e0e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon May 11 11:04:52 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/read.c: fix reading empty packets
++
+ Mon May 11 09:52:26 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/buffering.h: fix a test
+ 	* src/dblib/unittests/t0013.c src/dblib/unittests/t0013.sql:
+@@ -1536,4 +1539,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2784 2009/05/11 07:53:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2785 2009/05/11 09:05:11 freddy77 Exp $
+diff --git a/src/tds/read.c b/src/tds/read.c
+index ac76c7c..1f7886f 100644
+--- a/src/tds/read.c
++++ b/src/tds/read.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: read.c,v 1.108 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: read.c,v 1.109 2009/05/11 09:05:11 freddy77 Exp $");
+ 
+ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ 			    size_t * wire_size, char **outbuf, size_t * outbytesleft);
+@@ -71,7 +71,7 @@ tds_get_byte(TDSSOCKET * tds)
+ {
+ 	int rc;
+ 
+-	if (tds->in_pos >= tds->in_len) {
++	while (tds->in_pos >= tds->in_len) {
+ 		do {
+ 			if (IS_TDSDEAD(tds) || (rc = tds_read_packet(tds)) < 0)
+ 				return 0;
+
+commit c24c661452a4bd86a41d97063524a73c13a23eea
+Author: freddy77 <freddy77>
+Date:   Mon May 11 15:12:44 2009 +0000
+
+    test wide for output
+
+diff --git a/ChangeLog b/ChangeLog
+index 2c07e0e..82e1ef3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon May 11 17:11:52 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: test wide for output
++
+ Mon May 11 11:04:52 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/read.c: fix reading empty packets
+ 
+@@ -1539,4 +1542,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2785 2009/05/11 09:05:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2786 2009/05/11 15:12:44 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 4c38ffe..2e7d9ff 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -2,8 +2,10 @@
+ /* Test from Sebastien Flaesch */
+ 
+ #include "common.h"
++#include <ctype.h>
++#include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.15 2008/12/26 12:20:50 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.16 2009/05/11 15:12:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -49,7 +51,7 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ 
+ 	for (n = 0; n < len; ++n) {
+ 		sprintf(symbol, "%2x", (unsigned int)('a' + ((start+n) / 2 * step % ('z' - 'a' + 1))));
+-		if (buf[n] != symbol[(start+n) % 2])
++		if (tolower((unsigned char) buf[n]) != symbol[(start+n) % 2])
+ 			return 0;
+ 	}
+ 
+@@ -89,8 +91,19 @@ readBlob(SQLUSMALLINT pos)
+ 		failed = 1;
+ }
+ 
++static int
++from_sqlwchar(char *dst, const SQLWCHAR *src, int n)
++{
++	int i;
++	for (i = 0; i < n; ++i) {
++		assert(src[i] >= 0 && src[i] < 256);
++		dst[i] = src[i];
++	}
++	return n;
++}
++
+ static void
+-readBlobAsChar(SQLUSMALLINT pos, int step)
++readBlobAsChar(SQLUSMALLINT pos, int step, int wide)
+ {
+ 	SQLRETURN rc = SQL_SUCCESS_WITH_INFO;
+ 	char buf[8192];
+@@ -98,21 +111,33 @@ readBlobAsChar(SQLUSMALLINT pos, int step)
+ 	int i = 0;
+ 	int check;
+ 	int bufsize;
++
++	SQLSMALLINT type = SQL_C_CHAR;
++	unsigned int char_len = 1;
++	if (wide) {
++		char_len = sizeof(SQLWCHAR);
++		type = SQL_C_WCHAR;
++	}
+ 	
+-	if (step%2) bufsize = sizeof(buf) - 1;
++	if (step%2) bufsize = sizeof(buf) - char_len;
+ 	else bufsize = sizeof(buf);
+ 
+ 	printf(">> readBlobAsChar field %d\n", pos);
+ 	while (rc == SQL_SUCCESS_WITH_INFO) {
+ 		i++;
+-		rc = CHKGetData(pos, SQL_C_CHAR, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
++		rc = CHKGetData(pos, type, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
+ 		if (rc == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		if (len > (SQLLEN) bufsize)
+-			len = (SQLLEN) bufsize - 1;
+-		len -= len % 2;
++			len = (SQLLEN) bufsize - char_len;
++		len -= len % (2u * char_len);
+ 		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+-		
++
++		if (wide) {
++			len /= sizeof(SQLWCHAR);
++			from_sqlwchar((char *) buf, (SQLWCHAR *) buf, len + 1);
++		}
++
+ 		check =	check_hex(buf, len, 2*987 + total, 25);
+ 		if (!check) {
+ 			fprintf(stderr, "Wrong buffer content\n");
+@@ -141,7 +166,7 @@ main(int argc, char **argv)
+ 	SQLLEN vind2;
+ 	char buf3[NBYTES*2 + 1];
+ 	SQLLEN vind3;
+-	int cnt = 2;
++	int cnt = 2, wide;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+@@ -210,6 +235,7 @@ main(int argc, char **argv)
+ 
+ 	/* Now fetch rows ... */
+ 
++	for (wide = 0; wide < 2; ++wide)
+ 	for (i = 0; i < cnt; i++) {
+ 
+ 		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
+@@ -239,7 +265,7 @@ main(int argc, char **argv)
+ 
+ 		readBlob(1);
+ 		readBlob(2);
+-		readBlobAsChar(3, i);
++		readBlobAsChar(3, i, wide);
+ 
+ 		CHKCloseCursor("S");
+ 		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+
+commit fb467ab3ffd6cd3cd90f020e967216cf0beeea49
+Author: jklowden <jklowden>
+Date:   Wed May 20 14:17:31 2009 +0000
+
+    check ODBC library instead of isql for default directories.
+
+diff --git a/ChangeLog b/ChangeLog
+index 82e1ef3..328c664 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed May 20 10:15:08 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql 
++	- check ODBC library instead of isql for default directories. 
++
+ Mon May 11 17:11:52 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: test wide for output
+ 
+@@ -1542,4 +1546,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2786 2009/05/11 15:12:44 freddy77 Exp $
++$Id: ChangeLog,v 1.2787 2009/05/20 14:17:31 jklowden Exp $
+diff --git a/src/apps/osql b/src/apps/osql
+index 12e9bdc..077f5f4 100755
+--- a/src/apps/osql
++++ b/src/apps/osql
+@@ -1,5 +1,5 @@
+ #! /bin/sh
+-# $Id: osql,v 1.7 2008/05/09 18:49:04 jklowden Exp $
++# $Id: osql,v 1.8 2009/05/20 14:17:31 jklowden Exp $
+ #
+ # Check odbc.ini, odbcinst, and, optionally, freetds.conf, 
+ # then execute isql (assume it's unixODBC's isql).  
+@@ -41,59 +41,75 @@ fi
+ 
+ # Establish ODBC prefix directory
+ 
+-ODBC_DIR=$(strings ${ISQL} | grep ^/ | grep -v elf | grep -v '\.so\.' | head -1 | sed 's/lib$/etc/' )
++ISQL_DIR=$(strings ${ISQL} | grep ^/ | grep -v elf | grep -v '\.so\.' | head -1 | sed 's/lib$/etc/' )
+ 
+-# N.B.  better than head(1) would be a loop to test the strings.  Since we're looking for a directory, 
+-# something like this might work:
+-# for D in $(strings ${ISQL} | grep ^/ | grep -v elf | sed 's/lib$/etc/' )
+-# do
+-# 	if [ -d $D ]
+-# 	then
+-# 		ODBC_DIR = $D
+-# 	fi
+-# done
++INI_DIRNAME="/tmp/$(basename $0).$$"
++exec 3> ${INI_DIRNAME}
+ 
+-if [ -z "${ODBC_DIR}" ]
++# if no hard-coded directory is found in the isql executable, check the libraries. 
++if [ -z "${OVER_DIR}" ]
++then 
++	echo "checking shared odbc libraries linked to isql for default directories..."
++	(echo ${ISQL_DIR}; ldd "${ISQL}" | awk '/[-]lodbc/ {print $3}') \
++	| while read L
++	  do 
++	  	strings "$L" | grep '^/' | grep -v '/lib' \
++		| while read D 
++		  do 
++		  	if [ ! -s "${INI_DIRNAME}" ]
++			then
++			  	printf "	trying $D ... "
++			  	if [ -d "$D" -a -r "${D}/odbc.ini" ]
++				then
++					printf $D >&3
++					printf "OK"
++				fi
++				printf "\n"
++			fi
++		  done
++	  done
++fi
++
++ODBC_DIR=$(cat ${INI_DIRNAME}) && rm ${INI_DIRNAME}
++
++if [ -z "${ODBC_DIR}" -a -z "${OVER_DIR}" ]
+ then
+-	echo "$(basename $0): error: no potential directory strings in \"$(command -v isql)\""
++	echo "$(basename $0): problem: no potential directory strings in \"$(command -v isql)\""
++	echo "$(basename $0): advice: use \"osql -I DIR\" where DIR unixODBC\'s install prefix e.g. /usr/local"
+ 	echo "isql strings are:"
+ 	strings ${ISQL} | grep ^/ | sed 's/^/+ /'
+-	exit 1
++	#xit 1
+ fi
+ 
+ if [ "${OVER_DIR}" ]
+ then
+ 	if [ -d "${ODBC_DIR}" ]
+ 	then
+-		echo "\"${ODBC_DIR}\" (from isql) is a directory, "
+-		echo "	but is overridden by \"${OVER_DIR}\"."
++		echo "\"${ODBC_DIR}\" (from isql) is a directory, overridden by"
+ 	else 
+-		echo "${ODBC_DIR} (from isql) is not a directory"
+-		echo "	and is overridden by \"${OVER_DIR}\"."
++		echo "\"${ODBC_DIR}\" (from isql) is NOT a directory, overridden by"
+ 	fi
++	echo "\"${OVER_DIR}\"."
+ 	
+ 	if [ -d "${OVER_DIR}" ]
+ 	then
+ 		ODBC_DIR=${OVER_DIR}
+ 	else
+ 		echo "$(basename $0): error: \"${OVER_DIR}\" is not a directory (disallowing)"
++		exit 1
+ 	fi
+ fi
+ 
+-if [ ! -d "${ODBC_DIR}" ]
+-then
+-	echo "$(basename $0): error: ${ODBC_DIR} (from isql) is not a directory!"
+-	echo "isql strings are:"
+-	strings ${ISQL} | grep ^/ | grep -v elf | grep -v '\.so\.' | sed 's/^/+ /'
+-	return 1
+-fi
+-
+-echo "looking for odbc.ini and odbcinst.ini in ${ODBC_DIR}"
+-
+ # Look for server entry in odbc.ini 
+-
++echo 'checking odbc.ini files'
+ for F in "${HOME}/.odbc.ini" "${ODBC_DIR}/odbc.ini"
+ do
++	if [ ! -d "$(dirname $F)" ]
++	then
++		echo "$(dirname $0): error: $(basename $F) is not a directory!" 
++		continue
++	fi
++	
+ 	if [ -r "$F" ]
+ 	then
+ 		echo '	'reading \"$F\"
+@@ -145,7 +161,7 @@ do
+ 			continue
+ 		fi
+ 
+-		DRIVER=$(echo ${DRIVER_LINE} | awk '{print $3}')
++		DRIVER=$(echo ${DRIVER_LINE} | awk -F '[[:space:]]*=[[:space:]]*' '{print $2}')
+ 		if [ "${DRIVER}" ]
+ 		then
+ 			echo "driver \"${DRIVER}\" found for [$D] in $(basename ${ODBC_INI})"
+
+commit fb61279547df0c959cf9448511015d440fe6e61f
+Author: freddy77 <freddy77>
+Date:   Wed May 20 16:27:57 2009 +0000
+
+    improve odbc blob1 test
+
+diff --git a/ChangeLog b/ChangeLog
+index 328c664..eb278b9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed May 20 18:27:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c:
++	- allow easy extension and add some type check
++
+ Wed May 20 10:15:08 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/osql 
+ 	- check ODBC library instead of isql for default directories. 
+@@ -1546,4 +1550,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2787 2009/05/20 14:17:31 jklowden Exp $
++$Id: ChangeLog,v 1.2788 2009/05/20 16:27:57 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 2e7d9ff..ab70b45 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.16 2009/05/11 15:12:45 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.17 2009/05/20 16:27:57 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -58,8 +58,38 @@ check_hex(const char *buf, size_t len, unsigned int start, unsigned int step)
+ 	return 1;
+ }
+ 
++#define MAX_TESTS 10
++typedef struct {
++	unsigned num;
++	SQLSMALLINT c_type, sql_type;
++	const char *db_type;
++	unsigned gen1, gen2;
++	SQLLEN vind;
++	char *buf;
++} test_info;
++
++static test_info test_infos[MAX_TESTS];
++static unsigned num_tests = 0;
++
++static void
++dump(FILE* out, const char* start, void* buf, unsigned len)
++{
++	unsigned n;
++	char s[17];
++	if (len >= 16)
++		len = 16;
++	fprintf(out, "%s", start);
++	for (n = 0; n < len; ++n) {
++		unsigned char c = ((unsigned char*)buf)[n];
++		fprintf(out, " %02X", c);
++		s[n] = (c >= 0x20 && c < 127) ? (char) c : '.';
++	}
++	s[len] = 0;
++	fprintf(out, " - %s\n", s);
++}
++
+ static void
+-readBlob(SQLUSMALLINT pos)
++readBlob(test_info *t)
+ {
+ 	SQLRETURN rc;
+ 	char buf[4096];
+@@ -67,21 +97,19 @@ readBlob(SQLUSMALLINT pos)
+ 	int i = 0;
+ 	int check;
+ 
+-	printf(">> readBlob field %d\n", pos);
++	printf(">> readBlob field %d\n", t->num);
+ 	while (1) {
+ 		i++;
+-		rc = CHKGetData(pos, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len, "SINo");
++		rc = CHKGetData(t->num, SQL_C_BINARY, (SQLPOINTER) buf, (SQLINTEGER) sizeof(buf), &len, "SINo");
+ 		if (rc == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		if (len > (SQLLEN) sizeof(buf))
+ 			len = (SQLLEN) sizeof(buf);
+ 		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+-		if (pos == 1)
+-			check = check_chars(buf, len, 123 + total, 1);
+-		else
+-			check =	check_chars(buf, len, 987 + total, 25);
++		check = check_chars(buf, len, t->gen1 + total, t->gen2);
+ 		if (!check) {
+ 			fprintf(stderr, "Wrong buffer content\n");
++			dump(stderr, " buf ", buf, len);
+ 			failed = 1;
+ 		}
+ 		total += len;
+@@ -103,11 +131,11 @@ from_sqlwchar(char *dst, const SQLWCHAR *src, int n)
+ }
+ 
+ static void
+-readBlobAsChar(SQLUSMALLINT pos, int step, int wide)
++readBlobAsChar(test_info *t, int step, int wide)
+ {
+ 	SQLRETURN rc = SQL_SUCCESS_WITH_INFO;
+ 	char buf[8192];
+-	SQLLEN len, total = 0;
++	SQLLEN len, total = 0, len2;
+ 	int i = 0;
+ 	int check;
+ 	int bufsize;
+@@ -122,15 +150,21 @@ readBlobAsChar(SQLUSMALLINT pos, int step, int wide)
+ 	if (step%2) bufsize = sizeof(buf) - char_len;
+ 	else bufsize = sizeof(buf);
+ 
+-	printf(">> readBlobAsChar field %d\n", pos);
++	printf(">> readBlobAsChar field %d\n", t->num);
+ 	while (rc == SQL_SUCCESS_WITH_INFO) {
+ 		i++;
+-		rc = CHKGetData(pos, type, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
++		rc = CHKGetData(t->num, type, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
+ 		if (rc == SQL_NO_DATA || len <= 0)
+ 			break;
+-		if (len > (SQLLEN) bufsize)
+-			len = (SQLLEN) bufsize - char_len;
++		rc = CHKGetData(t->num, type, (SQLPOINTER) buf, 0, &len2, "SINo");
++//		printf("out_len %u bufsize %u len2 %u\n", (unsigned) len, (unsigned) bufsize, (unsigned) len2);
++		if (rc == SQL_SUCCESS_WITH_INFO)
++			len = len - len2;
++#if 0
++		if (len > (SQLLEN) (bufsize - char_len))
++			len = (SQLLEN) (bufsize - char_len);
+ 		len -= len % (2u * char_len);
++#endif
+ 		printf(">>     step %d: %d bytes readed\n", i, (int) len);
+ 
+ 		if (wide) {
+@@ -138,9 +172,10 @@ readBlobAsChar(SQLUSMALLINT pos, int step, int wide)
+ 			from_sqlwchar((char *) buf, (SQLWCHAR *) buf, len + 1);
+ 		}
+ 
+-		check =	check_hex(buf, len, 2*987 + total, 25);
++		check =	check_hex(buf, len, 2*t->gen1 + total, t->gen2);
+ 		if (!check) {
+ 			fprintf(stderr, "Wrong buffer content\n");
++			dump(stderr, " buf ", buf, len);
+ 			failed = 1;
+ 		}
+ 		total += len;
+@@ -150,6 +185,37 @@ readBlobAsChar(SQLUSMALLINT pos, int step, int wide)
+ 		failed = 1;
+ }
+ 
++static void
++add_test(SQLSMALLINT c_type, SQLSMALLINT sql_type, const char *db_type, unsigned gen1, unsigned gen2)
++{
++	test_info *t = NULL;
++	size_t buf_len;
++
++	if (num_tests >= MAX_TESTS) {
++		fprintf(stderr, "too max tests\n");
++		exit(1);
++	}
++
++	t = &test_infos[num_tests++];
++	t->num = num_tests;
++	t->c_type = c_type;
++	t->sql_type = sql_type;
++	t->db_type = db_type;
++	t->gen1 = gen1;
++	t->gen2 = gen2;
++	t->vind = 0;
++	buf_len = (c_type == SQL_C_CHAR) ? NBYTES*2+1: NBYTES;
++	t->buf = (char*) malloc(buf_len);
++	if (!t->buf) {
++		fprintf(stderr, "memory error\n");
++		exit(1);
++	}
++	if (c_type != SQL_C_CHAR)
++		fill_chars(t->buf, NBYTES, t->gen1, t->gen2);
++	else
++		memset(t->buf, 0, buf_len);
++	t->vind = SQL_LEN_DATA_AT_EXEC(buf_len);
++}
+ 
+ int
+ main(int argc, char **argv)
+@@ -160,18 +226,26 @@ main(int argc, char **argv)
+ 
+ 	int key;
+ 	SQLLEN vind0;
+-	char buf1[NBYTES];
+-	SQLLEN vind1;
+-	char buf2[NBYTES];
+-	SQLLEN vind2;
+-	char buf3[NBYTES*2 + 1];
+-	SQLLEN vind3;
+ 	int cnt = 2, wide;
++	char sql[256];
++	test_info *t = NULL;
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+-	Command("CREATE TABLE #tt ( k INT, t TEXT, b1 IMAGE, b2 IMAGE, v INT )");
++	add_test(SQL_C_BINARY, SQL_LONGVARCHAR,   "TEXT",  123, 1 );
++	add_test(SQL_C_BINARY, SQL_LONGVARBINARY, "IMAGE", 987, 25);
++	add_test(SQL_C_CHAR,   SQL_LONGVARBINARY, "IMAGE", 987, 25);
++	if (db_is_microsoft()) {
++		add_test(SQL_C_BINARY, SQL_WLONGVARCHAR, "NTEXT", 765, 12);
++		add_test(SQL_C_CHAR,   SQL_WLONGVARCHAR, "NTEXT", 237, 71);
++	}
++
++	strcpy(sql, "CREATE TABLE #tt(k INT");
++	for (t = test_infos; t < test_infos+num_tests; ++t)
++		sprintf(strchr(sql, 0), ",f%u %s", t->num, t->db_type);
++	strcat(sql, ",v INT)");
++	Command(sql);
+ 
+ 	old_Statement = Statement;
+ 	Statement = SQL_NULL_HSTMT;
+@@ -182,27 +256,21 @@ main(int argc, char **argv)
+ 
+ 		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
+ 
+-		CHKPrepare((SQLCHAR *) "INSERT INTO #tt VALUES ( ?, ?, ?, ?, ? )", SQL_NTS, "S");
++		strcpy(sql, "INSERT INTO #tt VALUES(?");
++		for (t = test_infos; t < test_infos+num_tests; ++t)
++			strcat(sql, ",?");
++		strcat(sql, ",?)");
++		CHKPrepare((SQLCHAR *) sql, SQL_NTS, "S");
+ 
+ 		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
+-		CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARCHAR, 0x10000000, 0, buf1, 0, &vind1, "S");
+-		CHKBindParameter(3, SQL_PARAM_INPUT, SQL_C_BINARY, SQL_LONGVARBINARY, 0x10000000, 0, buf2, 0, &vind2, "S");
+-		CHKBindParameter(4, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_LONGVARBINARY, 0x10000000, 0, buf3, 0, &vind3, "S");
+-		CHKBindParameter(5, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
++		for (t = test_infos; t < test_infos+num_tests; ++t)
++			CHKBindParameter(t->num+1, SQL_PARAM_INPUT, t->c_type, t->sql_type, 0x10000000, 0, t->buf, 0, &t->vind, "S");
++
++		CHKBindParameter(num_tests+2, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &key, 0, &vind0, "S");
+ 
+ 		key = i;
+ 		vind0 = 0;
+ 
+-		fill_chars(buf1, NBYTES, 123, 1);
+-		vind1 = SQL_LEN_DATA_AT_EXEC(NBYTES);
+-
+-		fill_chars(buf2, NBYTES, 987, 25);
+-		vind2 = SQL_LEN_DATA_AT_EXEC(NBYTES);
+-		
+-		memset(buf3, 0, sizeof(buf3));
+-		vind3 = SQL_LEN_DATA_AT_EXEC(2*NBYTES+1);
+-		
+-
+ 		printf(">> insert... %d\n", i);
+ 		RetCode = CHKExecute("SINe");
+ 		while (RetCode == SQL_NEED_DATA) {
+@@ -211,13 +279,16 @@ main(int argc, char **argv)
+ 			RetCode = CHKParamData((SQLPOINTER) & p, "SINe");
+ 			printf(">> SQLParamData: ptr = %p  RetCode = %d\n", (void *) p, RetCode);
+ 			if (RetCode == SQL_NEED_DATA) {
+-				if (p == buf3) {
+-					fill_hex(buf3, NBYTES, 987, 25);
+-					
++				for (t = test_infos; t < test_infos+num_tests && t->buf != p; ++t)
++					;
++				assert(t < test_infos+num_tests);
++				if (t->c_type == SQL_C_CHAR) {
++					fill_hex(p, NBYTES, t->gen1, t->gen2);
++
+ 					CHKPutData(p, NBYTES - (i&1), "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
+-					
++
+ 					CHKPutData(p + NBYTES - (i&1), NBYTES + (i&1), "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
+@@ -245,37 +316,46 @@ main(int argc, char **argv)
+ 			CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+ 		}
+ 
+-		CHKPrepare((SQLCHAR *) "SELECT t, b1, b2, v FROM #tt WHERE k = ?", SQL_NTS, "S");
++		strcpy(sql, "SELECT ");
++		for (t = test_infos; t < test_infos+num_tests; ++t)
++			sprintf(strchr(sql, 0), "f%u,", t->num);
++		strcat(sql, "v FROM #tt WHERE k = ?");
++		CHKPrepare((SQLCHAR *) sql, SQL_NTS, "S");
+ 
+ 		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_INTEGER, 0, 0, &i, 0, &vind0, "S");
+ 
+-		CHKBindCol(1, SQL_C_BINARY, NULL, 0, &vind1, "S");
+-		CHKBindCol(2, SQL_C_BINARY, NULL, 0, &vind2, "S");
+-		CHKBindCol(3, SQL_C_BINARY, NULL, 0, &vind3, "S");
+-		CHKBindCol(4, SQL_C_LONG, &key, 0, &vind0, "S");
++		for (t = test_infos; t < test_infos+num_tests; ++t) {
++			t->vind = SQL_DATA_AT_EXEC;
++			CHKBindCol(t->num, SQL_C_BINARY, NULL, 0, &t->vind, "S");
++		}
++		CHKBindCol(num_tests+1, SQL_C_LONG, &key, 0, &vind0, "S");
+ 
+ 		vind0 = 0;
+-		vind1 = SQL_DATA_AT_EXEC;
+-		vind2 = SQL_DATA_AT_EXEC;
+ 
+ 		CHKExecute("S");
+ 
+ 		CHKFetchScroll(SQL_FETCH_NEXT, 0, "S");
+ 		printf(">> fetch... %d\n", i);
+ 
+-		readBlob(1);
+-		readBlob(2);
+-		readBlobAsChar(3, i, wide);
++		for (t = test_infos; t < test_infos+num_tests; ++t) {
++			if (t->c_type == SQL_C_CHAR)
++				readBlobAsChar(t, i, wide);
++			else
++				readBlob(t);
++		}
+ 
+ 		CHKCloseCursor("S");
+ 		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+ 		Statement = SQL_NULL_HSTMT;
+ 	}
+-	
++
+ 	Statement = old_Statement;
+ 
+ 	Disconnect();
+ 
++	if (!failed)
++		printf("ok!\n");
++
+ 	return failed ? 1 : 0;
+ }
+ 
+
+commit f57ab849aefc2ab6cbeea946e929278533bd7342
+Author: freddy77 <freddy77>
+Date:   Wed May 20 16:34:52 2009 +0000
+
+    fix blob1 test
+
+diff --git a/ChangeLog b/ChangeLog
+index eb278b9..d58f97c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 20 18:34:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c: fix blob1 test
++
+ Wed May 20 18:27:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c:
+ 	- allow easy extension and add some type check
+@@ -1550,4 +1553,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2788 2009/05/20 16:27:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2789 2009/05/20 16:34:52 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 152494e..65fe4bf 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.80 2009/03/06 17:34:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.81 2009/05/20 16:34:52 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -212,6 +212,9 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		memcpy(curcol->column_collation, tds->collation, sizeof(tds->collation));
+ 	} else {
+ 		tds_set_param_type(dbc->tds_socket, curcol, dest_type);
++		/* use binary format for binary to char */
++		if (sql_src_type == SQL_C_BINARY && is_char_type(dest_type))
++			curcol->char_conv = NULL;
+ 	}
+ 	if (is_numeric_type(curcol->column_type)) {
+ 		curcol->column_prec = drec_ipd->sql_desc_precision;
+
+commit b0f42346f7f50754ccbeb3b9ccbee8affbd31724
+Author: freddy77 <freddy77>
+Date:   Wed May 20 16:36:58 2009 +0000
+
+    add test on bcp
+
+diff --git a/ChangeLog b/ChangeLog
+index d58f97c..c770295 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 20 18:36:51 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: prevent core and return error
++
+ Wed May 20 18:34:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c: fix blob1 test
+ 
+@@ -1553,4 +1556,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2789 2009/05/20 16:34:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2790 2009/05/20 16:36:58 freddy77 Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index e407004..c629325 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.184 2009/03/24 01:22:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.185 2009/05/20 16:36:58 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -411,6 +411,11 @@ bcp_colfmt(DBPROCESS * dbproc, int host_colnum, int host_type, int host_prefixle
+ 		return FAIL;
+ 	}
+ 
++	if (host_colnum > dbproc->hostfileinfo->host_colcount) {
++		dbperror(dbproc, SYBECNOR, 0);
++		return FAIL;
++	}
++
+ 	if (host_prefixlen != 0 && host_prefixlen != 1 && host_prefixlen != 2 && host_prefixlen != 4 && host_prefixlen != -1) {
+ 		dbperror(dbproc, SYBEBCPREF, 0);
+ 		return FAIL;
+
+commit a8742eb3b960a5729023cfce4323c65f8ffa5a26
+Author: freddy77 <freddy77>
+Date:   Thu May 21 16:30:57 2009 +0000
+
+    add wchar tests to blob1 test
+
+diff --git a/ChangeLog b/ChangeLog
+index c770295..3eaf349 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May 21 18:30:48 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: add wchar test
++
+ Wed May 20 18:36:51 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/bcp.c: prevent core and return error
+ 
+@@ -1556,4 +1559,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2790 2009/05/20 16:36:58 freddy77 Exp $
++$Id: ChangeLog,v 1.2791 2009/05/21 16:30:57 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index ab70b45..038da59 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.17 2009/05/20 16:27:57 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.18 2009/05/21 16:30:57 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -120,6 +120,15 @@ readBlob(test_info *t)
+ }
+ 
+ static int
++to_sqlwchar(SQLWCHAR *dst, const char *src, int n)
++{
++	int i = n;
++	while (--i >= 0)
++		dst[i] = (unsigned char) src[i];
++	return n * sizeof(SQLWCHAR);
++}
++
++static int
+ from_sqlwchar(char *dst, const SQLWCHAR *src, int n)
+ {
+ 	int i;
+@@ -204,19 +213,38 @@ add_test(SQLSMALLINT c_type, SQLSMALLINT sql_type, const char *db_type, unsigned
+ 	t->gen1 = gen1;
+ 	t->gen2 = gen2;
+ 	t->vind = 0;
+-	buf_len = (c_type == SQL_C_CHAR) ? NBYTES*2+1: NBYTES;
++	switch (c_type) {
++	case SQL_C_CHAR:
++		buf_len =  NBYTES*2+1;
++		break;
++	case SQL_C_WCHAR:
++		buf_len = (NBYTES*2+1) * sizeof(SQLWCHAR);
++		break;
++	default:
++		buf_len = NBYTES;
++	}
+ 	t->buf = (char*) malloc(buf_len);
+ 	if (!t->buf) {
+ 		fprintf(stderr, "memory error\n");
+ 		exit(1);
+ 	}
+-	if (c_type != SQL_C_CHAR)
++	if (c_type != SQL_C_CHAR && c_type != SQL_C_WCHAR)
+ 		fill_chars(t->buf, NBYTES, t->gen1, t->gen2);
+ 	else
+ 		memset(t->buf, 0, buf_len);
+ 	t->vind = SQL_LEN_DATA_AT_EXEC(buf_len);
+ }
+ 
++static void
++free_tests()
++{
++	while (num_tests > 0) {
++		test_info *t = &test_infos[--num_tests];
++		free(t->buf);
++		t->buf = NULL;
++	}
++}
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -236,9 +264,13 @@ main(int argc, char **argv)
+ 	add_test(SQL_C_BINARY, SQL_LONGVARCHAR,   "TEXT",  123, 1 );
+ 	add_test(SQL_C_BINARY, SQL_LONGVARBINARY, "IMAGE", 987, 25);
+ 	add_test(SQL_C_CHAR,   SQL_LONGVARBINARY, "IMAGE", 987, 25);
++	add_test(SQL_C_CHAR,   SQL_LONGVARCHAR,   "TEXT",  343, 47);
++	add_test(SQL_C_WCHAR,  SQL_LONGVARBINARY, "IMAGE", 561, 29);
++	add_test(SQL_C_WCHAR,  SQL_LONGVARCHAR,   "TEXT",  698, 24);
+ 	if (db_is_microsoft()) {
+ 		add_test(SQL_C_BINARY, SQL_WLONGVARCHAR, "NTEXT", 765, 12);
+ 		add_test(SQL_C_CHAR,   SQL_WLONGVARCHAR, "NTEXT", 237, 71);
++		add_test(SQL_C_WCHAR,  SQL_WLONGVARCHAR, "NTEXT", 687, 68);
+ 	}
+ 
+ 	strcpy(sql, "CREATE TABLE #tt(k INT");
+@@ -253,6 +285,9 @@ main(int argc, char **argv)
+ 	/* Insert rows ... */
+ 
+ 	for (i = 0; i < cnt; i++) {
++		/* MS do not save correctly char -> binary */
++		if (!driver_is_freetds() && i)
++			continue;
+ 
+ 		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
+ 
+@@ -282,14 +317,20 @@ main(int argc, char **argv)
+ 				for (t = test_infos; t < test_infos+num_tests && t->buf != p; ++t)
+ 					;
+ 				assert(t < test_infos+num_tests);
+-				if (t->c_type == SQL_C_CHAR) {
++				if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR) {
++					unsigned char_len = 1;
++
+ 					fill_hex(p, NBYTES, t->gen1, t->gen2);
++					if (t->c_type == SQL_C_WCHAR) {
++						char_len = sizeof(SQLWCHAR);
++						to_sqlwchar((SQLWCHAR*) p, p, NBYTES * 2);
++					}
+ 
+-					CHKPutData(p, NBYTES - (i&1), "S");
++					CHKPutData(p, (NBYTES - (i&1)) * char_len, "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES - (i&1));
+ 
+-					CHKPutData(p + NBYTES - (i&1), NBYTES + (i&1), "S");
++					CHKPutData(p + (NBYTES - (i&1)) * char_len, (NBYTES + (i&1)) * char_len, "S");
+ 
+ 					printf(">> param %p: total bytes written = %d\n", (void *) p, NBYTES + (i&1));
+ 				} else {
+@@ -308,6 +349,10 @@ main(int argc, char **argv)
+ 
+ 	for (wide = 0; wide < 2; ++wide)
+ 	for (i = 0; i < cnt; i++) {
++		/* MS do not save correctly char -> binary */
++		if (!driver_is_freetds() && i)
++			continue;
++
+ 
+ 		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
+ 
+@@ -338,7 +383,7 @@ main(int argc, char **argv)
+ 		printf(">> fetch... %d\n", i);
+ 
+ 		for (t = test_infos; t < test_infos+num_tests; ++t) {
+-			if (t->c_type == SQL_C_CHAR)
++			if (t->c_type == SQL_C_CHAR || t->c_type == SQL_C_WCHAR)
+ 				readBlobAsChar(t, i, wide);
+ 			else
+ 				readBlob(t);
+@@ -351,6 +396,7 @@ main(int argc, char **argv)
+ 
+ 	Statement = old_Statement;
+ 
++	free_tests();
+ 	Disconnect();
+ 
+ 	if (!failed)
+
+commit 05c9fdaa65d0ee25dff43ea241912b585da77b7a
+Author: freddy77 <freddy77>
+Date:   Thu May 21 16:35:21 2009 +0000
+
+    improve continue_parse_prepared_query
+
+diff --git a/ChangeLog b/ChangeLog
+index 3eaf349..4e5cdfa 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May 21 18:35:15 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/prepare_query.c: improve continue_parse_prepared_query
++
+ Thu May 21 18:30:48 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: add wchar test
+ 
+@@ -1559,4 +1562,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2791 2009/05/21 16:30:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2792 2009/05/21 16:35:21 freddy77 Exp $
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 5a2ed80..d9607dd 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.74 2008/11/12 10:38:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.75 2009/05/21 16:35:21 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -324,27 +324,20 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	/* copy to destination */
+ 	if (blob) {
+ 		TDS_CHAR *p;
+-		int dest_type, src_type, res;
+-		CONV_RESULT ores;
+-		TDS_DBC * dbc = stmt->dbc;
+ 		void *free_ptr = NULL;
+ 		SQLPOINTER extradata = NULL;
+ 		SQLLEN extralen = 0;
+ 
+-		if (0 == (dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type))) {
+-			odbc_errs_add(&stmt->errs, "07006", NULL); /* Restricted data type attribute violation */
+-			return SQL_ERROR;
+-		}
++		if (sql_src_type == SQL_C_CHAR) {
++			int dest_type, res;
++			CONV_RESULT ores;
++			TDS_DBC * dbc = stmt->dbc;
+ 
+-		/* test source type */
+-		/* TODO test intervals */
+-		src_type = odbc_c_to_server_type(sql_src_type);
+-		if (src_type == TDS_FAIL) {
+-			odbc_errs_add(&stmt->errs, "07006", NULL); /* Restricted data type attribute violation */
+-			return SQL_ERROR;
+-		}
++			if (0 == (dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type))) {
++				odbc_errs_add(&stmt->errs, "07006", NULL); /* Restricted data type attribute violation */
++				return SQL_ERROR;
++			}
+ 
+-		if (sql_src_type == SQL_C_CHAR) {
+ 			switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
+ 			case SYBBINARY:
+ 			case SYBVARBINARY:
+@@ -352,9 +345,9 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 			case XSYBVARBINARY:
+ 			case SYBLONGBINARY:
+ 			case SYBIMAGE:
+-				if (!*((char*)DataPtr+len-1))
++				if (len && !*((char*)DataPtr+len-1))
+ 					--len;
+-					
++
+ 				if (!len)
+ 					return SQL_SUCCESS;
+ 					
+@@ -364,7 +357,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 					data[0] = curcol->column_text_sqlputdatainfo;
+ 					data[1] = *(char*)DataPtr;
+ 				    
+-					res = tds_convert(dbc->env->tds_ctx, src_type, data, 2, dest_type, &ores);
++					res = tds_convert(dbc->env->tds_ctx, SYBVARCHAR, data, 2, dest_type, &ores);
+ 					if (res < 0) {
+ 						odbc_convert_err_set(&dbc->errs, res);
+ 						return SQL_ERROR;
+@@ -382,7 +375,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 					curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
+ 				}
+ 
+-				res = tds_convert(dbc->env->tds_ctx, src_type, DataPtr, len, dest_type, &ores);
++				res = tds_convert(dbc->env->tds_ctx, SYBVARCHAR, DataPtr, len, dest_type, &ores);
+ 				if (res < 0) {
+ 					odbc_convert_err_set(&dbc->errs, res);
+ 					free(extradata);
+
+commit ef9cb0568baee9b4269fb94f0fdfefe15afb5837
+Author: freddy77 <freddy77>
+Date:   Thu May 21 16:39:37 2009 +0000
+
+    extract and reuse tds_char2hex
+
+diff --git a/ChangeLog b/ChangeLog
+index 4e5cdfa..1a59002 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu May 21 18:39:31 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsconvert.h src/odbc/prepare_query.c src/tds/convert.c:
++	- extract and reuse tds_char2hex
++
+ Thu May 21 18:35:15 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/prepare_query.c: improve continue_parse_prepared_query
+ 
+@@ -1562,4 +1566,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2792 2009/05/21 16:35:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2793 2009/05/21 16:39:37 freddy77 Exp $
+diff --git a/include/tdsconvert.h b/include/tdsconvert.h
+index 449f826..9699247 100644
+--- a/include/tdsconvert.h
++++ b/include/tdsconvert.h
+@@ -32,7 +32,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsconvert.h,v 1.24 2008/12/09 09:39:14 freddy77 Exp $ */
++/* $Id: tdsconvert.h,v 1.25 2009/05/21 16:39:38 freddy77 Exp $ */
+ 
+ typedef union conv_result
+ {
+@@ -89,6 +89,7 @@ struct tds_time
+ unsigned char tds_willconvert(int srctype, int desttype);
+ 
+ TDS_INT tds_get_null_type(int srctype);
++TDS_INT tds_char2hex(TDS_CHAR *dest, TDS_UINT destlen, const TDS_CHAR * src, TDS_UINT srclen);
+ TDS_INT tds_convert(const TDSCONTEXT * context, int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttype, CONV_RESULT * cr);
+ 
+ size_t tds_strftime(char *buf, size_t maxsize, const char *format, const TDSDATEREC * timeptr);
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index d9607dd..b41fae9 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.75 2009/05/21 16:35:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.76 2009/05/21 16:39:38 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -206,8 +206,8 @@ parse_prepared_query(struct _hstmt *stmt, int compute_row)
+ 		/* find bound parameter */
+ 		if (stmt->param_num > stmt->apd->header.sql_desc_count || stmt->param_num > stmt->ipd->header.sql_desc_count) {
+ 			tdsdump_log(TDS_DBG_FUNC, "parse_prepared_query: logic_error: parameter out of bounds: "
+-						  "%d > %d || %d > %d\n", 
+-						   stmt->param_num, stmt->apd->header.sql_desc_count, 
++						  "%d > %d || %d > %d\n",
++						   stmt->param_num, stmt->apd->header.sql_desc_count,
+ 						   stmt->param_num, stmt->ipd->header.sql_desc_count);
+ 			return SQL_ERROR;
+ 		}
+@@ -252,9 +252,9 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	TDSCOLUMN *curcol;
+ 	TDSBLOB *blob;
+ 	int sql_src_type;
+-	
++
+ 	assert(stmt);
+-	
++
+ 	tdsdump_log(TDS_DBG_FUNC, "continue_parse_prepared_query with parameter %d\n", stmt->param_num);
+ 
+ 	if (!stmt->params) {
+@@ -283,7 +283,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 			odbc_errs_add(&stmt->errs, "HY009", NULL); /* Invalid use of null pointer */
+ 			return SQL_ERROR;
+ 		}
+-	}		
++	}
+ 
+ 	/* get C type */
+ 	sql_src_type = drec_apd->sql_desc_concise_type;
+@@ -307,8 +307,8 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	default:
+ 		if (DataPtr && StrLen_or_Ind < 0) {
+ 			/*
+-			 * "The argument DataPtr was not a null pointer, and 
+-			 * the argument StrLen_or_Ind was less than 0 
++			 * "The argument DataPtr was not a null pointer, and
++			 * the argument StrLen_or_Ind was less than 0
+ 			 * but not equal to SQL_NTS or SQL_NULL_DATA."
+ 			 */
+ 			odbc_errs_add(&stmt->errs, "HY090", NULL);
+@@ -324,20 +324,10 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	/* copy to destination */
+ 	if (blob) {
+ 		TDS_CHAR *p;
+-		void *free_ptr = NULL;
+-		SQLPOINTER extradata = NULL;
+-		SQLLEN extralen = 0;
++		int binary_convert = 0;
++		SQLLEN orig_len;
+ 
+ 		if (sql_src_type == SQL_C_CHAR) {
+-			int dest_type, res;
+-			CONV_RESULT ores;
+-			TDS_DBC * dbc = stmt->dbc;
+-
+-			if (0 == (dest_type = odbc_sql_to_server_type(dbc->tds_socket, drec_ipd->sql_desc_concise_type))) {
+-				odbc_errs_add(&stmt->errs, "07006", NULL); /* Restricted data type attribute violation */
+-				return SQL_ERROR;
+-			}
+-
+ 			switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
+ 			case SYBBINARY:
+ 			case SYBVARBINARY:
+@@ -350,71 +340,71 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 
+ 				if (!len)
+ 					return SQL_SUCCESS;
+-					
+-				if (curcol->column_cur_size > 0
+-				&&  curcol->column_text_sqlputdatainfo) {
+-					TDS_CHAR data[2];
+-					data[0] = curcol->column_text_sqlputdatainfo;
+-					data[1] = *(char*)DataPtr;
+-				    
+-					res = tds_convert(dbc->env->tds_ctx, SYBVARCHAR, data, 2, dest_type, &ores);
+-					if (res < 0) {
+-						odbc_convert_err_set(&dbc->errs, res);
+-						return SQL_ERROR;
+-					}
+-				    
+-					extradata = ores.ib;
+-					extralen = res;
+-					
+-					DataPtr = (SQLPOINTER) (((char*)DataPtr) + 1);
+-					--len;
+-				}
+-				
+-			        if (len&1) {
+-					--len;
+-					curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
+-				}
+ 
+-				res = tds_convert(dbc->env->tds_ctx, SYBVARCHAR, DataPtr, len, dest_type, &ores);
+-				if (res < 0) {
+-					odbc_convert_err_set(&dbc->errs, res);
+-					free(extradata);
+-					return SQL_ERROR;
+-				}
+-			    
+-				DataPtr = free_ptr = ores.ib;
+-				len = res;
++				binary_convert = 1;
++				orig_len = len;
++				len = len / 2u + 1u;
+ 				break;
+ 			}
+ 		}
+ 
+ 		if (blob->textvalue)
+-			p = (TDS_CHAR *) realloc(blob->textvalue, len + extralen + curcol->column_cur_size);
++			p = (TDS_CHAR *) realloc(blob->textvalue, len + curcol->column_cur_size);
+ 		else {
+ 			assert(curcol->column_cur_size == 0);
+-			p = (TDS_CHAR *) malloc(len + extralen);
++			p = (TDS_CHAR *) malloc(len);
+ 		}
+ 		if (!p) {
+-			free(free_ptr);
+-			free(extradata);
+ 			odbc_errs_add(&stmt->errs, "HY001", NULL); /* Memory allocation error */
+ 			return SQL_ERROR;
+ 		}
+ 		blob->textvalue = p;
+-		if (extralen) {
+-			memcpy(blob->textvalue + curcol->column_cur_size, extradata, extralen);
+-			curcol->column_cur_size += extralen;
++
++		p += curcol->column_cur_size;
++		if (binary_convert) {
++			int res;
++
++			len = orig_len;
++
++			if (curcol->column_cur_size > 0
++			&&  curcol->column_text_sqlputdatainfo) {
++				TDS_CHAR data[2];
++				data[0] = curcol->column_text_sqlputdatainfo;
++				data[1] = *(char*)DataPtr;
++
++				res = tds_char2hex(p, 1, data, 2);
++				if (res < 0) {
++					odbc_convert_err_set(&stmt->errs, res);
++					return SQL_ERROR;
++				}
++				p += res;
++
++				DataPtr = (SQLPOINTER) (((char*)DataPtr) + 1);
++				--len;
++			}
++
++			if (len&1) {
++				--len;
++				curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
++			}
++
++			res = tds_char2hex(p, len / 2u, DataPtr, len);
++			if (res < 0) {
++				odbc_convert_err_set(&stmt->errs, res);
++				return SQL_ERROR;
++			}
++			p += res;
++
++			len = p - (blob->textvalue + curcol->column_cur_size);
++		} else {
++			memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len);
+ 		}
+-		memcpy(blob->textvalue + curcol->column_cur_size, DataPtr, len);
+-		
+-		free(extradata);
+-		free(free_ptr);
+ 	} else {
+ 		memcpy(curcol->column_data + curcol->column_cur_size, DataPtr, len);
+ 	}
+-	
++
+ 	curcol->column_cur_size += len;
+-	
++
+ 	if (blob && curcol->column_cur_size > curcol->column_size)
+ 		curcol->column_size = curcol->column_cur_size;
+ 
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 32dc709..2c0dad4 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.188 2009/02/07 00:26:22 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.189 2009/05/21 16:39:38 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -277,11 +277,51 @@ tds_convert_binary(int srctype, const TDS_UCHAR * src, TDS_INT srclen, int destt
+ 	return TDS_CONVERT_NOAVAIL;
+ }
+ 
++TDS_INT
++tds_char2hex(TDS_CHAR *dest, TDS_UINT destlen, const TDS_CHAR * src, TDS_UINT srclen)
++{
++	unsigned int i;
++	unsigned char hex1, c = 0;
++
++	/* if srclen if odd we must add a "0" before ... */
++	i = 0;		/* number where to start converting */
++	if (srclen & 1) {
++		++srclen;
++		i = 1;
++		--src;
++	}
++	for (; i < srclen; ++i) {
++		hex1 = src[i];
++
++		if ('0' <= hex1 && hex1 <= '9')
++			hex1 &= 0x0f;
++		else {
++			hex1 &= 0x20 ^ 0xff;	/* mask off 0x20 to ensure upper case */
++			if ('A' <= hex1 && hex1 <= 'F') {
++				hex1 -= ('A' - 10);
++			} else {
++				tdsdump_log(TDS_DBG_INFO1,
++					    "error_handler:  attempt to convert data stopped by syntax error in source field \n");
++				return TDS_CONVERT_SYNTAX;
++			}
++		}
++		assert(hex1 < 0x10);
++
++		if ((i/2u) >= destlen)
++			continue;
++
++		if (i & 1)
++			dest[i / 2u] = c | hex1;
++		else
++			c = hex1 << 4;
++	}
++	return srclen / 2u;
++}
++
+ static TDS_INT
+ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttype, CONV_RESULT * cr)
+ {
+ 	unsigned int i, j;
+-	unsigned char hex1;
+ 
+ 	TDS_INT8 mymoney;
+ 	char mynumber[39];
+@@ -324,46 +364,13 @@ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttyp
+ 		/* a binary string output will be half the length of */
+ 		/* the string which represents it in hexadecimal     */
+ 
+-		/* if srclen if odd we must add a "0" before ... */
+-		j = 0;		/* number where to start converting */
+-		if (srclen & 1) {
+-			++srclen;
+-			j = 1;
+-			--src;
+-		}
+ 		ib = cr->cb.ib;
+ 		if (desttype != TDS_CONVERT_BINARY) {
+-			cr->ib = (TDS_CHAR *) malloc(srclen / 2);
++			cr->ib = (TDS_CHAR *) malloc((srclen + 1u) / 2u);
+ 			test_alloc(cr->ib);
+ 			ib = cr->ib;
+ 		}
+-
+-		for (i = srclen; i > j;) {
+-			hex1 = src[--i];
+-
+-			if ('0' <= hex1 && hex1 <= '9')
+-				hex1 &= 0x0f;
+-			else {
+-				hex1 &= 0x20 ^ 0xff;	/* mask off 0x20 to ensure upper case */
+-				if ('A' <= hex1 && hex1 <= 'F') {
+-					hex1 -= ('A' - 10);
+-				} else {
+-					tdsdump_log(TDS_DBG_INFO1,
+-						    "error_handler:  attempt to convert data stopped by syntax error in source field \n");
+-					return TDS_CONVERT_SYNTAX;
+-				}
+-			}
+-			assert(hex1 < 0x10);
+-
+-			if (desttype == TDS_CONVERT_BINARY && (i/2) >= cr->cb.len)
+-				continue;
+-
+-			if (i & 1)
+-				ib[i / 2] = hex1;
+-			else
+-				ib[i / 2] |= hex1 << 4;
+-		}
+-		return srclen / 2;
++		return tds_char2hex(ib, desttype == TDS_CONVERT_BINARY ? cr->cb.len : 0xffffffffu, src, srclen);
+ 		break;
+ 	case SYBINT1:
+ 		if ((rc = string_to_int(src, src + srclen, &tds_i)) < 0)
+
+commit 2829e221b0cd89eccf1c553f1bc5c1b87aba1232
+Author: freddy77 <freddy77>
+Date:   Thu May 21 16:41:27 2009 +0000
+
+    support wchar -> binary conversions
+
+diff --git a/ChangeLog b/ChangeLog
+index 1a59002..7892c24 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu May 21 18:41:21 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/prepare_query.c src/odbc/unittests/blob1.c:
++	- support wchar -> binary conversions
++
+ Thu May 21 18:39:31 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsconvert.h src/odbc/prepare_query.c src/tds/convert.c:
+ 	- extract and reuse tds_char2hex
+@@ -1566,4 +1570,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2793 2009/05/21 16:39:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2794 2009/05/21 16:41:27 freddy77 Exp $
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index b41fae9..418513c 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.76 2009/05/21 16:39:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.77 2009/05/21 16:41:27 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -243,6 +243,48 @@ start_parse_prepared_query(struct _hstmt *stmt, int compute_row)
+ 	return parse_prepared_query(stmt, compute_row);
+ }
+ 
++static TDS_INT
++odbc_wchar2hex(TDS_CHAR *dest, TDS_UINT destlen, const SQLWCHAR * src, TDS_UINT srclen)
++{
++	unsigned int i;
++	SQLWCHAR hex1, c = 0;
++
++	/* if srclen if odd we must add a "0" before ... */
++	i = 0;		/* number where to start converting */
++	if (srclen & 1) {
++		++srclen;
++		i = 1;
++		--src;
++	}
++	for (; i < srclen; ++i) {
++		hex1 = src[i];
++
++		if ('0' <= hex1 && hex1 <= '9')
++			hex1 &= 0x0f;
++		else {
++			hex1 &= (SQLWCHAR) ~0x20u;	/* mask off 0x20 to ensure upper case */
++			if ('A' <= hex1 && hex1 <= 'F') {
++				hex1 -= ('A' - 10);
++			} else {
++				tdsdump_log(TDS_DBG_INFO1,
++					    "error_handler:  attempt to convert data stopped by syntax error in source field \n");
++				return TDS_CONVERT_SYNTAX;
++			}
++		}
++		assert(hex1 < 0x10);
++
++		if ((i/2u) >= destlen)
++			continue;
++
++		if (i & 1)
++			dest[i / 2u] = c | hex1;
++		else
++			c = hex1 << 4;
++	}
++	return srclen / 2u;
++}
++
++
+ int
+ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN StrLen_or_Ind)
+ {
+@@ -327,7 +369,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 		int binary_convert = 0;
+ 		SQLLEN orig_len;
+ 
+-		if (sql_src_type == SQL_C_CHAR) {
++		if (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR) {
+ 			switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
+ 			case SYBBINARY:
+ 			case SYBVARBINARY:
+@@ -335,9 +377,12 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 			case XSYBVARBINARY:
+ 			case SYBLONGBINARY:
+ 			case SYBIMAGE:
+-				if (len && !*((char*)DataPtr+len-1))
++				if (len && sql_src_type == SQL_C_CHAR && !*((char*)DataPtr+len-1))
+ 					--len;
+ 
++				if (sql_src_type == SQL_C_WCHAR)
++					len /= sizeof(SQLWCHAR);
++
+ 				if (!len)
+ 					return SQL_SUCCESS;
+ 
+@@ -368,27 +413,30 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 
+ 			if (curcol->column_cur_size > 0
+ 			&&  curcol->column_text_sqlputdatainfo) {
+-				TDS_CHAR data[2];
++				SQLWCHAR data[2];
+ 				data[0] = curcol->column_text_sqlputdatainfo;
+-				data[1] = *(char*)DataPtr;
++				data[1] = (sql_src_type == SQL_C_CHAR) ? *(unsigned char*)DataPtr : *(SQLWCHAR*)DataPtr;
+ 
+-				res = tds_char2hex(p, 1, data, 2);
++				res = odbc_wchar2hex(p, 1, data, 2);
+ 				if (res < 0) {
+ 					odbc_convert_err_set(&stmt->errs, res);
+ 					return SQL_ERROR;
+ 				}
+ 				p += res;
+ 
+-				DataPtr = (SQLPOINTER) (((char*)DataPtr) + 1);
++				DataPtr = (SQLPOINTER) (((char*)DataPtr) +
++					(sql_src_type == SQL_C_CHAR ? 1 : sizeof(SQLWCHAR)));
+ 				--len;
+ 			}
+ 
+ 			if (len&1) {
+ 				--len;
+-				curcol->column_text_sqlputdatainfo = *((char*)DataPtr+len);
++				curcol->column_text_sqlputdatainfo = (sql_src_type == SQL_C_CHAR) ? ((char*)DataPtr)[len] : ((SQLWCHAR*)DataPtr)[len];
+ 			}
+ 
+-			res = tds_char2hex(p, len / 2u, DataPtr, len);
++			res = (sql_src_type == SQL_C_CHAR) ?
++				tds_char2hex(p, len / 2u, DataPtr, len):
++				odbc_wchar2hex(p, len / 2u, DataPtr, len);
+ 			if (res < 0) {
+ 				odbc_convert_err_set(&stmt->errs, res);
+ 				return SQL_ERROR;
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 038da59..04cd1e3 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.18 2009/05/21 16:30:57 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.19 2009/05/21 16:41:27 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -133,7 +133,7 @@ from_sqlwchar(char *dst, const SQLWCHAR *src, int n)
+ {
+ 	int i;
+ 	for (i = 0; i < n; ++i) {
+-		assert(src[i] >= 0 && src[i] < 256);
++		assert(src[i] < 256);
+ 		dst[i] = src[i];
+ 	}
+ 	return n;
+@@ -236,7 +236,7 @@ add_test(SQLSMALLINT c_type, SQLSMALLINT sql_type, const char *db_type, unsigned
+ }
+ 
+ static void
+-free_tests()
++free_tests(void)
+ {
+ 	while (num_tests > 0) {
+ 		test_info *t = &test_infos[--num_tests];
+
+commit 7cd284df245b6eeff40d19d3f0c34ea0724968d1
+Author: freddy77 <freddy77>
+Date:   Thu May 21 21:58:42 2009 +0000
+
+    update notes
+
+diff --git a/ChangeLog b/ChangeLog
+index 7892c24..60f661c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May 21 23:58:34 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO.freddy src/odbc/unittests/blob1.c: update notes
++
+ Thu May 21 18:41:21 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/prepare_query.c src/odbc/unittests/blob1.c:
+ 	- support wchar -> binary conversions
+@@ -1570,4 +1573,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2794 2009/05/21 16:41:27 freddy77 Exp $
++$Id: ChangeLog,v 1.2795 2009/05/21 21:58:42 freddy77 Exp $
+diff --git a/TODO.freddy b/TODO.freddy
+index d84a9d4..8668fb5 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -46,16 +46,10 @@ Free unused cursors and dynamic and/or reuse them
+ ODBC SQL_C_CHAR with wide
+ -------------------------
+ Check iso8859-1 for single ??
+-test to review
+-- data.c (char -> sql_c_char) DONE
+-- genparams.c DONE
+-- getdata.c DONE
+-- putdata.c DONE
+-- blob1.c (SQLGetData test with binary -> char and between chars)
+ Is it possible to support direct binding for parameters using different
+ encodings? For instance client <-> server iso8859-1 <-> ucs2. It should be
+ possible changing TDSCOLUMN->char_conv.
+-Merge putdata and blob1 tests, tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases).
++Merge putdata and blob1 tests.
+ Check blob1 dialog, seems to prepare twice during insert.
+ Do merge a bit continue_parse_prepared_query and odbc_sql2tds ??
+ 
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 04cd1e3..2339bea 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.19 2009/05/21 16:41:27 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.20 2009/05/21 21:58:43 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -261,6 +261,7 @@ main(int argc, char **argv)
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
++	/* tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases) */
+ 	add_test(SQL_C_BINARY, SQL_LONGVARCHAR,   "TEXT",  123, 1 );
+ 	add_test(SQL_C_BINARY, SQL_LONGVARBINARY, "IMAGE", 987, 25);
+ 	add_test(SQL_C_CHAR,   SQL_LONGVARBINARY, "IMAGE", 987, 25);
+
+commit 241b8d0967f3104fd6f84816e6d8a349f4c06c05
+Author: freddy77 <freddy77>
+Date:   Fri May 22 17:33:35 2009 +0000
+
+    fix genparams
+
+diff --git a/ChangeLog b/ChangeLog
+index 60f661c..fe54cc7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri May 22 19:33:28 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c: fix genparams
++
+ Thu May 21 23:58:34 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO.freddy src/odbc/unittests/blob1.c: update notes
+ 
+@@ -1573,4 +1576,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2795 2009/05/21 21:58:42 freddy77 Exp $
++$Id: ChangeLog,v 1.2796 2009/05/22 17:33:35 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 65fe4bf..27e657c 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.81 2009/05/20 16:34:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.82 2009/05/22 17:33:36 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -362,7 +362,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 	case SYBNVARCHAR:
+ 	case SYBNTEXT:
+ 	case SYBTEXT:
+-		if (!need_data && (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR)) {
++		if (!need_data && (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR || sql_src_type == SQL_C_BINARY)) {
+ 			if (curcol->column_data && curcol->column_data_free)
+ 				curcol->column_data_free(curcol);
+ 			curcol->column_data_free = NULL;
+@@ -390,6 +390,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		return SQL_ERROR;
+ 	}
+ 
++	/* fill data with SQLPutData */
+ 	if (need_data) {
+ 		curcol->column_cur_size = 0;
+ 		return SQL_NEED_DATA;
+
+commit 0d132a5077b2039bd4d9b104add3eaef9a8431c9
+Author: freddy77 <freddy77>
+Date:   Tue May 26 16:20:32 2009 +0000
+
+    small change
+
+diff --git a/ChangeLog b/ChangeLog
+index fe54cc7..c267c8d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue May 26 18:18:50 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: reduce num scope
++
+ Fri May 22 19:33:28 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c: fix genparams
+ 
+@@ -1576,4 +1579,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2796 2009/05/22 17:33:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2797 2009/05/26 16:20:32 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 3d227af..c45be3b 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.235 2009/03/19 16:02:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.236 2009/05/26 16:20:32 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1440,7 +1440,6 @@ static int
+ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ {
+ 	unsigned char *src;
+-	TDS_NUMERIC *num;
+ 	TDSBLOB *blob = NULL;
+ 	size_t colsize, size;
+ 
+@@ -1598,7 +1597,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 
+ 		/* put real data */
+ 		if (is_numeric_type(curcol->column_type)) {
+-			num = (TDS_NUMERIC *) src;
++			TDS_NUMERIC *num = (TDS_NUMERIC *) src;
+ 			tds_put_n(tds, num->array, colsize);
+ 		} else if (blob) {
+ 			tds_put_n(tds, s, colsize);
+
+commit d974be78384cfaee2e58a8edf75704a3d0d1b013
+Author: freddy77 <freddy77>
+Date:   Wed May 27 17:58:02 2009 +0000
+
+    fix test for MS ODBC
+
+diff --git a/ChangeLog b/ChangeLog
+index c267c8d..e0ba2fe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 27 19:57:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: fix for MS ODBC
++
+ Tue May 26 18:18:50 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c: reduce num scope
+ 
+@@ -1579,4 +1582,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2797 2009/05/26 16:20:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2798 2009/05/27 17:58:02 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index acb7ecb..8411ed6 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.42 2009/03/17 09:05:47 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.43 2009/05/27 17:58:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -79,6 +79,13 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 		CHKExecute("S");
+ 	}
+ 
++	/*
++	 * MS OBDC requires it cause first recordset is a recordset with a
++	 * warning caused by the way it execute RPC (via EXEC statement)
++	 */
++	if (use_cursors && !driver_is_freetds())
++		SQLMoreResults(Statement);
++
+ 	/* test results */
+ 	sbuf[0] = 0;
+ 	switch (out_c_type) {
+@@ -297,7 +304,9 @@ AllTests(void)
+ 		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "313233");
+ 	/* FIXME our driver ignore precision for date */
+ 	precision = 3;
+-	TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
++	/* Some MS driver incorrectly prepare with smalldatetime*/
++	if (!use_cursors || driver_is_freetds())
++		TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
+ 	TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP,
+ 	     big_endian ? "0000949700FB9640" : "979400004096FB00");
+ 	TestInput(SQL_C_TYPE_TIMESTAMP, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", "2005-07-22 09:51:34");
+
+commit d10765f89e9a92702d34fd3f44529aa5255babf3
+Author: freddy77 <freddy77>
+Date:   Thu May 28 16:15:29 2009 +0000
+
+    add SYBDECIMAL to dblib tests definitions
+
+diff --git a/ChangeLog b/ChangeLog
+index e0ba2fe..7de0222 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May 28 18:15:23 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.h: add SYBDECIMAL
++
+ Wed May 27 19:57:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c: fix for MS ODBC
+ 
+@@ -1582,4 +1585,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2798 2009/05/27 17:58:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2799 2009/05/28 16:15:29 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h
+index 1f5bcb5..e167ce3 100644
+--- a/src/dblib/unittests/common.h
++++ b/src/dblib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.18 2009/03/19 13:11:41 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.19 2009/05/28 16:15:29 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #if HAVE_CONFIG_H
+@@ -64,6 +64,7 @@ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_wa
+ #define SYBTEXT     SQLTEXT
+ #define SYBBINARY   SQLBINARY
+ #define SYBIMAGE    SQLIMAGE
++#define SYBDECIMAL  SQLDECIMAL
+ 
+ #define dberrhandle(h) dberrhandle((DBERRHANDLE_PROC) h)
+ #define dbmsghandle(h) dbmsghandle((DBMSGHANDLE_PROC) h)
+
+commit 915ce7955221e04d59dc0ae0ccd97970c60f8eb1
+Author: freddy77 <freddy77>
+Date:   Thu May 28 16:17:49 2009 +0000
+
+    add tests for mssql2005 types
+
+diff --git a/ChangeLog b/ChangeLog
+index 7de0222..59e991c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu May 28 18:17:43 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c: add tests for mssql2005 types
++
+ Thu May 28 18:15:23 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.h: add SYBDECIMAL
+ 
+@@ -1585,4 +1588,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2799 2009/05/28 16:15:29 freddy77 Exp $
++$Id: ChangeLog,v 1.2800 2009/05/28 16:17:49 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 0d38b0b..2f1a59c 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.26 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.27 2009/05/28 16:17:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -178,6 +178,13 @@ main(int argc, char *argv[])
+ 	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_WCHAR, "23 2006-06-09 11:22:44.000");
+ 	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_WCHAR, "19 2006-06-12 22:37:00");
+ 
++	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
++		Test("VARCHAR(MAX)", "goodbye!", SQL_C_CHAR, "8 goodbye!");
++		Test("NVARCHAR(MAX)", "Micio mao", SQL_C_CHAR, "9 Micio mao");
++		Test("VARBINARY(MAX)", "ciao", SQL_C_BINARY, "6369616F");
++		Test("XML", "<a b=\"aaa\"><b>ciao</b>hi</a>", SQL_C_CHAR, "28 <a b=\"aaa\"><b>ciao</b>hi</a>");
++	}
++
+ 	Disconnect();
+ 
+ 	if (!result)
+
+commit 70874918ca50439f9190840ecaef683762131dfa
+Author: freddy77 <freddy77>
+Date:   Thu May 28 16:23:31 2009 +0000
+
+    improve support for mssql2005 types
+
+diff --git a/ChangeLog b/ChangeLog
+index 59e991c..c7de97f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,13 @@
++Thu May 28 18:23:16 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h misc/types.txt src/apps/tsql.c src/ctlib/ct.c:
++	* src/dblib/bcp.c src/dblib/buffering.h src/dblib/dblib.c:
++	* src/dblib/rpc.c src/odbc/odbc.c src/odbc/odbc_util.c:
++	* src/odbc/prepare_query.c src/odbc/sql2tds.c src/tds/mem.c:
++	* src/tds/query.c src/tds/read.c src/tds/tds_checks.c:
++	* src/tds/token.c src/tds/unittests/dataread.c:
++	* src/tds/unittests/utf8_1.c src/tds/unittests/utf8_2.c:
++	- improve support for mssql2005 types (still under development)
++
+ Thu May 28 18:17:43 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: add tests for mssql2005 types
+ 
+@@ -1588,4 +1598,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2800 2009/05/28 16:17:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2801 2009/05/28 16:23:31 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 9b31c4f..04dc446 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.313 2009/04/18 19:35:38 jklowden Exp $ */
++/* $Id: tds.h,v 1.314 2009/05/28 16:23:31 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -754,6 +754,7 @@ typedef enum tds_encryption_level {
+ 	(x)==XSYBNCHAR)
+ 
+ #define is_blob_type(x) (x==SYBTEXT || x==SYBIMAGE || x==SYBNTEXT)
++#define is_blob_col(x) ((x)->column_varint_size > 2)
+ /* large type means it has a two byte size field */
+ /* define is_large_type(x) (x>128) */
+ #define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL)
+diff --git a/misc/types.txt b/misc/types.txt
+index 79db411..b7c8488 100644
+--- a/misc/types.txt
++++ b/misc/types.txt
+@@ -27,7 +27,7 @@ SYBMONEY	ALL	0	1	0	0	0	0	0	0	8	SYBMONEYN
+ SYBMONEY4	ALL	0	1	0	0	0	0	0	0	4	SYBMONEYN
+ SYBMONEYN	ALL	1	0	1	0	0	0	0	0	-1	0
+ SYBMSUDT	MS	??	0	1	1	??	0	??	??	-1	0
+-SYBMSXML	MS	??	0	1	1	??	0	??	??	-1	0
++SYBMSXML	MS	8	0	1	1	1	0	0	0	-1	0
+ SYBNTEXT	MS	4	0	1	1	1	0	1	0	-1	0
+ SYBNUMERIC	ALL	1	0	1	0	0	1	0	0	-1	0
+ SYBNVARCHAR	MS	??	0	1	1	0	0	1	0	-1	0	# Same as XSYBNVARCHAR ??
+@@ -63,5 +63,5 @@ XSYBVARCHAR	MS	2	0	1	1	0	0	0	1	-1	0
+ # tds_get_conversion_type from nullable to not nullable
+ # tds_get_cardinal_type ??
+ 
+-# $Id: types.txt,v 1.1 2008/09/17 07:28:36 freddy77 Exp $
++# $Id: types.txt,v 1.2 2009/05/28 16:23:31 freddy77 Exp $
+ 
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 0e86a68..7777542 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.127 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.128 2009/05/28 16:23:31 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -235,7 +235,7 @@ do_query(TDSSOCKET * tds, char *buf, int opt_flags)
+ 					ctype = tds_get_conversion_type(col->column_type, col->column_size);
+ 
+ 					src = col->column_data;
+-					if (is_blob_type(col->column_type))
++					if (is_blob_col(col))
+ 						src = (unsigned char *) ((TDSBLOB *) src)->textvalue;
+ 					srclen = col->column_cur_size;
+ 
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 86629cd..def81f3 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.188 2009/05/11 07:25:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.189 2009/05/28 16:23:31 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -1770,7 +1770,7 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo,
+ 				srctype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
+ 
+ 				src = curcol->column_data;
+-				if (is_blob_type(curcol->column_type))
++				if (is_blob_col(curcol))
+ 					src = (unsigned char *) ((TDSBLOB *) src)->textvalue;
+ 
+ 				srclen = curcol->column_cur_size;
+@@ -2691,7 +2691,7 @@ ct_get_data(CS_COMMAND * cmd, CS_INT item, CS_VOID * buffer, CS_INT buflen, CS_I
+ 		curcol = resinfo->columns[item - 1];
+ 
+ 		src = curcol->column_data;
+-		if (is_blob_type(curcol->column_type)) {
++		if (is_blob_col(curcol)) {
+ 			blob = (TDSBLOB *) src;
+ 			src = (unsigned char *) blob->textvalue;
+ 		}
+@@ -2731,7 +2731,7 @@ ct_get_data(CS_COMMAND * cmd, CS_INT item, CS_VOID * buffer, CS_INT buflen, CS_I
+ 		/* get at the source data */
+ 		curcol = resinfo->columns[item - 1];
+ 		src = curcol->column_data;
+-		if (is_blob_type(curcol->column_type))
++		if (is_blob_col(curcol))
+ 			src = (unsigned char *) ((TDSBLOB *) src)->textvalue;
+ 
+ 	}
+@@ -3887,7 +3887,7 @@ paramrowalloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *va
+ 			size = curcol->column_size;
+ 		}
+ 		/* TODO blobs */
+-		if (!is_blob_type(curcol->column_type))
++		if (!is_blob_col(curcol))
+ 			memcpy(curcol->column_data, value, size);
+ 		else {
+ 			TDSBLOB *blob = (TDSBLOB *) curcol->column_data;
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index c629325..34fa10e 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.185 2009/05/20 16:36:58 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.186 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -948,7 +948,7 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 
+ 				src = curcol->column_data;
+ 
+-				if (is_blob_type(curcol->column_type)) {
++				if (is_blob_col(curcol)) {
+ 					src = (BYTE *) ((TDSBLOB *) src)->textvalue;
+ 				}
+ 
+diff --git a/src/dblib/buffering.h b/src/dblib/buffering.h
+index d07c32b..f51d92c 100644
+--- a/src/dblib/buffering.h
++++ b/src/dblib/buffering.h
+@@ -332,9 +332,8 @@ buffer_transfer_bound_data(DBPROC_ROWBUF *buf, TDS_INT res_type, TDS_INT compute
+ 		else
+ 			src = curcol->column_data;
+ 		srclen = curcol->column_cur_size;
+-		if (is_blob_type(curcol->column_type)) {
++		if (is_blob_col(curcol))
+ 			src = (BYTE *) ((TDSBLOB *) src)->textvalue;
+-		}
+ 		desttype = _db_get_server_type(curcol->column_bindtype);
+ 		srctype = tds_get_conversion_type(curcol->column_type, curcol->column_size);
+ 
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index c268aa6..c9bd4ee 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.349 2009/04/23 13:12:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.350 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -3094,7 +3094,7 @@ dbdata(DBPROCESS * dbproc, int column)
+ 	if (colinfo->column_cur_size < 0)
+ 		return NULL;
+ 
+-	if (is_blob_type(colinfo->column_type)) {
++	if (is_blob_col(colinfo)) {
+ 		BYTE *res = (BYTE *) ((TDSBLOB *) colinfo->column_data)->textvalue;
+ 		if (!res)
+ 			return (BYTE *) empty;
+@@ -4181,7 +4181,7 @@ dbadata(DBPROCESS * dbproc, int computeid, int column)
+ 	if (!colinfo)
+ 		return NULL;
+ 
+-	if (is_blob_type(colinfo->column_type)) {
++	if (is_blob_col(colinfo)) {
+ 		return (BYTE *) ((TDSBLOB *) colinfo->column_data)->textvalue;
+ 	}
+ 
+@@ -6241,7 +6241,7 @@ dbtxtimestamp(DBPROCESS * dbproc, int column)
+ 	tdsdump_log(TDS_DBG_FUNC, "dbtxtimestamp(%p, %d)\n", dbproc, column);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+-	if (!colinfo || !is_blob_type(colinfo->column_type))
++	if (!colinfo || !is_blob_col(colinfo))
+ 		return NULL;
+ 
+ 	blob = (TDSBLOB *) colinfo->column_data;
+@@ -6267,7 +6267,7 @@ dbtxptr(DBPROCESS * dbproc, int column)
+ 	tdsdump_log(TDS_DBG_FUNC, "dbtxptr(%p, %d)\n", dbproc, column);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+-	if (!colinfo || !is_blob_type(colinfo->column_type))
++	if (!colinfo || !is_blob_col(colinfo))
+ 		return NULL;
+ 
+ 	blob = (TDSBLOB *) colinfo->column_data;
+diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c
+index 8d8947d..a335112 100644
+--- a/src/dblib/rpc.c
++++ b/src/dblib/rpc.c
+@@ -54,7 +54,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: rpc.c,v 1.68 2009/03/24 01:22:14 jklowden Exp $");
++TDS_RCSID(var, "$Id: rpc.c,v 1.69 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static void rpc_clear(DBREMOTE_PROC * rpc);
+ static void param_clear(DBREMOTE_PROC_PARAM * pparam);
+@@ -334,7 +334,7 @@ param_row_alloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *
+ 		return NULL;
+ 	if (size > 0 && value) {
+ 		tdsdump_log(TDS_DBG_FUNC, "copying %d bytes of data to parameter #%d\n", size, param_num);
+-		if (!is_blob_type(curcol->column_type)) {
++		if (!is_blob_col(curcol)) {
+ 			memcpy(curcol->column_data, value, size);
+ 		} else {
+ 			TDSBLOB *blob = (TDSBLOB *) curcol->column_data;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 2ab668a..78d7401 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.510 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.511 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3655,7 +3655,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				TDS_CHAR *data_ptr = (TDS_CHAR *) drec_ard->sql_desc_data_ptr;
+ 
+ 				src = (TDS_CHAR *) colinfo->column_data;
+-				if (is_blob_type(colinfo->column_type))
++				if (is_blob_col(colinfo))
+ 					src = ((TDSBLOB *) src)->textvalue;
+ 				srclen = colinfo->column_cur_size;
+ 				c_type = drec_ard->sql_desc_concise_type;
+@@ -4708,7 +4708,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 
+ 			/* 2003-8-29 check for an old bug -- freddy77 */
+ 			assert(colinfo->column_text_sqlgetdatapos >= 0);
+-			if (is_blob_type(colinfo->column_type))
++			if (is_blob_col(colinfo))
+ 				src = ((TDSBLOB *) src)->textvalue;
+ 			src += colinfo->column_text_sqlgetdatapos;
+ 			srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 450f391..641b5e8 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.106 2008/10/22 15:22:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.107 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -209,7 +209,7 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 		}
+ 
+ 		src = (TDS_CHAR *) colinfo->column_data;
+-		if (is_blob_type(colinfo->column_type))
++		if (is_blob_col(colinfo))
+ 			src = ((TDSBLOB *) src)->textvalue;
+ 		srclen = colinfo->column_cur_size;
+ 		c_type = drec_apd->sql_desc_concise_type;
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index 418513c..a3be5f4 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.77 2009/05/21 16:41:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.78 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -311,7 +311,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 
+ 	curcol = stmt->params->columns[stmt->param_num - (stmt->prepared_query_is_func ? 2 : 1)];
+ 	blob = NULL;
+-	if (is_blob_type(curcol->column_type))
++	if (is_blob_col(curcol))
+ 		blob = (TDSBLOB *) curcol->column_data;
+ 	assert(curcol->column_cur_size <= curcol->column_size);
+ 	need_bytes = curcol->column_size - curcol->column_cur_size;
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 27e657c..7d57bc4 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.82 2009/05/22 17:33:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.83 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -206,7 +206,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 		TDSSOCKET *tds = dbc->tds_socket;
+ 		TDSICONV *conv = tds->char_convs[is_unicode_type(dest_type) ? client2ucs2 : client2server_chardata];
+ 
+-		tds_set_column_type(tds, curcol, dest_type);
++		tds_set_param_type(tds, curcol, dest_type);
+ 
+                 curcol->char_conv = tds_iconv_get(tds, ODBC_WIDE_NAME, conv->server_charset.name);
+ 		memcpy(curcol->column_collation, tds->collation, sizeof(tds->collation));
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 33d6e99..3eb1231 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.188 2009/02/07 00:26:22 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.189 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -291,7 +291,7 @@ _tds_param_free(TDSCOLUMN *col)
+ 	if (!col->column_data)
+ 		return;
+ 
+-	if (is_blob_type(col->column_type)) {
++	if (is_blob_col(col)) {
+ 		TDSBLOB *blob = (TDSBLOB *) col->column_data;
+ 		free(blob->textvalue);
+ 	}
+@@ -313,7 +313,7 @@ tds_alloc_param_data(TDSCOLUMN * curparam)
+ 
+ 	if (is_numeric_type(curparam->column_type)) {
+ 		data_size = sizeof(TDS_NUMERIC);
+-	} else if (is_blob_type(curparam->column_type)) {
++	} else if (is_blob_col(curparam)) {
+ 		data_size = sizeof(TDSBLOB);
+ 	} else {
+ 		data_size = curparam->column_size;
+@@ -330,7 +330,7 @@ tds_alloc_param_data(TDSCOLUMN * curparam)
+ 	if (!data)
+ 		return NULL;
+ 	/* if is a blob reset buffer */
+-	if (is_blob_type(curparam->column_type))
++	if (is_blob_col(curparam))
+ 		memset(data, 0, sizeof(TDSBLOB));
+ 
+ 	return data;
+@@ -438,7 +438,7 @@ _tds_row_free(TDSRESULTINFO *res_info, unsigned char *row)
+ 	for (i = 0; i < res_info->num_cols; ++i) {
+ 		col = res_info->columns[i];
+ 		
+-		if (is_blob_type(col->column_type)) {
++		if (is_blob_col(col)) {
+ 			TDSBLOB *blob = (TDSBLOB *) &row[col->column_data - res_info->current_row];
+ 			if (blob->textvalue)
+ 				TDS_ZERO_FREE(blob->textvalue);
+@@ -469,7 +469,7 @@ tds_alloc_row(TDSRESULTINFO * res_info)
+ 
+ 		if (is_numeric_type(col->column_type)) {
+ 			row_size += sizeof(TDS_NUMERIC);
+-		} else if (is_blob_type(col->column_type)) {
++		} else if (is_blob_col(col)) {
+ 			row_size += sizeof(TDSBLOB);
+ 		} else {
+ 			row_size += col->column_size;
+@@ -494,7 +494,7 @@ tds_alloc_row(TDSRESULTINFO * res_info)
+ 
+ 		if (is_numeric_type(col->column_type)) {
+ 			row_size += sizeof(TDS_NUMERIC);
+-		} else if (is_blob_type(col->column_type)) {
++		} else if (is_blob_col(col)) {
+ 			row_size += sizeof(TDSBLOB);
+ 		} else {
+ 			row_size += col->column_size;
+diff --git a/src/tds/query.c b/src/tds/query.c
+index c45be3b..3e07f95 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.236 2009/05/26 16:20:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.237 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1473,7 +1473,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	size = tds_fix_column_size(tds, curcol);
+ 
+ 	src = curcol->column_data;
+-	if (is_blob_type(curcol->column_type)) {
++	if (is_blob_col(curcol)) {
+ 		blob = (TDSBLOB *) src;
+ 		src = (unsigned char *) blob->textvalue;
+ 	}
+@@ -2896,7 +2896,7 @@ tds_put_param_as_string(TDSSOCKET * tds, TDSPARAMINFO * params, int n)
+ 		return TDS_SUCCEED;
+ 	}
+ 	
+-	if (is_blob_type(curcol->column_type))
++	if (is_blob_col(curcol))
+ 		src = ((TDSBLOB *)src)->textvalue;
+ 
+ 	save_src = src;
+diff --git a/src/tds/read.c b/src/tds/read.c
+index 1f7886f..d655cf4 100644
+--- a/src/tds/read.c
++++ b/src/tds/read.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: read.c,v 1.109 2009/05/11 09:05:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: read.c,v 1.110 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ 			    size_t * wire_size, char **outbuf, size_t * outbytesleft);
+@@ -232,7 +232,7 @@ tds_get_char_data(TDSSOCKET * tds, char *row_buffer, size_t wire_size, TDSCOLUMN
+ 	TDSBLOB *blob = NULL;
+ 	char *dest = row_buffer;
+ 
+-	if (is_blob_type(curcol->column_type)) {
++	if (is_blob_col(curcol)) {
+ 		blob = (TDSBLOB *) row_buffer;
+ 		dest = blob->textvalue;
+ 	}
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index 2ba07fa..81cba27 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.21 2008/10/28 12:50:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.22 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -177,7 +177,8 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 
+ 	assert(column);
+ 
+-	assert(column->column_varint_size <= 5 && column->column_varint_size != 3);
++	/* 8 is for varchar(max) or similar */
++	assert(column->column_varint_size == 8 || (column->column_varint_size <= 5 && column->column_varint_size != 3));
+ 
+ 	assert(column->column_scale <= column->column_prec);
+ 	assert(column->column_prec <= 77);
+@@ -193,9 +194,19 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	assert(tds_get_cardinal_type(column->on_server.column_type) == column->column_type
+ 		|| (tds_get_null_type(column->column_type) == column->on_server.column_type 
+ 		&& column->column_varint_size == 1 && is_fixed_type(column->column_type)));
++
++	varint_ok = 0;
++	if (is_blob_type(column->column_type)) {
++		assert(column->column_varint_size >= 4);
++	} else if (column->column_varint_size == 8) {
++		assert(column->on_server.column_type == XSYBVARCHAR || column->on_server.column_type == XSYBVARBINARY || column->on_server.column_type == XSYBNVARCHAR);
++		varint_ok = 1;
++	} else {
++		assert(column->column_varint_size < 3);
++	}
+ 	tds.minor_version = 0;
+ 	tds.major_version = 5;
+-	varint_ok = tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
++	varint_ok = varint_ok || tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
+ 	tds.major_version = 7;
+ 	varint_ok = varint_ok || tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
+ 	assert(varint_ok);
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 0641bc9..39b5465 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.359 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.360 2009/05/28 16:23:32 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1441,8 +1441,10 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		curcol->column_size = tds_get_smallint(tds);
+ #ifdef ENABLE_DEVELOPING
+ 		/* under TDS9 this means ?var???(MAX) */
+-		if (curcol->column_size < 0 && IS_TDS90(tds))
++		if (curcol->column_size < 0 && IS_TDS90(tds)) {
+ 			curcol->column_size = 0x1ffffffflu;
++			curcol->column_varint_size = 8;
++		}
+ #endif
+ 		break;
+ 	case 1:
+@@ -1951,6 +1953,8 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ {
+ 	TDS_INT8 len = tds_get_int8(tds);
+ 	TDS_INT chunk_len;
++	TDS_CHAR **p;
++	size_t offset;
+ 
+ 	/* NULL */
+ 	if (len == -1) {
+@@ -1958,11 +1962,28 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		return TDS_SUCCEED;
+ 	}
+ 
++	curcol->column_cur_size = 0;
++	offset = 0;
++	p = &(((TDSBLOB*) curcol->column_data)->textvalue);
+ 	for (;;) {
++		TDS_CHAR *tmp;
++
+ 		chunk_len = tds_get_int(tds);
+-		if (chunk_len < 0)
++		if (chunk_len <= 0) {
++			curcol->column_cur_size = offset;
+ 			return TDS_SUCCEED;
++		}
++		if (*p)
++			tmp = (TDS_CHAR*) malloc(chunk_len);
++		else
++			tmp = (TDS_CHAR*) realloc(*p, offset + chunk_len);
++		if (!tmp)
++			return TDS_FAIL;
++		*p = tmp;
++		tds_get_n(tds, *p + offset, chunk_len);
++		offset += chunk_len;
+ 	}
++	return TDS_SUCCEED;
+ }
+ #endif
+ 
+@@ -2024,11 +2045,11 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	case 5:
+ 		colsize = tds_get_int(tds);
+ 		break;
+-	case 2:
+ #ifdef ENABLE_DEVELOPING
+-		if (curcol->column_size == 0x1ffffffflu)
+-			return tds9_get_varmax(tds, curcol);
++	case 8:
++		return tds9_get_varmax(tds, curcol);
+ #endif
++	case 2:
+ 		colsize = tds_get_smallint(tds);
+ 		break;
+ 	case 1:
+@@ -2090,7 +2111,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			tds_swap_numeric(num);
+ 		}
+ 		curcol->column_cur_size = colsize;
+-	} else if (is_blob_type(curcol->column_type)) {
++	} else if (is_blob_col(curcol)) {
+ 		TDS_CHAR *p;
+ 		int new_blob_size;
+ 		assert(blob == (TDSBLOB *) dest); 	/* cf. column_varint_size case 4, above */
+diff --git a/src/tds/unittests/dataread.c b/src/tds/unittests/dataread.c
+index 887d554..d0a1843 100644
+--- a/src/tds/unittests/dataread.c
++++ b/src/tds/unittests/dataread.c
+@@ -22,7 +22,7 @@
+ #include <assert.h>
+ #include <tdsconvert.h>
+ 
+-static char software_version[] = "$Id: dataread.c,v 1.19 2007/10/16 15:12:23 freddy77 Exp $";
++static char software_version[] = "$Id: dataread.c,v 1.20 2009/05/28 16:23:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -119,7 +119,7 @@ test0(const char *type, ...)
+ 
+ 		assert(i_row < num_data);
+ 
+-		if (is_blob_type(curcol->column_type)) {
++		if (is_blob_col(curcol)) {
+ 			TDSBLOB *blob = (TDSBLOB *) src;
+ 
+ 			src = blob->textvalue;
+diff --git a/src/tds/unittests/utf8_1.c b/src/tds/unittests/utf8_1.c
+index 9e7971e..d8c2340 100644
+--- a/src/tds/unittests/utf8_1.c
++++ b/src/tds/unittests/utf8_1.c
+@@ -21,7 +21,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: utf8_1.c,v 1.12 2006/01/24 15:03:28 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_1.c,v 1.13 2009/05/28 16:23:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static TDSSOCKET *tds;
+@@ -165,7 +165,7 @@ test(const char *type, const char *test_name)
+ 			TDSCOLUMN *curcol = tds->current_results->columns[0];
+ 			char *src = (char *) curcol->column_data;
+ 
+-			if (is_blob_type(curcol->column_type)) {
++			if (is_blob_col(curcol)) {
+ 				TDSBLOB *blob = (TDSBLOB *) src;
+ 
+ 				src = blob->textvalue;
+diff --git a/src/tds/unittests/utf8_2.c b/src/tds/unittests/utf8_2.c
+index 0f896a1..fa1fa22 100644
+--- a/src/tds/unittests/utf8_2.c
++++ b/src/tds/unittests/utf8_2.c
+@@ -22,7 +22,7 @@
+ #include <assert.h>
+ 
+ /* try conversion from utf8 to iso8859-1 */
+-static char software_version[] = "$Id: utf8_2.c,v 1.14 2007/01/18 07:58:08 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.15 2009/05/28 16:23:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static TDSSOCKET *tds;
+@@ -107,7 +107,7 @@ test(int n, int type)
+ 	curcol = tds->current_results->columns[0];
+ 	src = (char*) curcol->column_data;
+ 
+-	if (is_blob_type(curcol->column_type)) {
++	if (is_blob_col(curcol)) {
+ 		TDSBLOB *blob = (TDSBLOB *) src;
+ 
+ 		src = blob->textvalue;
+
+commit 16b3497735727fcb2618388a3d469ffd20a30fef
+Author: jklowden <jklowden>
+Date:   Thu Jun 4 03:45:32 2009 +0000
+
+    added ClientCharset connection attribute
+
+diff --git a/ChangeLog b/ChangeLog
+index c7de97f..13737b7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jun  3 23:41:17 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* doc/api_status.txt doc/userguide.sgml
++	- added ClientCharset connection attribute
++
+ Thu May 28 18:23:16 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h misc/types.txt src/apps/tsql.c src/ctlib/ct.c:
+ 	* src/dblib/bcp.c src/dblib/buffering.h src/dblib/dblib.c:
+@@ -1598,4 +1602,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2801 2009/05/28 16:23:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2802 2009/06/04 03:45:32 jklowden Exp $
+diff --git a/doc/api_status.txt b/doc/api_status.txt
+index 162104c..ae202bd 100644
+--- a/doc/api_status.txt
++++ b/doc/api_status.txt
+@@ -1,7 +1,7 @@
+ #!/usr/pkg/bin/perl
+ # API status document
+ #
+-# $Id: api_status.txt,v 1.61 2009/01/31 19:13:20 jklowden Exp $s
++# $Id: api_status.txt,v 1.62 2009/06/04 03:45:33 jklowden Exp $s
+ #
+ # This tab-delimited file is a database of the "readiness" of the various
+ # APIs.  Please feel free to modify it if you notice something is missing or 
+@@ -137,7 +137,7 @@ odbc	(all)	SQLColumns	OK
+ odbc	(all)	SQLConnect	OK
+ odbc	(all)	SQLCopyDesc	OK
+ odbc	(all)	SQLDescribeCol	OK
+-odbc	(all)	SQLDescribeParam	
++odbc	(all)	SQLDescribeParam	unimplemented
+ odbc	(all)	SQLDisconnect	OK
+ odbc	(all)	SQLDriverConnect	OK
+ odbc	(all)	SQLEndTran	OK
+@@ -186,7 +186,7 @@ odbc	(all)	SQLSetDescRec	OK
+ odbc	(all)	SQLSetEnvAttr	partial
+ odbc	(all)	SQLSetPos	OK
+ odbc	(all)	SQLSetParam	OK
+-odbc	(all)	SQLSetScrollOption	
++odbc	(all)	SQLSetScrollOption	unimplemented
+ odbc	(all)	SQLSetStmtAttr	OK
+ odbc	(all)	SQLSetStmtOption	OK
+ odbc	(all)	SQLSpecialColumns	OK
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 1c77454..6818b29 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2009/04/09 01:40:37 $</date>
+-		<releaseinfo>$Revision: 1.122 $</releaseinfo>
++		<date>$Date: 2009/06/04 03:45:33 $</date>
++		<releaseinfo>$Revision: 1.123 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -57,9 +57,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.122 $</>
+-<member>$Date: 2009/04/09 01:40:37 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.122 2009/04/09 01:40:37 jklowden Exp $.</>
++<member>$Revision: 1.123 $</>
++<member>$Date: 2009/06/04 03:45:33 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.123 2009/06/04 03:45:33 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -569,7 +569,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2009/04/09 01:40:37 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2009/06/04 03:45:33 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1535,6 +1535,12 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<entry>TDS protocol version to use (e.g., 5.0, 7.0).</entry>
+ 	</row>
+ 	<row>
++	<entry><literal>ClientCharset</></entry>
++	<entry>A name recognized by the iconv library linked to FreeTDS</entry>
++	<entry>Taken from the LANG environment variable, maybe?</entry>
++	<entry>Character set (encoding) used by the client.  </entry>
++	</row>
++	<row>
+ 	<entry><literal>APP</></entry>
+ 	<entry>Free form text, up to 30 characters.  </entry>
+ 	<entry>none</entry>
+
+commit d740766a9531a696b89e826efe2e7fbeb86e47e1
+Author: freddy77 <freddy77>
+Date:   Thu Jun 4 05:39:56 2009 +0000
+
+    updated api status for SQLSetScrollOption
+
+diff --git a/ChangeLog b/ChangeLog
+index 13737b7..9b60039 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jun  4 07:39:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/api_status.txt: updated
++
+ Wed Jun  3 23:41:17 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* doc/api_status.txt doc/userguide.sgml
+ 	- added ClientCharset connection attribute
+@@ -1602,4 +1605,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2802 2009/06/04 03:45:32 jklowden Exp $
++$Id: ChangeLog,v 1.2803 2009/06/04 05:39:56 freddy77 Exp $
+diff --git a/doc/api_status.txt b/doc/api_status.txt
+index ae202bd..395c278 100644
+--- a/doc/api_status.txt
++++ b/doc/api_status.txt
+@@ -1,7 +1,7 @@
+ #!/usr/pkg/bin/perl
+ # API status document
+ #
+-# $Id: api_status.txt,v 1.62 2009/06/04 03:45:33 jklowden Exp $s
++# $Id: api_status.txt,v 1.63 2009/06/04 05:39:56 freddy77 Exp $s
+ #
+ # This tab-delimited file is a database of the "readiness" of the various
+ # APIs.  Please feel free to modify it if you notice something is missing or 
+@@ -186,7 +186,7 @@ odbc	(all)	SQLSetDescRec	OK
+ odbc	(all)	SQLSetEnvAttr	partial
+ odbc	(all)	SQLSetPos	OK
+ odbc	(all)	SQLSetParam	OK
+-odbc	(all)	SQLSetScrollOption	unimplemented
++odbc	(all)	SQLSetScrollOption	OK
+ odbc	(all)	SQLSetStmtAttr	OK
+ odbc	(all)	SQLSetStmtOption	OK
+ odbc	(all)	SQLSpecialColumns	OK
+
+commit d2434e21eea6198bc9320bfe13f817559a36ac62
+Author: jklowden <jklowden>
+Date:   Sat Jun 6 01:42:28 2009 +0000
+
+    Applied patch from Andrew Victor ML 24 November 2008 "CTLib implementation handles NVARCHAR strings as VARCHAR"
+
+diff --git a/ChangeLog b/ChangeLog
+index 9b60039..eac2964 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Jun  5 21:36:29 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/ctlib/cs.c src/ctlib/ct.c
++	* src/tds/convert.c src/tds/data.c
++	- Applied patch from Andrew Victor ML 24 November 2008
++	- "CTLib implementation handles NVARCHAR strings as VARCHAR"
++
+ Thu Jun  4 07:39:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/api_status.txt: updated
+ 
+@@ -1605,4 +1611,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2803 2009/06/04 05:39:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2804 2009/06/06 01:42:28 jklowden Exp $
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index 3646016..ecbb332 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.70 2009/05/03 19:32:57 jklowden Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.71 2009/06/06 01:42:29 jklowden Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -601,6 +601,7 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ 
+ 		case SYBCHAR:
+ 		case SYBVARCHAR:
++		case SYBNVARCHAR:
+ 		case SYBTEXT:
+ 			tdsdump_log(TDS_DBG_FUNC, "cs_convert() desttype = character\n");
+ 
+@@ -812,6 +813,7 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ 		break;
+ 	case SYBCHAR:
+ 	case SYBVARCHAR:
++	case SYBNVARCHAR:
+ 	case SYBTEXT:
+ 		if (len > destlen) {
+ 			fprintf(stderr, "error_handler: Data-conversion resulted in overflow.\n");
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index def81f3..f4e8b6b 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.189 2009/05/28 16:23:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.190 2009/06/06 01:42:29 jklowden Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2016,6 +2016,9 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 			return CS_UNICHAR_TYPE;
+ 		return CS_CHAR_TYPE;
+ 		break;
++	case SYBNVARCHAR:
++		return CS_UNICHAR_TYPE;
++		break;
+ 	}
+ 
+ 	return CS_FAIL;
+@@ -4034,7 +4037,10 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ 				return NULL;
+ 			pcol->on_server.column_size = pcol->column_size = p->maxlen;
+ 			pcol->column_cur_size = temp_datalen;
+-			if (temp_datalen > 0 && temp_datalen > p->maxlen)
++			if (p->maxlen == 0 && pcol->column_type == SYBNVARCHAR) {
++				pcol->on_server.column_size = pcol->column_size = temp_datalen*2;
++			}
++			else if (temp_datalen > 0 && temp_datalen > p->maxlen)
+ 				pcol->on_server.column_size = pcol->column_size = temp_datalen;
+ 		} else {
+ 			pcol->column_cur_size = pcol->column_size;
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 2c0dad4..0cdb5fa 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.189 2009/05/21 16:39:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.190 2009/06/06 01:42:29 jklowden Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -340,6 +340,7 @@ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttyp
+ 		return srclen;
+ 
+ 	case CASE_ALL_CHAR:
++	case SYBNVARCHAR:		/* CHAR return as Unicode */
+ 		cr->c = (TDS_CHAR *) malloc(srclen + 1);
+ 		test_alloc(cr->c);
+ 		memcpy(cr->c, src, srclen);
+diff --git a/src/tds/data.c b/src/tds/data.c
+index 3c81ff5..042337b 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,7 +35,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.19 2008/09/17 12:16:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: data.c,v 1.20 2009/06/06 01:42:29 jklowden Exp $");
+ 
+ #if !ENABLE_EXTRA_CHECKS
+ static int tds_get_cardinal_type(int datatype);
+@@ -85,6 +85,9 @@ tds_set_param_type(TDSSOCKET * tds, TDSCOLUMN * curcol, TDS_SERVER_TYPE type)
+ 		case SYBBINARY:
+ 			type = XSYBBINARY;
+ 			break;
++		case SYBNVARCHAR:
++			type = XSYBNVARCHAR;
++			break;
+ 			/* avoid warning on other types */
+ 		default:
+ 			break;
+@@ -152,6 +155,7 @@ tds_get_cardinal_type(int datatype)
+ 	case SYBNTEXT:
+ 		return SYBTEXT;
+ 	case XSYBNVARCHAR:
++		return SYBNVARCHAR;
+ 	case XSYBVARCHAR:
+ 		return SYBVARCHAR;
+ 	case XSYBNCHAR:
+
+commit 87cbbd45bf959fd140a291ba5aecf61f01a9c2b8
+Author: freddy77 <freddy77>
+Date:   Sat Jun 6 16:24:11 2009 +0000
+
+    update ClientCharset setting
+
+diff --git a/ChangeLog b/ChangeLog
+index eac2964..6ab20e4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun  6 18:23:50 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: update ClientCharset setting
++
+ Fri Jun  5 21:36:29 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/ctlib/cs.c src/ctlib/ct.c
+ 	* src/tds/convert.c src/tds/data.c
+@@ -1611,4 +1614,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2804 2009/06/06 01:42:28 jklowden Exp $
++$Id: ChangeLog,v 1.2805 2009/06/06 16:24:11 freddy77 Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 6818b29..1c42309 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2009/06/04 03:45:33 $</date>
+-		<releaseinfo>$Revision: 1.123 $</releaseinfo>
++		<date>$Date: 2009/06/06 16:24:11 $</date>
++		<releaseinfo>$Revision: 1.124 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -57,9 +57,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.123 $</>
+-<member>$Date: 2009/06/04 03:45:33 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.123 2009/06/04 03:45:33 jklowden Exp $.</>
++<member>$Revision: 1.124 $</>
++<member>$Date: 2009/06/06 16:24:11 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.124 2009/06/06 16:24:11 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -569,7 +569,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2009/06/04 03:45:33 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2009/06/06 16:24:11 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1536,9 +1536,10 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	</row>
+ 	<row>
+ 	<entry><literal>ClientCharset</></entry>
+-	<entry>A name recognized by the iconv library linked to FreeTDS</entry>
+-	<entry>Taken from the LANG environment variable, maybe?</entry>
+-	<entry>Character set (encoding) used by the client.  </entry>
++	<entry>A name recognized by the iconv library linked to FreeTDS.
++	This correspond to <literal>client charset</> in <filename>freetds.conf</>.</entry>
++	<entry>ISO8859-1</entry>
++	<entry>Character set (encoding) used by the client.</entry>
+ 	</row>
+ 	<row>
+ 	<entry><literal>APP</></entry>
+
+commit 1c0cf8299799d4a0f00730a535518dde239f2a54
+Author: freddy77 <freddy77>
+Date:   Mon Jun 8 18:38:52 2009 +0000
+
+    update BUGS
+
+diff --git a/BUGS b/BUGS
+index f454d77..28a4ef5 100644
+--- a/BUGS
++++ b/BUGS
+@@ -7,15 +7,12 @@ Needs Fixing
+ ------------
+ 1. Fix formatting of dbprhead/dbprrow...its a little off
+    (Anybody care?)
+-2. text/image does not work for row buffering under dblib.
+-3. dbwritetext() and friends do not work under TDS 7.0
+-4. There is a bug with the order of returns from ct_results() such that rows
++2. dbwritetext() and friends do not work under TDS 7.0
++3. There is a bug with the order of returns from ct_results() such that rows
+    affected doesn't show up in sqsh.
+-5. ct-lib placeholders do not work with TDS 7.0+.  To fix 
++4. ct-lib placeholders do not work with TDS 7.0+.  To fix 
+    this requires either an SQL parser or API modification, 
+    because the library has to determine the SQL datatype 
+    of the placeholder variable.  
+-6. ML Mar 21 2009: "freebcp error HINT -b doesnt work", freebcp -n broken. 
+-
+-
++5. ML Mar 21 2009: "freebcp error HINT -b doesnt work", freebcp -n broken. 
+ 
+diff --git a/ChangeLog b/ChangeLog
+index 6ab20e4..51325bd 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jun  8 20:38:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* BUGS: updated
++
+ Sat Jun  6 18:23:50 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/userguide.sgml: update ClientCharset setting
+ 
+@@ -1614,4 +1617,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2805 2009/06/06 16:24:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2806 2009/06/08 18:38:52 freddy77 Exp $
+
+commit 52a39ca60d5d3fcf48a7e0b7cbc6e9c3c2fb8bae
+Author: freddy77 <freddy77>
+Date:   Mon Jun 8 19:39:39 2009 +0000
+
+    avoid improper fall through on error
+
+diff --git a/ChangeLog b/ChangeLog
+index 51325bd..4a3a8a9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jun  8 21:39:32 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: avoid improper fall through on error
++
+ Mon Jun  8 20:38:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* BUGS: updated
+ 
+@@ -1617,4 +1620,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2806 2009/06/08 18:38:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2807 2009/06/08 19:39:39 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index f4e8b6b..d6a513b 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.190 2009/06/06 01:42:29 jklowden Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.191 2009/06/08 19:39:39 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -1958,9 +1958,9 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 			return CS_REAL_TYPE;
+ 		} else if (size == 8) {
+ 			return CS_FLOAT_TYPE;
+-		} else {
+-			fprintf(stderr, "Error! unknown float size of %d\n", size);
+ 		}
++		fprintf(stderr, "Error! unknown float size of %d\n", size);
++		break;
+ 	case SYBMONEY:
+ 		return CS_MONEY_TYPE;
+ 		break;
+@@ -1972,9 +1972,9 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 			return CS_MONEY4_TYPE;
+ 		} else if (size == 8) {
+ 			return CS_MONEY_TYPE;
+-		} else {
+-			fprintf(stderr, "Error! unknown money size of %d\n", size);
+ 		}
++		fprintf(stderr, "Error! unknown money size of %d\n", size);
++		break;
+ 	case SYBDATETIME:
+ 		return CS_DATETIME_TYPE;
+ 		break;
+@@ -1986,9 +1986,8 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 			return CS_DATETIME4_TYPE;
+ 		} else if (size == 8) {
+ 			return CS_DATETIME_TYPE;
+-		} else {
+-			fprintf(stderr, "Error! unknown date size of %d\n", size);
+ 		}
++		fprintf(stderr, "Error! unknown date size of %d\n", size);
+ 		break;
+ 	case SYBNUMERIC:
+ 		return CS_NUMERIC_TYPE;
+
+commit 301e285d64a510248cc4c1f8f420183729a99842
+Author: freddy77 <freddy77>
+Date:   Mon Jun 8 19:55:11 2009 +0000
+
+    make _ct_get_client_type call shorter
+
+diff --git a/ChangeLog b/ChangeLog
+index 4a3a8a9..2649c36 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jun  8 21:54:55 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/ctlib.h src/ctlib/blk.c src/ctlib/ct.c:
++	- make _ct_get_client_type call shorter
++
+ Mon Jun  8 21:39:32 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c: avoid improper fall through on error
+ 
+@@ -1620,4 +1624,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2807 2009/06/08 19:39:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2808 2009/06/08 19:55:11 freddy77 Exp $
+diff --git a/include/ctlib.h b/include/ctlib.h
+index 55924f8..a047851 100644
+--- a/include/ctlib.h
++++ b/include/ctlib.h
+@@ -36,7 +36,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.26 2008/12/12 13:56:11 freddy77 Exp $";
++static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.27 2009/06/08 19:55:11 freddy77 Exp $";
+ static const void *const no_unused_ctlib_h_warn[] = { rcsid_ctlib_h, no_unused_ctlib_h_warn };
+ 
+ #include <tds.h>
+@@ -270,7 +270,7 @@ int _ct_handle_server_message(const TDSCONTEXT * ctxptr, TDSSOCKET * tdsptr, TDS
+ int _ct_handle_client_message(const TDSCONTEXT * ctxptr, TDSSOCKET * tdsptr, TDSMESSAGE * msgptr);
+ int _ct_get_server_type(int datatype);
+ int _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo, CS_INT offset);
+-int _ct_get_client_type(int datatype, int usertype, int size);
++int _ct_get_client_type(TDSCOLUMN *col);
+ void _ctclient_msg(CS_CONNECTION * con, const char *funcname, int layer, int origin, int severity, int number,
+ 		   const char *fmt, ...);
+ CS_INT _ct_diag_clearmsg(CS_CONTEXT * context, CS_INT type);
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index d0eb7d9..977780f 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,7 +38,7 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.50 2009/05/03 19:32:57 jklowden Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.51 2009/06/08 19:55:11 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+@@ -194,7 +194,7 @@ blk_describe(CS_BLKDESC * blkdesc, CS_INT item, CS_DATAFMT * datafmt)
+ 	datafmt->name[len] = 0;
+ 	datafmt->namelen = len;
+ 	/* need to turn the SYBxxx into a CS_xxx_TYPE */
+-	datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
++	datafmt->datatype = _ct_get_client_type(curcol);
+ 	tdsdump_log(TDS_DBG_INFO1, "blk_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype,
+ 			curcol->column_type);
+ 	/* FIXME is ok this value for numeric/decimal? */
+@@ -714,7 +714,7 @@ _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bindcol, int offset)
+ 			srcfmt.datatype = srctype;
+ 			srcfmt.maxlength = srclen;
+ 
+-			destfmt.datatype  = _ct_get_client_type(bindcol->column_type, bindcol->column_usertype, bindcol->column_size);
++			destfmt.datatype  = _ct_get_client_type(bindcol);
+ 			destfmt.maxlength = bindcol->column_size;
+ 			destfmt.precision = bindcol->column_prec;
+ 			destfmt.scale     = bindcol->column_scale;
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index d6a513b..993aa87 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.191 2009/06/08 19:39:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.192 2009/06/08 19:55:11 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -48,7 +48,6 @@ static char * ct_describe_cmd_state(CS_INT state);
+  * @return 0 on success
+  */
+ static int _ct_fetch_cursor(CS_COMMAND * cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT * rows_read);
+-int _ct_get_client_type(int datatype, int usertype, int size);
+ static int _ct_fetchable_results(CS_COMMAND * cmd);
+ static int _ct_process_return_status(TDSSOCKET * tds);
+ 
+@@ -1767,7 +1766,7 @@ _ct_bind_data(CS_CONTEXT *ctx, TDSRESULTINFO * resinfo, TDSRESULTINFO *bindinfo,
+ 				*pdatalen = 0;
+ 			} else {
+ 
+-				srctype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
++				srctype = _ct_get_client_type(curcol);
+ 
+ 				src = curcol->column_data;
+ 				if (is_blob_col(curcol))
+@@ -1908,11 +1907,11 @@ ct_con_drop(CS_CONNECTION * con)
+ }
+ 
+ int
+-_ct_get_client_type(int datatype, int usertype, int size)
++_ct_get_client_type(TDSCOLUMN *col)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "_ct_get_client_type(type %d, user %d, size %d)\n", datatype, usertype, size);
++	tdsdump_log(TDS_DBG_FUNC, "_ct_get_client_type(type %d, user %d, size %d)\n", col->column_type, col->column_usertype, col->column_size);
+ 
+-	switch (datatype) {
++	switch (col->column_type) {
+ 	case SYBBIT:
+ 	case SYBBITN:
+ 		return CS_BIT_TYPE;
+@@ -1934,7 +1933,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_TINYINT_TYPE;
+ 		break;
+ 	case SYBINTN:
+-		switch (size) {
++		switch (col->column_size) {
+ 		case 8:
+ 			return CS_BIGINT_TYPE;
+ 		case 4:
+@@ -1944,7 +1943,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		case 1:
+ 			return CS_TINYINT_TYPE;
+ 		default:
+-			fprintf(stderr, "Unknown size %d for SYBINTN\n", size);
++			fprintf(stderr, "Unknown size %d for SYBINTN\n", col->column_size);
+ 		}
+ 		break;
+ 	case SYBREAL:
+@@ -1954,12 +1953,12 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_FLOAT_TYPE;
+ 		break;
+ 	case SYBFLTN:
+-		if (size == 4) {
++		if (col->column_size == 4) {
+ 			return CS_REAL_TYPE;
+-		} else if (size == 8) {
++		} else if (col->column_size == 8) {
+ 			return CS_FLOAT_TYPE;
+ 		}
+-		fprintf(stderr, "Error! unknown float size of %d\n", size);
++		fprintf(stderr, "Error! unknown float size of %d\n", col->column_size);
+ 		break;
+ 	case SYBMONEY:
+ 		return CS_MONEY_TYPE;
+@@ -1968,12 +1967,12 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_MONEY4_TYPE;
+ 		break;
+ 	case SYBMONEYN:
+-		if (size == 4) {
++		if (col->column_size == 4) {
+ 			return CS_MONEY4_TYPE;
+-		} else if (size == 8) {
++		} else if (col->column_size == 8) {
+ 			return CS_MONEY_TYPE;
+ 		}
+-		fprintf(stderr, "Error! unknown money size of %d\n", size);
++		fprintf(stderr, "Error! unknown money size of %d\n", col->column_size);
+ 		break;
+ 	case SYBDATETIME:
+ 		return CS_DATETIME_TYPE;
+@@ -1982,12 +1981,12 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_DATETIME4_TYPE;
+ 		break;
+ 	case SYBDATETIMN:
+-		if (size == 4) {
++		if (col->column_size == 4) {
+ 			return CS_DATETIME4_TYPE;
+-		} else if (size == 8) {
++		} else if (col->column_size == 8) {
+ 			return CS_DATETIME_TYPE;
+ 		}
+-		fprintf(stderr, "Error! unknown date size of %d\n", size);
++		fprintf(stderr, "Error! unknown date size of %d\n", col->column_size);
+ 		break;
+ 	case SYBNUMERIC:
+ 		return CS_NUMERIC_TYPE;
+@@ -2011,7 +2010,7 @@ _ct_get_client_type(int datatype, int usertype, int size)
+ 		return CS_UNIQUE_TYPE;
+ 		break;
+ 	case SYBLONGBINARY:
+-		if (usertype == USER_UNICHAR_TYPE || usertype == USER_UNIVARCHAR_TYPE)
++		if (col->column_usertype == USER_UNICHAR_TYPE || col->column_usertype == USER_UNIVARCHAR_TYPE)
+ 			return CS_UNICHAR_TYPE;
+ 		return CS_CHAR_TYPE;
+ 		break;
+@@ -2309,7 +2308,7 @@ ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt)
+ 	datafmt->name[len] = 0;
+ 	datafmt->namelen = len;
+ 	/* need to turn the SYBxxx into a CS_xxx_TYPE */
+-	datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_usertype, curcol->column_size);
++	datafmt->datatype = _ct_get_client_type(curcol);
+ 	tdsdump_log(TDS_DBG_INFO1, "ct_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype,
+ 		    curcol->column_type);
+ 	/* FIXME is ok this value for numeric/decimal? */
+
+commit 09912093c50a049d9addb9d8576e755d5423018f
+Author: freddy77 <freddy77>
+Date:   Tue Jun 9 06:50:12 2009 +0000
+
+    revert Andrew Victor patch
+
+diff --git a/ChangeLog b/ChangeLog
+index 2649c36..ee076b7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Jun  9 08:49:43 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/cs.c src/ctlib/ct.c src/tds/convert.c src/tds/data.c:
++	- revert Andrew Victor patch
++
+ Mon Jun  8 21:54:55 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/ctlib.h src/ctlib/blk.c src/ctlib/ct.c:
+ 	- make _ct_get_client_type call shorter
+@@ -1624,4 +1628,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2808 2009/06/08 19:55:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2809 2009/06/09 06:50:12 freddy77 Exp $
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index ecbb332..0952353 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.71 2009/06/06 01:42:29 jklowden Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.72 2009/06/09 06:50:12 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -601,7 +601,6 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ 
+ 		case SYBCHAR:
+ 		case SYBVARCHAR:
+-		case SYBNVARCHAR:
+ 		case SYBTEXT:
+ 			tdsdump_log(TDS_DBG_FUNC, "cs_convert() desttype = character\n");
+ 
+@@ -813,7 +812,6 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ 		break;
+ 	case SYBCHAR:
+ 	case SYBVARCHAR:
+-	case SYBNVARCHAR:
+ 	case SYBTEXT:
+ 		if (len > destlen) {
+ 			fprintf(stderr, "error_handler: Data-conversion resulted in overflow.\n");
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 993aa87..44831c6 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.192 2009/06/08 19:55:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.193 2009/06/09 06:50:12 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2014,9 +2014,6 @@ _ct_get_client_type(TDSCOLUMN *col)
+ 			return CS_UNICHAR_TYPE;
+ 		return CS_CHAR_TYPE;
+ 		break;
+-	case SYBNVARCHAR:
+-		return CS_UNICHAR_TYPE;
+-		break;
+ 	}
+ 
+ 	return CS_FAIL;
+@@ -4035,10 +4032,7 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ 				return NULL;
+ 			pcol->on_server.column_size = pcol->column_size = p->maxlen;
+ 			pcol->column_cur_size = temp_datalen;
+-			if (p->maxlen == 0 && pcol->column_type == SYBNVARCHAR) {
+-				pcol->on_server.column_size = pcol->column_size = temp_datalen*2;
+-			}
+-			else if (temp_datalen > 0 && temp_datalen > p->maxlen)
++			if (temp_datalen > 0 && temp_datalen > p->maxlen)
+ 				pcol->on_server.column_size = pcol->column_size = temp_datalen;
+ 		} else {
+ 			pcol->column_cur_size = pcol->column_size;
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 0cdb5fa..6ebd544 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.190 2009/06/06 01:42:29 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.191 2009/06/09 06:50:12 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -340,7 +340,6 @@ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttyp
+ 		return srclen;
+ 
+ 	case CASE_ALL_CHAR:
+-	case SYBNVARCHAR:		/* CHAR return as Unicode */
+ 		cr->c = (TDS_CHAR *) malloc(srclen + 1);
+ 		test_alloc(cr->c);
+ 		memcpy(cr->c, src, srclen);
+diff --git a/src/tds/data.c b/src/tds/data.c
+index 042337b..1455667 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,7 +35,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.20 2009/06/06 01:42:29 jklowden Exp $");
++TDS_RCSID(var, "$Id: data.c,v 1.21 2009/06/09 06:50:12 freddy77 Exp $");
+ 
+ #if !ENABLE_EXTRA_CHECKS
+ static int tds_get_cardinal_type(int datatype);
+@@ -85,9 +85,6 @@ tds_set_param_type(TDSSOCKET * tds, TDSCOLUMN * curcol, TDS_SERVER_TYPE type)
+ 		case SYBBINARY:
+ 			type = XSYBBINARY;
+ 			break;
+-		case SYBNVARCHAR:
+-			type = XSYBNVARCHAR;
+-			break;
+ 			/* avoid warning on other types */
+ 		default:
+ 			break;
+@@ -155,7 +152,6 @@ tds_get_cardinal_type(int datatype)
+ 	case SYBNTEXT:
+ 		return SYBTEXT;
+ 	case XSYBNVARCHAR:
+-		return SYBNVARCHAR;
+ 	case XSYBVARCHAR:
+ 		return SYBVARCHAR;
+ 	case XSYBNCHAR:
+
+commit 72852c080f1392edd8f468da34cc012a30781d50
+Author: freddy77 <freddy77>
+Date:   Tue Jun 9 08:55:23 2009 +0000
+
+    use calloc instead of malloc and memset
+
+diff --git a/ChangeLog b/ChangeLog
+index ee076b7..36817f4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Tue Jun  9 10:54:29 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/datacopy.c src/ctlib/blk.c src/ctlib/cs.c:
++	* src/ctlib/ct.c src/odbc/connectparams.c src/odbc/descriptor.c:
++	* src/pool/main.c src/pool/member.c src/tds/challenge.c:
++	* src/tds/iconv.c src/tds/token.c:
++	- use calloc instead of malloc and memset
++
+ Tue Jun  9 08:49:43 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/cs.c src/ctlib/ct.c src/tds/convert.c src/tds/data.c:
+ 	- revert Andrew Victor patch
+@@ -1628,4 +1635,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2809 2009/06/09 06:50:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2810 2009/06/09 08:55:23 freddy77 Exp $
+diff --git a/src/apps/datacopy.c b/src/apps/datacopy.c
+index cdab16c..d8e8dd7 100644
+--- a/src/apps/datacopy.c
++++ b/src/apps/datacopy.c
+@@ -798,8 +798,7 @@ transfer_data(BCPPARAMDATA params, DBPROCESS * dbsrc, DBPROCESS * dbdest)
+ 
+ 	for (col = 0; col < src_numcols; col++) {
+ 
+-		srcdata[col] = (MIGCOLDATA *) malloc(sizeof(MIGCOLDATA));
+-		memset(srcdata[col], '\0', sizeof(MIGCOLDATA));
++		srcdata[col] = (MIGCOLDATA *) calloc(1, sizeof(MIGCOLDATA));
+ 		srcdata[col]->coltype = dbcoltype(dbsrc, col + 1);
+ 		srcdata[col]->collen = dbcollen(dbsrc, col + 1);
+ 
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index 977780f..b061b16 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -38,7 +38,7 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.51 2009/06/08 19:55:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.52 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+@@ -50,8 +50,7 @@ blk_alloc(CS_CONNECTION * connection, CS_INT version, CS_BLKDESC ** blk_pointer)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "blk_alloc(%p, %d, %p)\n", connection, version, blk_pointer);
+ 
+-	*blk_pointer = (CS_BLKDESC *) malloc(sizeof(CS_BLKDESC));
+-	memset(*blk_pointer, '\0', sizeof(CS_BLKDESC));
++	*blk_pointer = (CS_BLKDESC *) calloc(1, sizeof(CS_BLKDESC));
+ 
+ 	/* so we know who we belong to */
+ 	(*blk_pointer)->con = connection;
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index 0952353..d136fc3 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.72 2009/06/09 06:50:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.73 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -369,8 +369,7 @@ cs_ctx_alloc(CS_INT version, CS_CONTEXT ** ctx)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "cs_ctx_alloc(%d, %p)\n", version, ctx);
+ 
+-	*ctx = (CS_CONTEXT *) malloc(sizeof(CS_CONTEXT));
+-	memset(*ctx, '\0', sizeof(CS_CONTEXT));
++	*ctx = (CS_CONTEXT *) calloc(1, sizeof(CS_CONTEXT));
+ 	tds_ctx = tds_alloc_context(*ctx);
+ 	if (!tds_ctx) {
+ 		free(*ctx);
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 44831c6..b74c663 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.193 2009/06/09 06:50:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.194 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -659,10 +659,9 @@ ct_cmd_alloc(CS_CONNECTION * con, CS_COMMAND ** cmd)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_cmd_alloc(%p, %p)\n", con, cmd);
+ 
+-	*cmd = (CS_COMMAND *) malloc(sizeof(CS_COMMAND));
++	*cmd = (CS_COMMAND *) calloc(1, sizeof(CS_COMMAND));
+ 	if (!*cmd)
+ 		return CS_FAIL;
+-	memset(*cmd, '\0', sizeof(CS_COMMAND));
+ 
+ 	/* so we know who we belong to */
+ 	(*cmd)->con = con;
+@@ -670,8 +669,7 @@ ct_cmd_alloc(CS_CONNECTION * con, CS_COMMAND ** cmd)
+ 	/* initialise command state */
+ 	ct_set_command_state(*cmd, _CS_COMMAND_IDLE);
+ 
+-	command_list = malloc(sizeof(CS_COMMAND_LIST));
+-	memset(command_list, '\0', sizeof(CS_COMMAND_LIST));
++	command_list = calloc(1, sizeof(CS_COMMAND_LIST));
+ 	command_list->cmd = *cmd;
+ 	command_list->next = NULL;
+ 
+@@ -759,21 +757,18 @@ ct_command(CS_COMMAND * cmd, CS_INT type, const CS_VOID * buffer, CS_INT buflen,
+ 		if (cmd == NULL)
+ 			return CS_FAIL;
+ 
+-		cmd->rpc = (CSREMOTE_PROC *) malloc(sizeof(CSREMOTE_PROC));
++		cmd->rpc = (CSREMOTE_PROC *) calloc(1, sizeof(CSREMOTE_PROC));
+ 		if (cmd->rpc == NULL)
+ 			return CS_FAIL;
+ 
+-		memset(cmd->rpc, 0, sizeof(CSREMOTE_PROC));
+-
+ 		if (buflen == CS_NULLTERM) {
+ 			cmd->rpc->name = strdup(buffer);
+ 			if (cmd->rpc->name == NULL)
+ 				return CS_FAIL;
+ 		} else if (buflen > 0) {
+-			cmd->rpc->name = (char *) malloc(buflen + 1);
++			cmd->rpc->name = (char *) calloc(1, buflen + 1);
+ 			if (cmd->rpc->name == NULL)
+ 				return CS_FAIL;
+-			memset(cmd->rpc->name, 0, buflen + 1);
+ 			strncpy(cmd->rpc->name, (const char *) buffer, buflen);
+ 		} else {
+ 			return CS_FAIL;
+@@ -3152,10 +3147,9 @@ ct_param(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT datalen,
+ 			return CS_FAIL;
+ 		}
+ 
+-		param = (CSREMOTE_PROC_PARAM *) malloc(sizeof(CSREMOTE_PROC_PARAM));
++		param = (CSREMOTE_PROC_PARAM *) calloc(1, sizeof(CSREMOTE_PROC_PARAM));
+ 		if (!param)
+ 			return CS_FAIL;
+-		memset(param, 0, sizeof(CSREMOTE_PROC_PARAM));
+ 
+ 		if (CS_SUCCEED != _ct_fill_param(cmd->command_type, param, datafmt, data, &datalen, &indicator, 1)) {
+ 			tdsdump_log(TDS_DBG_INFO1, "ct_param() failed to add rpc param\n");
+@@ -3182,8 +3176,7 @@ ct_param(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT datalen,
+ 			return CS_FAIL;
+ 		}
+ 
+-		param = (CSREMOTE_PROC_PARAM *) malloc(sizeof(CSREMOTE_PROC_PARAM));
+-		memset(param, 0, sizeof(CSREMOTE_PROC_PARAM));
++		param = (CSREMOTE_PROC_PARAM *) calloc(1, sizeof(CSREMOTE_PROC_PARAM));
+ 
+ 		if (CS_SUCCEED != _ct_fill_param(cmd->command_type, param, datafmt, data, &datalen, &indicator, 1)) {
+ 			free(param);
+@@ -3208,10 +3201,9 @@ ct_param(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT datalen,
+ 			return CS_FAIL;
+ 		}
+ 
+-		param = (CS_DYNAMIC_PARAM *) malloc(sizeof(CS_DYNAMIC_PARAM));
++		param = (CS_DYNAMIC_PARAM *) calloc(1, sizeof(CS_DYNAMIC_PARAM));
+ 		if (!param)
+ 			return CS_FAIL;
+-		memset(param, 0, sizeof(CS_DYNAMIC_PARAM));
+ 
+ 		if (CS_SUCCEED != _ct_fill_param(cmd->command_type, param, datafmt, data, &datalen, &indicator, 1)) {
+ 			tdsdump_log(TDS_DBG_INFO1, "ct_param() failed to add CS_DYNAMIC param\n");
+@@ -3259,8 +3251,7 @@ ct_setparam(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT * dat
+ 			return CS_FAIL;
+ 		}
+ 
+-		param = (CSREMOTE_PROC_PARAM *) malloc(sizeof(CSREMOTE_PROC_PARAM));
+-		memset(param, 0, sizeof(CSREMOTE_PROC_PARAM));
++		param = (CSREMOTE_PROC_PARAM *) calloc(1, sizeof(CSREMOTE_PROC_PARAM));
+ 
+ 		if (CS_SUCCEED != _ct_fill_param(cmd->command_type, param, datafmt, data, datalen, indicator, 0)) {
+ 			tdsdump_log(TDS_DBG_INFO1, "ct_setparam() failed to add rpc param\n");
+@@ -3292,8 +3283,7 @@ ct_setparam(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT * dat
+ 			return CS_FAIL;
+ 		}
+ 
+-		param = (CS_DYNAMIC_PARAM *) malloc(sizeof(CS_DYNAMIC_PARAM));
+-		memset(param, 0, sizeof(CS_DYNAMIC_PARAM));
++		param = (CS_DYNAMIC_PARAM *) calloc(1, sizeof(CS_DYNAMIC_PARAM));
+ 
+ 		if (CS_SUCCEED != _ct_fill_param(cmd->command_type, param, datafmt, data, datalen, indicator, 0)) {
+ 			tdsdump_log(TDS_DBG_INFO1, "ct_setparam() failed to add dynamic param\n");
+@@ -3324,8 +3314,7 @@ ct_setparam(CS_COMMAND * cmd, CS_DATAFMT * datafmt, CS_VOID * data, CS_INT * dat
+ 			return CS_FAIL;
+ 		}
+ 
+-		param = (CSREMOTE_PROC_PARAM *) malloc(sizeof(CSREMOTE_PROC_PARAM));
+-		memset(param, 0, sizeof(CSREMOTE_PROC_PARAM));
++		param = (CSREMOTE_PROC_PARAM *) calloc(1, sizeof(CSREMOTE_PROC_PARAM));
+ 
+ 		if (CS_SUCCEED != _ct_fill_param(cmd->command_type, param, datafmt, data, datalen, indicator, 0)) {
+ 			tdsdump_log(TDS_DBG_INFO1, "ct_setparam() failed to add language param\n");
+@@ -4127,10 +4116,9 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *d
+ 			if (param->name == NULL)
+ 				return CS_FAIL;
+ 		} else if (datafmt->namelen > 0) {
+-			param->name = malloc(datafmt->namelen + 1);
++			param->name = calloc(1, datafmt->namelen + 1);
+ 			if (param->name == NULL)
+ 				return CS_FAIL;
+-			memset(param->name, 0, datafmt->namelen + 1);
+ 			strncpy(param->name, datafmt->name, datafmt->namelen);
+ 		} else {
+ 			param->name = NULL;
+@@ -4586,7 +4574,7 @@ _ct_allocate_dynamic(CS_CONNECTION * con, char *id, int idlen)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_ct_allocate_dynamic(%p, %p, %d)\n", con, id, idlen);
+ 
+-	dyn = (CS_DYNAMIC *) malloc(sizeof(CS_DYNAMIC));
++	dyn = (CS_DYNAMIC *) calloc(1, sizeof(CS_DYNAMIC));
+ 
+ 	if (idlen == CS_NULLTERM)
+ 		id_len = strlen(id);
+@@ -4594,7 +4582,6 @@ _ct_allocate_dynamic(CS_CONNECTION * con, char *id, int idlen)
+ 		id_len = idlen;
+ 
+ 	if (dyn != NULL) {
+-		memset(dyn, '\0', sizeof(CS_DYNAMIC));
+ 		dyn->id = malloc(id_len + 1);
+ 		strncpy(dyn->id, id, id_len);
+ 		dyn->id[id_len] = '\0';
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 5383cf5..82f1194 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.76 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.77 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -548,9 +548,8 @@ static const char *aAuth[] = {
+ static HODBCINSTPROPERTY
+ addProperty(HODBCINSTPROPERTY hLastProperty)
+ {
+-	hLastProperty->pNext = (HODBCINSTPROPERTY) malloc(sizeof(ODBCINSTPROPERTY));
++	hLastProperty->pNext = (HODBCINSTPROPERTY) calloc(1, sizeof(ODBCINSTPROPERTY));
+ 	hLastProperty = hLastProperty->pNext;
+-	memset(hLastProperty, 0, sizeof(ODBCINSTPROPERTY));
+ 	return hLastProperty;
+ }
+ 
+diff --git a/src/odbc/descriptor.c b/src/odbc/descriptor.c
+index 59094d6..1eae216 100644
+--- a/src/odbc/descriptor.c
++++ b/src/odbc/descriptor.c
+@@ -47,10 +47,9 @@ desc_alloc(SQLHANDLE parent, int desc_type, int alloc_type)
+ {
+ 	TDS_DESC *desc;
+ 
+-	desc = (TDS_DESC *) malloc(sizeof(TDS_DESC));
++	desc = (TDS_DESC *) calloc(1, sizeof(TDS_DESC));
+ 	if (!desc)
+ 		return NULL;
+-	memset(desc, 0, sizeof(TDS_DESC));
+ 
+ 	/* set defualt header values */
+ 	desc->htype = SQL_HANDLE_DESC;
+diff --git a/src/pool/main.c b/src/pool/main.c
+index 74a42af..db0831f 100644
+--- a/src/pool/main.c
++++ b/src/pool/main.c
+@@ -57,7 +57,7 @@
+ 
+ #include "pool.h"
+ 
+-TDS_RCSID(var, "$Id: main.c,v 1.24 2007/09/17 08:46:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: main.c,v 1.25 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ /* to be set by sig term */
+ static int term = 0;
+@@ -87,8 +87,7 @@ pool_init(char *name)
+ 
+ 	/* initialize the pool */
+ 
+-	pool = (TDS_POOL *) malloc(sizeof(TDS_POOL));
+-	memset(pool, '\0', sizeof(TDS_POOL));
++	pool = (TDS_POOL *) calloc(1, sizeof(TDS_POOL));
+ 	/* FIXME -- read this from the conf file */
+ 	if (!pool_read_conf_file(name, pool)) {
+ 		fprintf(stderr, "Configuration for pool ``%s'' not found.\n", name);
+diff --git a/src/pool/member.c b/src/pool/member.c
+index b31fb5f..7acf8bd 100644
+--- a/src/pool/member.c
++++ b/src/pool/member.c
+@@ -59,7 +59,7 @@
+ #define MAXHOSTNAMELEN 256
+ #endif /* MAXHOSTNAMELEN */
+ 
+-TDS_RCSID(var, "$Id: member.c,v 1.44 2008/12/17 11:04:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: member.c,v 1.45 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ static int pool_packet_read(TDS_POOL_MEMBER * pmbr);
+ static TDSSOCKET *pool_mbr_login(TDS_POOL * pool);
+@@ -108,8 +108,7 @@ pool_mbr_login(TDS_POOL * pool)
+ 	 * FIXME -- tds_connect_and_login no longer preallocates the in_buf need to 
+ 	 * do something like what tds_read_packet does
+ 	 */
+-	tds->in_buf = (unsigned char *) malloc(BLOCKSIZ);
+-	memset(tds->in_buf, 0, BLOCKSIZ);
++	tds->in_buf = (unsigned char *) calloc(BLOCKSIZ, 1);
+ 
+ 	if (pool->database && strlen(pool->database)) {
+ 		query = (char *) malloc(strlen(pool->database) + 5);
+@@ -181,8 +180,7 @@ pool_mbr_init(TDS_POOL * pool)
+ 	/* allocate room for pool members */
+ 
+ 	pool->members = (TDS_POOL_MEMBER *)
+-		malloc(sizeof(TDS_POOL_MEMBER) * pool->num_members);
+-	memset(pool->members, '\0', sizeof(TDS_POOL_MEMBER) * pool->num_members);
++		calloc(pool->num_members, sizeof(TDS_POOL_MEMBER));
+ 
+ 	/* open connections for each member */
+ 
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index ae0b7a0..dd32186 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.38 2009/01/21 08:34:01 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.39 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -660,10 +660,9 @@ tds_ntlm_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t l
+ 		names_blob_len = sizeof(names_blob_prefix_t) + target_info_len + 4;
+ 
+ 		/* read Target Info */
+-		names_blob = (unsigned char *) malloc(names_blob_len);
++		names_blob = (unsigned char *) calloc(names_blob_len, 1);
+ 		if (!names_blob)
+ 			return TDS_FAIL;
+-		memset(names_blob, 0, names_blob_len);
+ 
+ 		fill_names_blob_prefix((names_blob_prefix_t *) names_blob);
+ 		tds_get_n(tds, names_blob + sizeof(names_blob_prefix_t), target_info_len);
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 18fe7ce..5a1afeb 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.136 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.137 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -281,13 +281,12 @@ tds_iconv_alloc(TDSSOCKET * tds)
+ 
+ 	assert(!tds->char_convs);
+ 	if (!(tds->char_convs = (TDSICONV **) malloc(sizeof(TDSICONV *) * (initial_char_conv_count + 1))))
+-	return 1;
+-	char_conv = (TDSICONV *) malloc(sizeof(TDSICONV) * initial_char_conv_count);
++		return 1;
++	char_conv = (TDSICONV *) calloc(initial_char_conv_count, sizeof(TDSICONV));
+ 	if (!char_conv) {
+ 		TDS_ZERO_FREE(tds->char_convs);
+ 		return 1;
+ 	}
+-	memset(char_conv, 0, sizeof(TDSICONV) * initial_char_conv_count);
+ 	tds->char_conv_count = initial_char_conv_count + 1;
+ 
+ 	for (i = 0; i < initial_char_conv_count; ++i) {
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 39b5465..6e74dc9 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.360 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.361 2009/06/09 08:55:23 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1391,10 +1391,8 @@ tds_process_compute_result(TDSSOCKET * tds)
+ 	tdsdump_log(TDS_DBG_INFO1, "processing tds compute result. by_cols = %d\n", by_cols);
+ 
+ 	if (by_cols) {
+-		if ((info->bycolumns = (TDS_SMALLINT *) malloc(by_cols * sizeof(TDS_SMALLINT))) == NULL)
++		if ((info->bycolumns = (TDS_SMALLINT *) calloc(by_cols, sizeof(TDS_SMALLINT))) == NULL)
+ 			return TDS_FAIL;
+-
+-		memset(info->bycolumns, '\0', by_cols * sizeof(TDS_SMALLINT));
+ 	}
+ 	info->by_cols = by_cols;
+ 
+
+commit 6f6fc9bb9b21df5c7bf1ebf378550732b998c4b9
+Author: freddy77 <freddy77>
+Date:   Wed Jun 10 16:44:56 2009 +0000
+
+    limit indentation
+
+diff --git a/ChangeLog b/ChangeLog
+index 36817f4..8d7cea0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jun 10 18:44:48 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: limit indentation
++
+ Tue Jun  9 10:54:29 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/datacopy.c src/ctlib/blk.c src/ctlib/cs.c:
+ 	* src/ctlib/ct.c src/odbc/connectparams.c src/odbc/descriptor.c:
+@@ -1635,4 +1638,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2810 2009/06/09 08:55:23 freddy77 Exp $
++$Id: ChangeLog,v 1.2811 2009/06/10 16:44:56 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index b74c663..b3b331a 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.194 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.195 2009/06/10 16:44:56 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -4157,48 +4157,42 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *d
+ 		param->ind = &param->indicator_value;
+ 		*(param->ind) = *indicator;
+ 
+-		/* here's one way of passing a null parameter */
+-
+-		if (*indicator == -1) {
++		/*
++		 * There are two ways to indicate a parameter with a null value:
++		 * - Pass indicator as -1. In this case, data and datalen are ignored.
++		 * - Pass data as NULL and datalen as 0 or CS_UNUSED
++		 */
++		if (*indicator == -1 || (data == NULL && (*datalen == 0 || *datalen == CS_UNUSED))) {
+ 			param->value = NULL;
+ 			*(param->datalen) = 0;
+ 			param_is_null = 1;
+ 		} else {
++			/* datafmt.datalen is ignored for fixed length types */
+ 
+-			/* and here's another... */
+-			if ((*datalen == 0 || *datalen == CS_UNUSED) && data == NULL) {
+-				param->value = NULL;
+-				*(param->datalen) = 0;
+-				param_is_null = 1;
++			if (is_fixed_type(param->type)) {
++				*(param->datalen) = tds_get_size_by_type(param->type);
+ 			} else {
++				*(param->datalen) = (*datalen == CS_UNUSED) ? 0 : *datalen;
++			}
+ 
+-				/* datafmt.datalen is ignored for fixed length types */
+-
+-				if (is_fixed_type(param->type)) {
+-					*(param->datalen) = tds_get_size_by_type(param->type);
+-				} else {
+-					*(param->datalen) = (*datalen == CS_UNUSED) ? 0 : *datalen;
+-				}
+-
+-				if (*(param->datalen) && data) {
+-					if (*(param->datalen) == CS_NULLTERM) {
+-						tdsdump_log(TDS_DBG_INFO1, 
+-							    " _ct_fill_param() about to strdup string %u bytes long\n",
+-							    (unsigned int) strlen(data));
+-						*(param->datalen) = strlen(data);
+-					} else if (*(param->datalen) < 0) {
+-						return CS_FAIL;
+-					}
+-					param->value = malloc(*(param->datalen));
+-					if (param->value == NULL)
+-						return CS_FAIL;
+-					memcpy(param->value, data, *(param->datalen));
+-					param->param_by_value = 1;
+-				} else {
+-					param->value = NULL;
+-					*(param->datalen) = 0;
+-					param_is_null = 1;
++			if (*(param->datalen) && data) {
++				if (*(param->datalen) == CS_NULLTERM) {
++					tdsdump_log(TDS_DBG_INFO1,
++						    " _ct_fill_param() about to strdup string %u bytes long\n",
++						    (unsigned int) strlen(data));
++					*(param->datalen) = strlen(data);
++				} else if (*(param->datalen) < 0) {
++					return CS_FAIL;
+ 				}
++				param->value = malloc(*(param->datalen));
++				if (param->value == NULL)
++					return CS_FAIL;
++				memcpy(param->value, data, *(param->datalen));
++				param->param_by_value = 1;
++			} else {
++				param->value = NULL;
++				*(param->datalen) = 0;
++				param_is_null = 1;
+ 			}
+ 		}
+ 
+
+commit a0c233bf805e2301c67e23397e61aab33c63f07c
+Author: freddy77 <freddy77>
+Date:   Wed Jun 10 18:54:38 2009 +0000
+
+    move blob check to odbc_tds2sql
+
+diff --git a/ChangeLog b/ChangeLog
+index 8d7cea0..e973916 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jun 10 20:54:07 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/odbc.c src/odbc/odbc_util.c:
++	- move blob check to odbc_tds2sql
++
+ Wed Jun 10 18:44:48 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c: limit indentation
+ 
+@@ -1638,4 +1642,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2811 2009/06/10 16:44:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2812 2009/06/10 18:54:38 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 2ac12f8..fb8b928 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.62 2008/10/24 05:37:19 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.63 2009/06/10 18:54:38 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -153,6 +153,15 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 
+ 	assert(desttype != SQL_C_DEFAULT);
+ 
++	if (curcol) {
++		if (is_blob_col(curcol))
++			src = ((TDSBLOB *) src)->textvalue;
++		if (is_variable_type(curcol->column_type)) {
++			src += curcol->column_text_sqlgetdatapos;
++			srclen -= curcol->column_text_sqlgetdatapos;
++		}
++	}
++
+ 	nDestSybType = odbc_c_to_server_type(desttype);
+ 	if (nDestSybType == TDS_FAIL) {
+ 		odbc_errs_add(&stmt->errs, "HY003", NULL);
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 78d7401..e7ba3a6 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.511 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.512 2009/06/10 18:54:38 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3655,9 +3655,8 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				TDS_CHAR *data_ptr = (TDS_CHAR *) drec_ard->sql_desc_data_ptr;
+ 
+ 				src = (TDS_CHAR *) colinfo->column_data;
+-				if (is_blob_col(colinfo))
+-					src = ((TDSBLOB *) src)->textvalue;
+ 				srclen = colinfo->column_cur_size;
++				colinfo->column_text_sqlgetdatapos = 0;
+ 				c_type = drec_ard->sql_desc_concise_type;
+ 				if (c_type == SQL_C_DEFAULT)
+ 					c_type = odbc_sql_to_c_type_default(stmt->ird->records[i].sql_desc_concise_type);
+@@ -4652,11 +4651,8 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 	TDSCOLUMN *colinfo;
+ 	TDSRESULTINFO *resinfo;
+ 	TDSSOCKET *tds;
+-	TDS_CHAR *src;
+-	int srclen;
+ 	TDSCONTEXT *context;
+ 	SQLLEN dummy_cb;
+-	int nSybType;
+ 
+ 	INIT_HSTMT;
+ 
+@@ -4700,25 +4696,19 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 		/* TODO check what should happen if pcbValue was NULL */
+ 		*pcbValue = SQL_NULL_DATA;
+ 	} else {
++		TDS_CHAR *src;
++		int srclen;
++		int nSybType;
++
++		if (colinfo->column_text_sqlgetdatapos > 0
++		    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
++			ODBC_RETURN(stmt, SQL_NO_DATA);
++
+ 		src = (TDS_CHAR *) colinfo->column_data;
+-		if (is_variable_type(colinfo->column_type)) {
+-			if (colinfo->column_text_sqlgetdatapos > 0
+-			    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-				ODBC_RETURN(stmt, SQL_NO_DATA);
+-
+-			/* 2003-8-29 check for an old bug -- freddy77 */
+-			assert(colinfo->column_text_sqlgetdatapos >= 0);
+-			if (is_blob_col(colinfo))
+-				src = ((TDSBLOB *) src)->textvalue;
+-			src += colinfo->column_text_sqlgetdatapos;
+-			srclen = colinfo->column_cur_size - colinfo->column_text_sqlgetdatapos;
+-		} else {
+-			if (colinfo->column_text_sqlgetdatapos > 0
+-			    && colinfo->column_text_sqlgetdatapos >= colinfo->column_cur_size)
+-				ODBC_RETURN(stmt, SQL_NO_DATA);
++		srclen = colinfo->column_cur_size;
++		if (!is_variable_type(colinfo->column_type))
++			colinfo->column_text_sqlgetdatapos = 0;
+ 
+-			srclen = colinfo->column_cur_size;
+-		}
+ 		nSybType = tds_get_conversion_type(colinfo->on_server.column_type, colinfo->on_server.column_size);
+ 		if (fCType == SQL_C_DEFAULT)
+ 			fCType = odbc_sql_to_c_type_default(stmt->ird->records[icol - 1].sql_desc_concise_type);
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 641b5e8..2665bda 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.107 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.108 2009/06/10 18:54:38 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -209,8 +209,7 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 		}
+ 
+ 		src = (TDS_CHAR *) colinfo->column_data;
+-		if (is_blob_col(colinfo))
+-			src = ((TDSBLOB *) src)->textvalue;
++		colinfo->column_text_sqlgetdatapos = 0;
+ 		srclen = colinfo->column_cur_size;
+ 		c_type = drec_apd->sql_desc_concise_type;
+ 		if (c_type == SQL_C_DEFAULT)
+
+commit dcdeb142434c6a7cceab62640fd8f78f53c16d5b
+Author: freddy77 <freddy77>
+Date:   Fri Jun 12 08:53:49 2009 +0000
+
+    improve variant support if --enable-developing
+
+diff --git a/ChangeLog b/ChangeLog
+index e973916..99326f8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Jun 12 10:53:39 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/convert_tds2sql.c:
++	* src/odbc/unittests/data.c src/tds/convert.c src/tds/tds_checks.c:
++	* src/tds/token.c:
++	- improve variant support if --enable-developing
++
+ Wed Jun 10 20:54:07 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	- move blob check to odbc_tds2sql
+@@ -1642,4 +1648,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2812 2009/06/10 18:54:38 freddy77 Exp $
++$Id: ChangeLog,v 1.2813 2009/06/12 08:53:49 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 04dc446..2bfe1cd 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.314 2009/05/28 16:23:31 freddy77 Exp $ */
++/* $Id: tds.h,v 1.315 2009/06/12 08:53:49 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -917,6 +917,18 @@ typedef struct tds_blob
+ 	TDS_CHAR timestamp[8];
+ } TDSBLOB;
+ 
++/**
++ * Store variant informations
++ */
++typedef struct tds_variant
++{
++	TDS_CHAR *data;
++	TDS_INT size;
++	TDS_INT data_len;
++	TDS_UCHAR type;
++	TDS_UCHAR collation[5];
++} TDSVARIANT;
++
+ /** 
+  * TDS 8.0 collation informations.
+  */
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index fb8b928..750d3b5 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.63 2009/06/10 18:54:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.64 2009/06/12 08:53:49 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -154,7 +154,7 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 	assert(desttype != SQL_C_DEFAULT);
+ 
+ 	if (curcol) {
+-		if (is_blob_col(curcol))
++		if (is_blob_col(curcol) && curcol->column_type != SYBVARIANT)
+ 			src = ((TDSBLOB *) src)->textvalue;
+ 		if (is_variable_type(curcol->column_type)) {
+ 			src += curcol->column_text_sqlgetdatapos;
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 2f1a59c..39ea5eb 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.27 2009/05/28 16:17:49 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.28 2009/06/12 08:53:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -35,6 +35,8 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 	sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
+ 	if (strncmp(value_to_convert, "0x", 2) == 0)
+ 		sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
++	else if (strcmp(type, "SQL_VARIANT") == 0)
++		sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert);
+ 	Command(sbuf);
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHKFetch("S");
+@@ -178,6 +180,16 @@ main(int argc, char *argv[])
+ 	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_WCHAR, "23 2006-06-09 11:22:44.000");
+ 	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_WCHAR, "19 2006-06-12 22:37:00");
+ 
++#ifdef ENABLE_DEVELOPING
++	if (db_is_microsoft() && db_version_int() >= 0x08000000u) {
++		Test("SQL_VARIANT", "CAST('123' AS INT)", SQL_C_CHAR, "3 123");
++		Test("SQL_VARIANT", "CAST('ciao' AS VARCHAR(10))", SQL_C_CHAR, "4 ciao");
++		Test("SQL_VARIANT", "CAST('321' AS VARBINARY(10))", SQL_C_CHAR, "6 333231");
++		Test("SQL_VARIANT", "CAST('-123.4' AS FLOAT)", SQL_C_CHAR, "6 -123.4");
++		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "6 -123.4");
++	}
++#endif
++
+ 	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
+ 		Test("VARCHAR(MAX)", "goodbye!", SQL_C_CHAR, "8 goodbye!");
+ 		Test("NVARCHAR(MAX)", "Micio mao", SQL_C_CHAR, "9 Micio mao");
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 6ebd544..b665b31 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.191 2009/06/09 06:50:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.192 2009/06/12 08:53:49 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -1620,6 +1620,13 @@ tds_convert(const TDSCONTEXT * tds_ctx, int srctype, const TDS_CHAR * src, TDS_U
+ 
+ 	assert(srclen >= 0 && srclen <= 2147483647u);
+ 
++	if (srctype == SYBVARIANT) {
++		TDSVARIANT *v = (TDSVARIANT*) src;
++		srctype = v->type;
++		src = v->data;
++		srclen = v->data_len;
++	}
++
+ 	switch (srctype) {
+ 	case CASE_ALL_CHAR:
+ 		length = tds_convert_char(srctype, src, srclen, desttype, cr);
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index 81cba27..50f60de 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.22 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.23 2009/06/12 08:53:49 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -201,6 +201,8 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	} else if (column->column_varint_size == 8) {
+ 		assert(column->on_server.column_type == XSYBVARCHAR || column->on_server.column_type == XSYBVARBINARY || column->on_server.column_type == XSYBNVARCHAR);
+ 		varint_ok = 1;
++	} else if (column->column_type == SYBVARIANT) {
++		assert(column->column_varint_size == 4);
+ 	} else {
+ 		assert(column->column_varint_size < 3);
+ 	}
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 6e74dc9..c545ef8 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.361 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.362 2009/06/12 08:53:49 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1985,6 +1985,93 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ }
+ #endif
+ 
++static int
++tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
++{
++#ifdef ENABLE_DEVELOPING
++	int colsize = tds_get_int(tds), varint;
++	TDS_UCHAR type, info_len;
++	TDSVARIANT *v;
++
++	/* NULL */
++	curcol->column_cur_size = -1;
++	if (colsize < 2) {
++		tds_get_n(tds, NULL, colsize);
++		return TDS_SUCCEED;
++	}
++
++	v = (TDSVARIANT*) curcol->column_data;
++	v->type = type = tds_get_byte(tds);
++	info_len = tds_get_byte(tds);
++	colsize -= 2;
++	if (info_len > colsize)
++		goto error_type;
++	if (is_collate_type(type)) {
++		if (sizeof(v->collation) > info_len)
++			goto error_type;
++		tds_get_n(tds, v->collation, sizeof(v->collation));
++		colsize -= sizeof(v->collation);
++		info_len -= sizeof(v->collation);
++	}
++	/* special case for numeric */
++	if (is_numeric_type(type)) {
++		TDS_NUMERIC *num;
++		if (info_len != 2)
++			goto error_type;
++		if (v->data)
++			TDS_ZERO_FREE(v->data);
++		v->data_len = sizeof(TDS_NUMERIC);
++		num = (TDS_NUMERIC*) calloc(1, sizeof(TDS_NUMERIC));
++		v->data = num;
++		num->precision = tds_get_byte(tds);
++		num->scale     = tds_get_byte(tds);
++		colsize -= 2;
++		/* FIXME check prec/scale, don't let server crash us */
++		if (colsize > sizeof(num->array))
++			goto error_type;
++		tds_get_n(tds, num->array, colsize);
++		if (IS_TDS7_PLUS(tds))
++			tds_swap_numeric(num);
++		return TDS_SUCCEED;
++	}
++	varint = tds_get_varint_size(tds, type);
++	if (varint != info_len)
++		goto error_type;
++	switch (varint) {
++	case 0:
++		v->size = tds_get_size_by_type(type);
++		break;
++	case 1:
++		v->size = tds_get_byte(tds);
++		break;
++	case 2:
++		v->size = tds_get_smallint(tds);
++		break;
++	default:
++		goto error_type;
++	}
++	colsize -= info_len;
++	curcol->column_cur_size = colsize;
++	if (v->data)
++		TDS_ZERO_FREE(v->data);
++	v->data_len = colsize;
++	if (colsize) {
++		v->data = (TDS_CHAR*) malloc(colsize);
++		tds_get_n(tds, v->data, colsize);
++	}
++	return TDS_SUCCEED;
++
++error_type:
++	tds_get_n(tds, NULL, colsize);
++	return TDS_FAIL;
++#else
++	int colsize = tds_get_int(tds);
++	tds_get_n(tds, NULL, colsize);
++	curcol->column_cur_size = -1;
++	return TDS_SUCCEED;
++#endif
++}
++
+ /**
+  * Read a data from wire
+  * \param tds state information for the socket and the TDS protocol
+@@ -2013,12 +2100,8 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		 * len (int32), type (int8), 7 (int8), collation, column size (int16) -- [n]char, [n]varchar, binary, varbinary 
+ 		 * BLOBS (text/image) not supported
+ 		 */
+-		if (curcol->column_type == SYBVARIANT) {
+-			colsize = tds_get_int(tds);
+-			tds_get_n(tds, NULL, colsize);
+-			curcol->column_cur_size = -1;
+-			return TDS_SUCCEED;
+-		}
++		if (curcol->column_type == SYBVARIANT)
++			return tds7_get_variant(tds, curcol);
+ 		
+ 		/*
+ 		 * LONGBINARY
+
+commit 899efdd12a1c79b7bba7bf1c7dcb72645996ab04
+Author: freddy77 <freddy77>
+Date:   Wed Jun 17 16:20:59 2009 +0000
+
+    fix iconv portability problem
+
+diff --git a/ChangeLog b/ChangeLog
+index 99326f8..c847906 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jun 17 18:20:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/iconv.c: fix iconv portability problem
++
+ Fri Jun 12 10:53:39 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/convert_tds2sql.c:
+ 	* src/odbc/unittests/data.c src/tds/convert.c src/tds/tds_checks.c:
+@@ -1648,4 +1651,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2813 2009/06/12 08:53:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2814 2009/06/17 16:20:59 freddy77 Exp $
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 5a1afeb..b7c8b3e 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.137 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.138 2009/06/17 16:20:59 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -746,9 +746,13 @@ tds_iconv(TDSSOCKET * tds, const TDSICONV * conv, TDS_ICONV_DIRECTION io,
+ 		}
+ 		/* iconv success, return */
+ 		if (irreversible != (size_t) - 1) {
++			/* here we detect end of conversion and try to reset shift state */
+ 			if (inbuf) {
++				/*
++				 * if inbuf or *inbuf is NULL iconv reset the shift state.
++				 * Note that setting inbytesleft to NULL can cause core so don't do it!
++				 */
+ 				inbuf = NULL;
+-				inbytesleft = 0;
+ 				continue;
+ 			}
+ 			break;
+
+commit 3046e840dfc80005b8678fd292959e64ec25c328
+Author: freddy77 <freddy77>
+Date:   Wed Jun 17 17:07:30 2009 +0000
+
+    reuse some macros for version check
+
+diff --git a/ChangeLog b/ChangeLog
+index c847906..54845e2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jun 17 19:07:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/iconv.c: reuse some macros for version check
++
+ Wed Jun 17 18:20:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/iconv.c: fix iconv portability problem
+ 
+@@ -1651,4 +1654,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2814 2009/06/17 16:20:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2815 2009/06/17 17:07:30 freddy77 Exp $
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index b7c8b3e..42645d7 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.138 2009/06/17 16:20:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.139 2009/06/17 17:07:31 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -395,7 +395,7 @@ tds_iconv_open(TDSSOCKET * tds, const char *charset)
+ 	 * ISO8859-1 <-> server meta data
+ 	 */
+ 	name = UCS_2LE;
+-	if (tds->major_version < 7) {
++	if (!IS_TDS7_PLUS(tds)) {
+ 		name = "ISO-8859-1";
+ 		if (tds->env.charset)
+ 			name = tds->env.charset;
+@@ -1008,7 +1008,7 @@ tds_srv_charset_changed(TDSSOCKET * tds, const char *charset)
+ 	int canonic_charset_num = tds_canonical_charset(charset);
+ 	const char *canonic_charset;
+ 
+-	if (tds->major_version >= 7 && canonic_charset_num == TDS_CHARSET_ISO_8859_1)
++	if (IS_TDS7_PLUS(tds) && canonic_charset_num == TDS_CHARSET_ISO_8859_1)
+ 		canonic_charset_num = TDS_CHARSET_CP1252;
+ 
+ 	/* ignore request to change to unknown charset */
+@@ -1029,7 +1029,7 @@ tds_srv_charset_changed(TDSSOCKET * tds, const char *charset)
+ 		tds->char_convs[client2server_chardata] = char_conv;
+ 
+ 	/* if sybase change also server conversions */
+-	if (tds->major_version >= 7)
++	if (IS_TDS7_PLUS(tds))
+ 		return;
+ 
+ 	char_conv = tds->char_convs[iso2server_metadata];
+
+commit 79065c79addc6ae6087408e7d661e68ec7c87f6b
+Author: jklowden <jklowden>
+Date:   Fri Jun 19 13:50:26 2009 +0000
+
+    added $ local keyword
+
+diff --git a/ChangeLog b/ChangeLog
+index 54845e2..aa67246 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jun 19 09:49:26 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* CVSROOT/config added $FreeTDS$ local keyword
++
+ Wed Jun 17 19:07:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/iconv.c: reuse some macros for version check
+ 
+@@ -1654,4 +1657,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog  truncated because of release
+ 	* ChangeLog-0.82 added because of release
+ 	
+-$Id: ChangeLog,v 1.2815 2009/06/17 17:07:30 freddy77 Exp $
++$FreeTDS$
+
+commit 67fcfe726bd6ab0ad22c2923bc16816d45a55853
+Author: jklowden <jklowden>
+Date:   Fri Jun 19 13:51:47 2009 +0000
+
+    testing local keyword
+
+diff --git a/ChangeLog b/ChangeLog
+index aa67246..b0fb66a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jun 19 09:50:29 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* ChangeLog testing local keyword
++
+ Fri Jun 19 09:49:26 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* CVSROOT/config added $FreeTDS$ local keyword
+ 
+
+commit 43c3441820521310c670955f063d12b7bb7c37ec
+Author: jklowden <jklowden>
+Date:   Fri Jun 19 13:56:12 2009 +0000
+
+    testing local keyword expansion
+
+diff --git a/ChangeLog b/ChangeLog
+index b0fb66a..4adf4ad 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,5 +1,5 @@
+ Fri Jun 19 09:50:29 EDT 2009	JK Lowden <jklowden@freetds.org>
+-	* ChangeLog testing local keyword
++	* ChangeLog testing local keyword expansion
+ 
+ Fri Jun 19 09:49:26 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* CVSROOT/config added $FreeTDS$ local keyword
+
+commit 2fa526e86375e2307ceba081c6ee672561cd4f74
+Author: jklowden <jklowden>
+Date:   Fri Jun 19 13:56:58 2009 +0000
+
+    added $ local keyword
+
+diff --git a/ChangeLog b/ChangeLog
+index 4adf4ad..aa67246 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,6 +1,3 @@
+-Fri Jun 19 09:50:29 EDT 2009	JK Lowden <jklowden@freetds.org>
+-	* ChangeLog testing local keyword expansion
+-
+ Fri Jun 19 09:49:26 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* CVSROOT/config added $FreeTDS$ local keyword
+ 
+
+commit 08beaafbe6219028684d4b64cbb60760a746e298
+Author: jklowden <jklowden>
+Date:   Fri Jun 19 13:57:15 2009 +0000
+
+    testing local keyword expansion
+
+diff --git a/ChangeLog b/ChangeLog
+index aa67246..4adf4ad 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jun 19 09:50:29 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* ChangeLog testing local keyword expansion
++
+ Fri Jun 19 09:49:26 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* CVSROOT/config added $FreeTDS$ local keyword
+ 
+
+commit dca82b1f281c6b256143bec5827514b7650ba289
+Author: jklowden <jklowden>
+Date:   Fri Jun 19 14:05:40 2009 +0000
+
+    added $Id$ back
+
+diff --git a/ChangeLog b/ChangeLog
+index 4adf4ad..15e674c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1661,3 +1661,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
++$Id: ChangeLog,v 1.2821 2009/06/19 14:05:40 jklowden Exp $
+
+commit 8772feb729e87e2f3365b1af282fadd7e13208a5
+Author: jklowden <jklowden>
+Date:   Sat Jun 20 21:58:26 2009 +0000
+
+    removed local keyword because not supported
+
+diff --git a/ChangeLog b/ChangeLog
+index 15e674c..b3786e1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 20 17:57:22 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* CVSROOT/config removed local keyword because not supported
++
+ Fri Jun 19 09:50:29 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog testing local keyword expansion
+ 
+@@ -1661,4 +1664,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2821 2009/06/19 14:05:40 jklowden Exp $
++$Id: ChangeLog,v 1.2822 2009/06/20 21:58:26 jklowden Exp $
+
+commit 9f36e365d1cf41435898668190d82a18733f2c85
+Author: jklowden <jklowden>
+Date:   Tue Jun 23 23:52:04 2009 +0000
+
+    added HP/UX news
+
+diff --git a/ChangeLog b/ChangeLog
+index b3786e1..276601a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jun 23 19:49:52 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* doc/htdoc/news.html added HP/UX news
++
+ Sat Jun 20 17:57:22 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* CVSROOT/config removed local keyword because not supported
+ 
+@@ -1664,4 +1667,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2822 2009/06/20 21:58:26 jklowden Exp $
++$Id: ChangeLog,v 1.2823 2009/06/23 23:52:04 jklowden Exp $
+diff --git a/doc/htdoc/news.html b/doc/htdoc/news.html
+index 1c7baf5..9cc5168 100644
+--- a/doc/htdoc/news.html
++++ b/doc/htdoc/news.html
+@@ -1,7 +1,7 @@
+ <?xml version="1.0" encoding="iso-8859-1" ?>
+ <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+ <html xmlns="http://www.w3.org/1999/xhtml">
+-<!-- $Id: news.html,v 1.18 2008/07/06 13:17:34 jklowden Exp $ -->
++<!-- $Id: news.html,v 1.19 2009/06/23 23:52:04 jklowden Exp $ -->
+ <head>
+ <title>FreeTDS.org</title>
+ </head>
+@@ -33,6 +33,18 @@ News&nbsp;&nbsp;|&nbsp;
+ <table summary="layout" width="80%" align="center">
+ 
+ <!--  item  -->
++<tr bgcolor="#c9c9ff"><td>Building 0.82 on HP/UX</td></tr>
++<tr>
++<td>
++
++<P>To build FreeTDS 0.82 on HP/UX, you may find you need GNU libiconv.  <a href="contrib/hpux/">Detailed intructions</a> were provided Pravin Shyam Goyal on 23 June 2009:
++<br />
++
++</td>
++</tr>
++
++
++<!--  item  -->
+ <tr bgcolor="#c9c9ff"><td>Building 0.82 on AIX</td></tr>
+ <tr>
+ <td>
+
+commit f251a4cc4d12cf50ffe23d443b20d571725184df
+Author: freddy77 <freddy77>
+Date:   Thu Jun 25 20:32:01 2009 +0000
+
+    add test for empty not null strings
+
+diff --git a/ChangeLog b/ChangeLog
+index 276601a..a5ba541 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jun 25 22:31:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/lang_ct_param.c:
++	- add test for empty not null strings
++
+ Tue Jun 23 19:49:52 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* doc/htdoc/news.html added HP/UX news
+ 
+@@ -1667,4 +1671,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2823 2009/06/23 23:52:04 jklowden Exp $
++$Id: ChangeLog,v 1.2824 2009/06/25 20:32:01 freddy77 Exp $
+diff --git a/src/ctlib/unittests/lang_ct_param.c b/src/ctlib/unittests/lang_ct_param.c
+index 7485c85..8865134 100644
+--- a/src/ctlib/unittests/lang_ct_param.c
++++ b/src/ctlib/unittests/lang_ct_param.c
+@@ -16,11 +16,11 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: lang_ct_param.c,v 1.7 2006/12/26 14:56:18 freddy77 Exp $";
++static char software_version[] = "$Id: lang_ct_param.c,v 1.8 2009/06/25 20:32:01 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *query =
+-	"insert into #ctparam_lang (name,age,cost,bdate,fval) values (@in1, @in2, @moneyval, @dateval, @floatval)";
++	"insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (@in1, @in2, @in3, @moneyval, @dateval, @floatval)";
+ 
+ CS_RETCODE ex_servermsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_SERVERMSG * errmsg);
+ CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
+@@ -59,7 +59,7 @@ main(int argc, char *argv[])
+ 	ct_callback(ctx, NULL, CS_SET, CS_SERVERMSG_CB, (CS_VOID *) ex_servermsg_cb);
+ 
+ 	strcpy(cmdbuf, "create table #ctparam_lang (id numeric identity not null, \
+-		name varchar(30), age int, cost money, bdate datetime, fval float) ");
++		name varchar(30), name2 varchar(20), age int, cost money, bdate datetime, fval float) ");
+ 
+ 	ret = run_command(cmd, cmdbuf);
+ 
+@@ -74,7 +74,7 @@ main(int argc, char *argv[])
+ 	/* if worked, test by position */
+ 	if (0 == errCode)
+ 		errCode = insert_test(conn, cmd, 0);
+-	query = "insert into #ctparam_lang (name,age,cost,bdate,fval) values (?, ?, ?, ?, ?)";
++	query = "insert into #ctparam_lang (name,name2,age,cost,bdate,fval) values (?, ?, ?, ?, ?, ?)";
+ 	if (0 == errCode)
+ 		errCode = insert_test(conn, cmd, 0);
+ 
+@@ -111,6 +111,7 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
+ 	CS_DATEREC datevar;
+ 	char moneystring[10];
+ 	char dummy_name[30];
++	char dummy_name2[20];
+ 	CS_INT destlen;
+ 
+ 	/* clear table */
+@@ -123,6 +124,7 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
+ 	intvar = 2;
+ 	floatvar = 0.12;
+ 	strcpy(dummy_name, "joe blow");
++	strcpy(dummy_name2, "");
+ 	strcpy(moneystring, "300.90");
+ 
+ 	/*
+@@ -200,6 +202,21 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
+ 		strcpy(datafmt.name, "@in2");
+ 	else
+ 		datafmt.name[0] = 0;
++	datafmt.maxlength = 255;
++	datafmt.namelen = CS_NULLTERM;
++	datafmt.datatype = CS_CHAR_TYPE;
++	datafmt.status = CS_INPUTVALUE;
++
++	ret = ct_param(cmd, &datafmt, dummy_name2, strlen(dummy_name2), 0);
++	if (CS_SUCCEED != ret) {
++		fprintf(stderr, "ct_param(char) failed\n");
++		return 1;
++	}
++
++	if (useNames)
++		strcpy(datafmt.name, "@in3");
++	else
++		datafmt.name[0] = 0;
+ 	datafmt.namelen = CS_NULLTERM;
+ 	datafmt.datatype = CS_INT_TYPE;
+ 	datafmt.status = CS_INPUTVALUE;
+@@ -308,7 +325,7 @@ insert_test(CS_CONNECTION *conn, CS_COMMAND *cmd, int useNames)
+ 		fprintf(stderr, "ct_results returned unexpected result %d.\n", (int) ret);
+ 
+ 	/* test row inserted */
+-	ret = run_command(cmd, "if not exists(select * from #ctparam_lang) select 1");
++	ret = run_command(cmd, "if not exists(select * from #ctparam_lang where name = 'joe blow' and name2 is not null and age = 2) select 1");
+ 	if (ret != CS_SUCCEED) {
+ 		fprintf(stderr, "check row inserted failed\n");
+ 		exit(1);
+
+commit 84f75fc7a3fdc91ffd482e0159dc25c870d53e4e
+Author: freddy77 <freddy77>
+Date:   Thu Jun 25 20:47:48 2009 +0000
+
+    style change
+
+diff --git a/ChangeLog b/ChangeLog
+index a5ba541..030fffa 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jun 25 22:47:37 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: comment style
++
+ Thu Jun 25 22:31:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/lang_ct_param.c:
+ 	- add test for empty not null strings
+@@ -1671,4 +1674,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2824 2009/06/25 20:32:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2825 2009/06/25 20:47:48 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index b3b331a..864ec2f 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.195 2009/06/10 16:44:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.196 2009/06/25 20:47:48 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -3924,9 +3924,10 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ 			return NULL;
+ 		}
+ 
+-		/* The parameteter data has been passed by reference */
+-		/* i.e. using ct_setparam rather than ct_param       */
+-
++		/*
++		 * The parameteter data has been passed by reference
++		 * i.e. using ct_setparam rather than ct_param
++		 */
+ 		if (p->param_by_value == 0) {
+ 
+ 			param_is_null = 0;
+
+commit 6f4eba9ae2a5748b48482036538bdb95a1b4a1c5
+Author: freddy77 <freddy77>
+Date:   Thu Jun 25 20:51:17 2009 +0000
+
+    applied Andrew Victor patch for empty strings
+
+diff --git a/ChangeLog b/ChangeLog
+index 030fffa..22ccd87 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jun 25 22:51:09 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: Andrew Victor patch for empty strings (modified)
++
+ Thu Jun 25 22:47:37 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c: comment style
+ 
+@@ -1674,4 +1677,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2825 2009/06/25 20:47:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2826 2009/06/25 20:51:17 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 864ec2f..2ec1695 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.196 2009/06/25 20:47:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.197 2009/06/25 20:51:17 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -3867,7 +3867,7 @@ paramrowalloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *va
+ 	if (!row)
+ 		return NULL;
+ 
+-	if (size > 0 && value) {
++	if (value) {
+ 		/* TODO check for BLOB and numeric */
+ 		if (size > curcol->column_size) {
+ 			tdsdump_log(TDS_DBG_FUNC, "paramrowalloc(): RESIZE %d to %d\n", size, curcol->column_size);
+@@ -4176,7 +4176,7 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *d
+ 				*(param->datalen) = (*datalen == CS_UNUSED) ? 0 : *datalen;
+ 			}
+ 
+-			if (*(param->datalen) && data) {
++			if (data) {
+ 				if (*(param->datalen) == CS_NULLTERM) {
+ 					tdsdump_log(TDS_DBG_INFO1,
+ 						    " _ct_fill_param() about to strdup string %u bytes long\n",
+@@ -4185,7 +4185,7 @@ _ct_fill_param(CS_INT cmd_type, CS_PARAM *param, CS_DATAFMT *datafmt, CS_VOID *d
+ 				} else if (*(param->datalen) < 0) {
+ 					return CS_FAIL;
+ 				}
+-				param->value = malloc(*(param->datalen));
++				param->value = malloc(*(param->datalen) ? *(param->datalen) : 1);
+ 				if (param->value == NULL)
+ 					return CS_FAIL;
+ 				memcpy(param->value, data, *(param->datalen));
+
+commit 404f0b50bc2d088c085737d376577f3734f9a0c1
+Author: jklowden <jklowden>
+Date:   Fri Jul 10 18:03:51 2009 +0000
+
+    pad nullable CHAR written to hostfile.
+
+diff --git a/ChangeLog b/ChangeLog
+index 22ccd87..821b030 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jul 10 14:01:28 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c pad nullable CHAR written to hostfile. 
++
+ Thu Jun 25 22:51:09 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c: Andrew Victor patch for empty strings (modified)
+ 
+@@ -1677,4 +1680,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2826 2009/06/25 20:51:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2827 2009/07/10 18:03:51 jklowden Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 34fa10e..d23172e 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.186 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.187 2009/07/10 18:03:52 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -857,12 +857,6 @@ _bcp_exec_out(DBPROCESS * dbproc, DBINT * rows_copied)
+ 				destlen = -1;
+ 				break;
+ 			case SYBCHAR:
+-				buflen = curcol->column_size + 1;
+-				if (curcol->column_nullable)
+-					destlen = -1;
+-				else
+-					destlen = -2;
+-				break;
+ 			case SYBTEXT:
+ 				/* FIXME column_size ?? if 2gb ?? */
+ 				buflen = curcol->column_size + 1;
+@@ -1761,9 +1755,7 @@ _bcp_exec_in(DBPROCESS * dbproc, DBINT * rows_copied)
+ 						tds_bcp_start(tds, dbproc->bcpinfo);
+ 					}
+ 				}
+-			} else {
+-				printf("skipping row %d (because <= %d)\n", dbproc->hostfileinfo->firstrow, row_of_hostfile);
+-			}
++			} 
+ 		}
+ 
+ 		row_start = ftello(hostfile);
+
+commit 10c296b6ca218964580d264dc63630bc682ba31c
+Author: jklowden <jklowden>
+Date:   Tue Jul 14 21:50:27 2009 +0000
+
+    more messages, perhaps somewhat clearer
+
+diff --git a/ChangeLog b/ChangeLog
+index 821b030..f623b3c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 14 17:48:04 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql more messages, perhaps somewhat clearer
++
+ Fri Jul 10 14:01:28 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/bcp.c pad nullable CHAR written to hostfile. 
+ 
+@@ -1680,4 +1683,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2827 2009/07/10 18:03:51 jklowden Exp $
++$Id: ChangeLog,v 1.2828 2009/07/14 21:50:27 jklowden Exp $
+diff --git a/src/apps/osql b/src/apps/osql
+index 077f5f4..d3d1ad7 100755
+--- a/src/apps/osql
++++ b/src/apps/osql
+@@ -1,5 +1,5 @@
+ #! /bin/sh
+-# $Id: osql,v 1.8 2009/05/20 14:17:31 jklowden Exp $
++# $Id: osql,v 1.9 2009/07/14 21:50:27 jklowden Exp $
+ #
+ # Check odbc.ini, odbcinst, and, optionally, freetds.conf, 
+ # then execute isql (assume it's unixODBC's isql).  
+@@ -157,17 +157,18 @@ do
+ 				| grep -Ei '^[[:space:]]*driver[[:space:]]*=')
+ 		if [ -z "${DRIVER_LINE}" ]
+ 		then
+-			echo "no driver mentioned for [$D] in $(basename ${ODBC_INI})"
++			echo "  no driver mentioned for [$D] in $(basename ${ODBC_INI})"
+ 			continue
+ 		fi
+ 
++		echo "  found driver line: \"${DRIVER_LINE}\""
+ 		DRIVER=$(echo ${DRIVER_LINE} | awk -F '[[:space:]]*=[[:space:]]*' '{print $2}')
+ 		if [ "${DRIVER}" ]
+ 		then
+-			echo "driver \"${DRIVER}\" found for [$D] in $(basename ${ODBC_INI})"
++			echo "  driver \"${DRIVER}\" found for [$D] in $(basename ${ODBC_INI})"
+ 			break
+ 		else
+-			echo "driver line incomplete for [$D] in $(basename ${ODBC_INI})"
++			echo "  driver line for [$D] incomplete in $(basename ${ODBC_INI})"
+ 			continue
+ 		fi
+ 	fi
+@@ -181,12 +182,12 @@ fi
+ 
+ # get filename of driver
+ echo found driver named \"${DRIVER}\"
+-if [ ! -r "${DRIVER}" ]
++if [ -d "${DRIVER}" -o ! -x "${DRIVER}" ]
+ then
+ 	# not a filename, look it up
+ 	DRIVERNAME=${DRIVER}
+ 	ODBC_INST="${ODBC_DIR}/odbcinst.ini"
+-	echo "${DRIVERNAME} is not a readable file"
++	echo "\"${DRIVERNAME}\" is not an executable file"
+ 	echo "looking for entry named [${DRIVERNAME}] in ${ODBC_INST}"
+ 
+ 	grep "${DRIVERNAME}" ${ODBC_INST} > /dev/null
+@@ -204,31 +205,32 @@ then
+ 				| grep -Ei '^[[:space:]]*driver[[:space:]]*=')
+ 	if [ -z "${DRIVER_LINE}" ]
+ 	then
+-		echo "no driver mentioned for [${DRIVERNAME}] in $(basename ${ODBC_INST})"
++		echo "$(basename $0): no driver mentioned for [${DRIVERNAME}] in $(basename ${ODBC_INST})"
+ 		exit 1
+ 	fi
+ 
++	echo "  found driver line: \"${DRIVER_LINE}\""
+ 	DRIVER=$(echo ${DRIVER_LINE} | awk '{print $3}')
+ 	if [ -z "${DRIVER}" ]
+ 	then
+-		echo "driver line incomplete for [${DRIVERNAME}] in $(basename ${ODBC_INST})"
++		echo "$(basename $0): driver line incomplete for [${DRIVERNAME}] in $(basename ${ODBC_INST})"
+ 		exit 1
+ 	fi
+ 
+-	echo "driver \"${DRIVER}\" found for [${DRIVERNAME}] in $(basename ${ODBC_INST})"
++	echo "  found driver ${DRIVER} for [${DRIVERNAME}] in $(basename ${ODBC_INST})"
+ fi
+ 
+ if [ -z "${DRIVER}" ]
+ then
+-	echo 'error: sorry, failed sanity check: ${DRIVER} is null' 
++	echo $(basename $0): 'error: sorry, failed sanity check: ${DRIVER} is null' 
+ 	exit 1
+ fi
+ 
+-if [ -r "${DRIVER}" ]
++if [ -x "${DRIVER}" ]
+ then
+-	echo "${DRIVER} is a readable file"
++	echo "${DRIVER} is an executable file"
+ else
+-	echo "${DRIVER} is not a readable file"
++	echo "${DRIVER} is not an executable file"
+ 	echo "$(basename $0): error: no driver found for ${DSN}"
+ 	exit 1
+ fi
+@@ -360,6 +362,15 @@ printf "%30s:\t%-30s\n" Address ${ADDRESS}
+ printf "\n";
+ 
+ echo Attempting connection as ${USERNAME} ... 
+-set -x
+-exec isql ${DSN} ${USERNAME} ${PASSWORD} -v
++
++if [ -z "${TDSDUMP}" ]
++then 
++	TDSDUMP_AUTO="/tmp/$(basename $0).dump.$$"
++	export TDSDUMP=${TDSDUMP_AUTO}
++fi
++
++( set -x; isql ${DSN} ${USERNAME} ${PASSWORD} -v ) \
++	|| sed -ne 's/Connecting/FAILED &/p' ${TDSDUMP}
++
++test "${TDSDUMP_AUTO}" && rm -f ${TDSDUMP_AUTO}
+ 
+
+commit 40599b2cc3408010833d3b197d69619b47c15267
+Author: jklowden <jklowden>
+Date:   Wed Jul 15 15:42:49 2009 +0000
+
+    more messages, perhaps somewhat clearer
+
+diff --git a/src/apps/osql b/src/apps/osql
+index d3d1ad7..5d6d73c 100755
+--- a/src/apps/osql
++++ b/src/apps/osql
+@@ -1,5 +1,5 @@
+ #! /bin/sh
+-# $Id: osql,v 1.9 2009/07/14 21:50:27 jklowden Exp $
++# $Id: osql,v 1.10 2009/07/15 15:42:49 jklowden Exp $
+ #
+ # Check odbc.ini, odbcinst, and, optionally, freetds.conf, 
+ # then execute isql (assume it's unixODBC's isql).  
+@@ -46,11 +46,11 @@ ISQL_DIR=$(strings ${ISQL} | grep ^/ | grep -v elf | grep -v '\.so\.' | head -1
+ INI_DIRNAME="/tmp/$(basename $0).$$"
+ exec 3> ${INI_DIRNAME}
+ 
+-# if no hard-coded directory is found in the isql executable, check the libraries. 
++# Check the libraries, too. 
+ if [ -z "${OVER_DIR}" ]
+ then 
+ 	echo "checking shared odbc libraries linked to isql for default directories..."
+-	(echo ${ISQL_DIR}; ldd "${ISQL}" | awk '/[-]lodbc/ {print $3}') \
++	(echo ${ISQL_DIR}; ldd "${ISQL}" | awk '/libodbc\./ {print $3}') \
+ 	| while read L
+ 	  do 
+ 	  	strings "$L" | grep '^/' | grep -v '/lib' \
+@@ -63,6 +63,8 @@ then
+ 				then
+ 					printf $D >&3
+ 					printf "OK"
++				else
++					printf "no"
+ 				fi
+ 				printf "\n"
+ 			fi
+@@ -148,7 +150,7 @@ sed -ne "${SED_CMD}" ${ODBC_INI}
+ # Find the driver in the servername or default section
+ for D in "${DSN}" 'default' 
+ do
+-	echo "looking for driver for DSN [$D]"
++	echo "looking for driver for DSN [$D] in ${ODBC_INI}"
+ 	grep "$D" ${ODBC_INI} > /dev/null
+ 	if [ $? -eq 0 ]
+ 	then
+@@ -256,7 +258,7 @@ if [ $? -eq 0 ] # ODBC-Combined
+ then
+ 	TDS_SERVER=$(echo ${SERVER_LINE} | awk '{print $3}')
+ 	echo 'Using ODBC-Combined strategy'
+-	echo "FreeTDS servername is \"${TDS_SERVER}\" (from ${ODBC_INI})"
++	echo "DSN [${DSN}] has servername \"${TDS_SERVER}\" (from ${ODBC_INI})"
+ 	if [ -z "${TDS_SERVER}" ]
+ 	then
+ 		exit 1
+@@ -273,15 +275,15 @@ then
+ 	
+ 	for F in "${HOME}/.freetds.conf" "${FREETDS_DIR}/freetds.conf"
+ 	do
+-		echo "looking for [${TDS_SERVER}] in $F"
+ 		if [ -r "$F" ]
+ 		then
+-			echo "\"$F\" is a readable file"
++			echo $F is a readable file
+ 		else
+ 			echo cannot read \"$F\"
+ 			continue
+ 		fi
+ 
++		echo "looking for [${TDS_SERVER}] in $F"
+ 		grep "[${TDS_SERVER}]" $F > /dev/null
+ 
+ 		if [ $? -eq 0 ]
+@@ -289,7 +291,7 @@ then
+ 			FREETDS_CONF=$F
+ 			break
+ 		else
+-			echo "[${TDS_SERVER}]" not found in \"$F\"
++			echo "[${TDS_SERVER}]" not found in $F
+ 		fi
+ 	done
+ 	
+@@ -350,16 +352,18 @@ then
+ 	exit 1
+ fi
+ 
+-echo ${HOST} has address ${ADDRESS}
++#cho ${HOST} has address ${ADDRESS}
+ 
+ # Report what we know and exec isql 
+ 
+-printf "\n";
+-printf "%30s:\t%-30s\n" DSN ${DSN}
+-printf "%30s:\t%-30s\n" Driver ${DRIVER}
+-printf "%30s:\t%-30s\n" "Server's hostname" ${HOST}
+-printf "%30s:\t%-30s\n" Address ${ADDRESS}
+-printf "\n";
++printf "\n"
++printf "Configuration looks OK.  Connection details:\n\n"
++printf "%22s:\t%-30s\n"  DSN ${DSN}
++printf "%22s:\t%-30s\n"  odbc.ini "${ODBC_INI}"
++printf "%22s:\t%-30s\n"  Driver ${DRIVER}
++printf "%22s:\t%-30s\n" "Server hostname" ${HOST}
++printf "%22s:\t%-30s\n"  Address ${ADDRESS}
++printf "\n"
+ 
+ echo Attempting connection as ${USERNAME} ... 
+ 
+
+commit 8550b9a09ff4b93d4ce4e59f7b6a3cb24ce2d7ce
+Author: jklowden <jklowden>
+Date:   Thu Jul 16 14:37:09 2009 +0000
+
+    work around mawk limitations
+
+diff --git a/ChangeLog b/ChangeLog
+index f623b3c..9528175 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jul 16 10:36:03 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/apps/osql work around mawk limitations
++
+ Tue Jul 14 17:48:04 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/osql more messages, perhaps somewhat clearer
+ 
+@@ -1683,4 +1686,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2828 2009/07/14 21:50:27 jklowden Exp $
++$Id: ChangeLog,v 1.2829 2009/07/16 14:37:09 jklowden Exp $
+diff --git a/src/apps/osql b/src/apps/osql
+index 5d6d73c..ff706c5 100755
+--- a/src/apps/osql
++++ b/src/apps/osql
+@@ -1,5 +1,5 @@
+ #! /bin/sh
+-# $Id: osql,v 1.10 2009/07/15 15:42:49 jklowden Exp $
++# $Id: osql,v 1.11 2009/07/16 14:37:10 jklowden Exp $
+ #
+ # Check odbc.ini, odbcinst, and, optionally, freetds.conf, 
+ # then execute isql (assume it's unixODBC's isql).  
+@@ -87,9 +87,9 @@ if [ "${OVER_DIR}" ]
+ then
+ 	if [ -d "${ODBC_DIR}" ]
+ 	then
+-		echo "\"${ODBC_DIR}\" (from isql) is a directory, overridden by"
++		echo "\"${ODBC_DIR}\" is a directory, overridden by"
+ 	else 
+-		echo "\"${ODBC_DIR}\" (from isql) is NOT a directory, overridden by"
++		echo "\"${ODBC_DIR}\" is NOT a directory, overridden by"
+ 	fi
+ 	echo "\"${OVER_DIR}\"."
+ 	
+@@ -97,7 +97,7 @@ then
+ 	then
+ 		ODBC_DIR=${OVER_DIR}
+ 	else
+-		echo "$(basename $0): error: \"${OVER_DIR}\" is not a directory (disallowing)"
++		echo "$(basename $0): error: \"${OVER_DIR}\" is not a directory"
+ 		exit 1
+ 	fi
+ fi
+@@ -108,15 +108,15 @@ for F in "${HOME}/.odbc.ini" "${ODBC_DIR}/odbc.ini"
+ do
+ 	if [ ! -d "$(dirname $F)" ]
+ 	then
+-		echo "$(dirname $0): error: $(basename $F) is not a directory!" 
++		echo "warning: $(dirname $F) is not a directory" 
+ 		continue
+ 	fi
+ 	
+ 	if [ -r "$F" ]
+ 	then
+-		echo '	'reading \"$F\"
++		echo "	reading $F"
+ 	else
+-		echo '	'cannot read \"$F\"
++		echo "	cannot read \"$F\""
+ 		continue
+ 	fi
+ 
+@@ -124,11 +124,11 @@ do
+ 
+ 	if [ $? -eq 0 ]
+ 	then
+-		echo "[${DSN}]" found in \"$F\"
++		echo "[${DSN}] found in $F"
+ 		ODBC_INI=$F
+ 		break
+ 	else
+-		echo "[${DSN}]" not found in \"$F\"
++		echo "[${DSN}] not found in $F"
+ 	fi
+ done
+ 
+@@ -164,7 +164,7 @@ do
+ 		fi
+ 
+ 		echo "  found driver line: \"${DRIVER_LINE}\""
+-		DRIVER=$(echo ${DRIVER_LINE} | awk -F '[[:space:]]*=[[:space:]]*' '{print $2}')
++		DRIVER=$(echo ${DRIVER_LINE} | awk -F '=' '{print $2}' | sed 's/[[:space:]][[:space:]]*//g')
+ 		if [ "${DRIVER}" ]
+ 		then
+ 			echo "  driver \"${DRIVER}\" found for [$D] in $(basename ${ODBC_INI})"
+
+commit 10bab12c20639d2d5b03cbae27a356f167933bec
+Author: freddy77 <freddy77>
+Date:   Thu Jul 16 17:34:04 2009 +0000
+
+    better encryption support for mssql
+
+diff --git a/ChangeLog b/ChangeLog
+index 9528175..0b0a0c7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jul 16 19:33:54 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: better encryption support for mssql
++
+ Thu Jul 16 10:36:03 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/osql work around mawk limitations
+ 
+@@ -1686,4 +1689,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2829 2009/07/16 14:37:09 jklowden Exp $
++$Id: ChangeLog,v 1.2830 2009/07/16 17:34:04 freddy77 Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index ccaa74b..0bba84d 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.183 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.184 2009/07/16 17:34:04 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -927,13 +927,6 @@ tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsigned char *cryp
+ static int
+ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ {
+-#if !defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL)
+-	/*
+-	 * In case we do not have SSL enabled do not send pre-login so
+-	 * if server has certificate but no force encryption login success
+-	 */
+-	return tds7_send_login(tds, connection);
+-#else
+ 	int i, len, ret;
+ 	const char *instance_name = tds_dstr_isempty(&connection->instance_name) ? "MSSQLServer" : tds_dstr_cstr(&connection->instance_name);
+ 	int instance_name_len = strlen(instance_name) + 1;
+@@ -987,12 +980,17 @@ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	/* netlib version */
+ 	tds_put_n(tds, IS_TDS90(tds) ? netlib9 : netlib8, 6);
+ 	/* encryption */
+-	tds_put_byte(tds, connection->encryption_level ? 1 : 0);
++#if !defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL)
++	/* not supported */
++	tds_put_byte(tds, 2);
++#else
++	tds_put_byte(tds, connection->encryption_level >= TDS_ENCRYPTION_REQUIRE ? 1 : 0);
++#endif
+ 	/* instance */
+ 	tds_put_n(tds, instance_name, instance_name_len);
+ 	/* pid */
+ 	tds_put_int(tds, getpid());
+-	/* ???? unknown ??? */
++	/* MARS (1 enabled) */
+ 	if (IS_TDS90(tds))
+ 		tds_put_byte(tds, 0);
+ 	if (tds_flush_packet(tds) == TDS_FAIL)
+@@ -1042,7 +1040,10 @@ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 		return tds7_send_login(tds, connection);
+ 	}
+-
++#if !defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL)
++	tdsdump_log(TDS_DBG_ERROR, "server required encryption but support is not compiled in\n");
++	return TDS_FAIL;
++#else
+ 	/*
+ 	 * if server has a certificate it require at least a crypted login
+ 	 * (even if data is not encrypted)
+
+commit a31e777860f1c4a89486c0b736415e69e8040768
+Author: freddy77 <freddy77>
+Date:   Mon Jul 20 17:38:12 2009 +0000
+
+    remove some warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index 0b0a0c7..5753c5e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul 20 19:38:01 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/login.c src/tds/mem.c: remove some warnings
++
+ Thu Jul 16 19:33:54 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/login.c: better encryption support for mssql
+ 
+@@ -1689,4 +1692,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2830 2009/07/16 17:34:04 freddy77 Exp $
++$Id: ChangeLog,v 1.2831 2009/07/20 17:38:12 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 2bfe1cd..a61e13b 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.315 2009/06/12 08:53:49 freddy77 Exp $ */
++/* $Id: tds.h,v 1.316 2009/07/20 17:38:12 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1598,6 +1598,7 @@ int tds7_get_instance_ports(FILE *output, const char *ip_addr);
+ int tds7_get_instance_port(const char *ip_addr, const char *instance);
+ int tds_ssl_init(TDSSOCKET *tds);
+ void tds_ssl_deinit(TDSSOCKET *tds);
++const char *tds_prwsaerror(int erc);
+ 
+ 
+ 
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 0bba84d..a51290c 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.184 2009/07/16 17:34:04 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.185 2009/07/20 17:38:12 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -927,11 +927,14 @@ tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsigned char *cryp
+ static int
+ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ {
+-	int i, len, ret;
++	int i, len;
+ 	const char *instance_name = tds_dstr_isempty(&connection->instance_name) ? "MSSQLServer" : tds_dstr_cstr(&connection->instance_name);
+ 	int instance_name_len = strlen(instance_name) + 1;
+ 	TDS_CHAR crypt_flag;
+ 	unsigned int start_pos = 21;
++#if defined(HAVE_GNUTLS) || defined(HAVE_OPENSSL)
++	int ret;
++#endif
+ 
+ #define START_POS 21
+ #define UI16BE(n) ((n) >> 8), ((n) & 0xffu)
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 3eb1231..33edd1a 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.189 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.190 2009/07/20 17:38:12 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -616,7 +616,6 @@ tds_free_all_results(TDSSOCKET * tds)
+ /*
+  * Return 1 if winsock is initialized, else 0.
+  */
+-const char *tds_prwsaerror( int erc );
+ static int
+ winsock_initialized(void)
+ {
+
+commit 403a42319b711235eccc9dcda216d1d0ad7ac664
+Author: freddy77 <freddy77>
+Date:   Mon Jul 20 17:41:27 2009 +0000
+
+    fix log string
+
+diff --git a/ChangeLog b/ChangeLog
+index 5753c5e..e1f684e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul 20 19:41:20 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix log string
++
+ Mon Jul 20 19:38:01 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/login.c src/tds/mem.c: remove some warnings
+ 
+@@ -1692,4 +1695,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2831 2009/07/20 17:38:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2832 2009/07/20 17:41:27 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index c545ef8..2d1ce61 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.362 2009/06/12 08:53:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.363 2009/07/20 17:41:27 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1581,7 +1581,7 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 	CHECK_TDS_EXTRA(tds);
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
+-	tdsdump_log(TDS_DBG_INFO1, "tds_get_data_info(%p, %p, %d) %s", tds, curcol, is_param, is_param? "[for parameter]" : "");
++	tdsdump_log(TDS_DBG_INFO1, "tds_get_data_info(%p, %p, %d) %s\n", tds, curcol, is_param, is_param? "[for parameter]" : "");
+ 
+ 	curcol->column_namelen = tds_get_string(tds, tds_get_byte(tds), curcol->column_name, sizeof(curcol->column_name) - 1);
+ 	curcol->column_name[curcol->column_namelen] = '\0';
+
+commit f40a79e8abda6b91f874f78a5201dee56834c141
+Author: freddy77 <freddy77>
+Date:   Tue Jul 21 06:40:16 2009 +0000
+
+    cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index e1f684e..dcaff50 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 21 08:39:36 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0022.c: cleanup
++
+ Mon Jul 20 19:41:20 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: fix log string
+ 
+@@ -1695,4 +1698,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2832 2009/07/20 17:41:27 freddy77 Exp $
++$Id: ChangeLog,v 1.2833 2009/07/21 06:40:16 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0022.c b/src/dblib/unittests/t0022.c
+index 0ddc8d4..89f823d 100644
+--- a/src/dblib/unittests/t0022.c
++++ b/src/dblib/unittests/t0022.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0022.c,v 1.27 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: t0022.c,v 1.28 2009/07/21 06:40:16 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -14,7 +14,6 @@ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ int
+ main(int argc, char **argv)
+ {
+-	char cmd[1024];
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+ 	int i;
+@@ -86,8 +85,6 @@ main(int argc, char **argv)
+ 		assert(erc == NO_MORE_ROWS);
+ 	}
+ 
+-	sprintf(cmd, "declare @b int\nexec t0022 @b = @b output\n");
+-	fprintf(stdout, "%s\n", cmd);
+ 	sql_cmd(dbproc);
+ 	dbsqlexec(dbproc);
+ 	add_bread_crumb();
+
+commit d8df3ad45ed412ff2436a0a0111b60f2916b202f
+Author: freddy77 <freddy77>
+Date:   Tue Jul 21 06:44:19 2009 +0000
+
+    add empty column to rpc test
+
+diff --git a/ChangeLog b/ChangeLog
+index dcaff50..6879dc9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 21 08:43:36 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/rpc_ct_param.c: add empty column
++
+ Tue Jul 21 08:39:36 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0022.c: cleanup
+ 
+@@ -1698,4 +1701,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2833 2009/07/21 06:40:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2834 2009/07/21 06:44:19 freddy77 Exp $
+diff --git a/src/ctlib/unittests/rpc_ct_param.c b/src/ctlib/unittests/rpc_ct_param.c
+index a517473..3932f62 100644
+--- a/src/ctlib/unittests/rpc_ct_param.c
++++ b/src/ctlib/unittests/rpc_ct_param.c
+@@ -18,7 +18,7 @@
+ #define MAX(X,Y)      (((X) > (Y)) ? (X) : (Y))
+ #define MIN(X,Y)      (((X) < (Y)) ? (X) : (Y))
+ 
+-static char software_version[] = "$Id: rpc_ct_param.c,v 1.8 2006/12/29 19:00:33 freddy77 Exp $";
++static char software_version[] = "$Id: rpc_ct_param.c,v 1.9 2009/07/21 06:44:19 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
+@@ -91,7 +91,7 @@ main(int argc, char *argv[])
+ 	strcpy(cmdbuf, "create proc sample_rpc (@intparam int, \
+         @sintparam smallint output, @floatparam float output, \
+         @moneyparam money output,  \
+-        @dateparam datetime output, @charparam char(20) output, \
++        @dateparam datetime output, @charparam char(20) output, @empty varchar(20) output, \
+         @binaryparam    binary(20) output) \
+         as ");
+ 
+@@ -102,6 +102,7 @@ main(int argc, char *argv[])
+         select @moneyparam = @moneyparam + convert(money, @intparam) \
+         select @dateparam = getdate() \
+         select @charparam = \'The char parameters\' \
++        select @empty = \'\' \
+         select @binaryparam = @binaryparam \
+         print \'This is the message printed out by sample_rpc.\'");
+ 
+@@ -253,6 +254,22 @@ main(int argc, char *argv[])
+ 		return 1;
+ 	}
+ 
++	strcpy(datafmt.name, "@empty");
++	datafmt.namelen = CS_NULLTERM;
++	datafmt.datatype = CS_VARCHAR_TYPE;
++	datafmt.maxlength = 60;
++	datafmt.status = CS_RETURN;
++	datafmt.locale = NULL;
++
++	/*
++	 * The character string variable is filled in by the RPC so pass NULL
++	 * for the data 0 for data length, and -1 for the indicator arguments.
++	 */
++	if ((ret = ct_param(cmd, &datafmt, NULL, 0, -1)) != CS_SUCCEED) {
++		fprintf(stderr, "ct_param(char) failed");
++		return 1;
++	}
++
+ 	strcpy(datafmt.name, "@binaryparam");
+ 	datafmt.namelen = CS_NULLTERM;
+ 	datafmt.datatype = CS_BINARY_TYPE;
+
+commit 59c87f9e87ef0829497bbffd5d9c0c7a6869ece5
+Author: freddy77 <freddy77>
+Date:   Thu Jul 23 18:22:00 2009 +0000
+
+    support setting charset in freebcp
+
+diff --git a/ChangeLog b/ChangeLog
+index 6879dc9..d4df9b5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jul 23 20:21:50 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/freebcp.c src/apps/freebcp.h:
++	- support setting charset in freebcp
++
+ Tue Jul 21 08:43:36 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/rpc_ct_param.c: add empty column
+ 
+@@ -1701,4 +1705,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2834 2009/07/21 06:44:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2835 2009/07/23 18:22:00 freddy77 Exp $
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 60e03c7..2c75a19 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -46,7 +46,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.50 2008/12/11 12:31:31 freddy77 Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.51 2009/07/23 18:22:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -192,7 +192,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 	 * Get the rest of the arguments 
+ 	 */
+ 	optind = 4; /* start processing options after table, direction, & filename */
+-	while ((ch = getopt(argc, argv, "m:f:e:F:L:b:t:r:U:P:I:S:h:T:A:O:0:ncEdvV")) != -1) {
++	while ((ch = getopt(argc, argv, "m:f:e:F:L:b:t:r:U:P:I:S:h:T:A:O:0:C:ncEdvV")) != -1) {
+ 		switch (ch) {
+ 		case 'v':
+ 		case 'V':
+@@ -287,6 +287,9 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 			pdata->Aflag++;
+ 			pdata->packetsize = atoi(optarg);
+ 			break;
++		case 'C':
++			pdata->charset = strdup(optarg);
++			break;
+ 		case '?':
+ 		default:
+ 			pusage();
+@@ -361,6 +364,8 @@ login_to_database(BCPPARAMDATA * pdata, DBPROCESS ** pdbproc)
+ 	DBSETLUSER(login, pdata->user);
+ 	DBSETLPWD(login, pdata->pass);
+ 	DBSETLAPP(login, "FreeBCP");
++	if (pdata->charset)
++		DBSETLCHARSET(login, pdata->charset);
+ 
+ 	/* if packet size specified, set in login record */
+ 
+@@ -373,7 +378,7 @@ login_to_database(BCPPARAMDATA * pdata, DBPROCESS ** pdbproc)
+ 	BCP_SETL(login, TRUE);
+ 
+ 	/*
+-	 * ** Get a connection to the database.
++	 * Get a connection to the database.
+ 	 */
+ 
+ 	if ((*pdbproc = dbopen(login, pdata->server)) == NULL) {
+diff --git a/src/apps/freebcp.h b/src/apps/freebcp.h
+index 8d77f86..53d1e26 100644
+--- a/src/apps/freebcp.h
++++ b/src/apps/freebcp.h
+@@ -1,4 +1,4 @@
+-static char rcsid_freebcp_h[] = "$Id: freebcp.h,v 1.13 2008/12/11 12:31:31 freddy77 Exp $";
++static char rcsid_freebcp_h[] = "$Id: freebcp.h,v 1.14 2009/07/23 18:22:00 freddy77 Exp $";
+ static void *no_unused_freebcp_h_warn[] = { rcsid_freebcp_h, no_unused_freebcp_h_warn };
+ 
+ enum states
+@@ -51,6 +51,7 @@ typedef struct pd
+ 	char *server;
+ 	char *hint;
+ 	char *options;
++	char *charset;
+ 	int packetsize;
+ 	int mflag;
+ 	int fflag;
+
+commit 34e058e833c3a879104c7f6476a3986f2e42839d
+Author: freddy77 <freddy77>
+Date:   Fri Jul 24 15:06:51 2009 +0000
+
+    fix Sybase LONGCHAR/LONGBINARY
+
+diff --git a/ChangeLog b/ChangeLog
+index d4df9b5..36883c7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jul 24 17:06:23 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix Sybase LONGCHAR/LONGBINARY
++
+ Thu Jul 23 20:21:50 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/freebcp.c src/apps/freebcp.h:
+ 	- support setting charset in freebcp
+@@ -1705,4 +1708,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2835 2009/07/23 18:22:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2836 2009/07/24 15:06:51 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 2d1ce61..05546d9 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.363 2009/07/20 17:41:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.364 2009/07/24 15:06:52 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2124,6 +2124,7 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		}
+ 		break;
+ 	case 5:
++		blob = (TDSBLOB *) curcol->column_data;
+ 		colsize = tds_get_int(tds);
+ 		break;
+ #ifdef ENABLE_DEVELOPING
+
+commit 868df76e68037977e906e41689ecb654e806bf53
+Author: freddy77 <freddy77>
+Date:   Fri Aug 14 13:53:16 2009 +0000
+
+    use pkg-config instead of libgnutls-config if possible
+
+diff --git a/ChangeLog b/ChangeLog
+index 36883c7..16197e5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Aug 14 15:53:01 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac:
++	- use pkg-config instead of libgnutls-config if possible
++
+ Fri Jul 24 17:06:23 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: fix Sybase LONGCHAR/LONGBINARY
+ 
+@@ -1708,4 +1712,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2836 2009/07/24 15:06:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2837 2009/08/14 13:53:16 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index a705473..28bc9d7 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.40 2009/02/27 10:11:42 freddy77 Exp $
++dnl $Id: configure.ac,v 1.41 2009/08/14 13:53:17 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.40 $)
++AC_REVISION($Revision: 1.41 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -105,8 +105,9 @@ fi
+ 
+ # See if we have doxygen installed
+ AC_CHECK_PROG(DOXYGEN,doxygen,doxygen)
+-AC_CHECK_PROG(ODBC_CONFIG,odbc_config,odbc_config)
+ AM_CONDITIONAL(HAVE_DOXYGEN, [test -n "$DOXYGEN"])
++AC_CHECK_PROG(ODBC_CONFIG,odbc_config,odbc_config)
++AC_CHECK_PROG(PKG_CONFIG,pkg-config,pkg-config)
+ 
+ # ------------------------------------------------------------
+ # Check for CVS-only sources.
+@@ -657,8 +658,13 @@ AC_ARG_WITH(gnutls,
+ AS_HELP_STRING([--with-gnutls], [build with TLS support]))
+ if test "$with_gnutls" = "yes"; then
+ 	AC_DEFINE(HAVE_GNUTLS, 1, [Define to 1 if you have GNU tls.])
+-	CPPFLAGS="$CPPFLAGS `libgnutls-config --cflags`"
+-	NETWORK_LIBS="$NETWORK_LIBS `libgnutls-config --libs`"
++	if test "$PKG_CONFIG" != "" && "$PKG_CONFIG" --libs gnutls > /dev/null 2>&1; then
++		CPPFLAGS="$CPPFLAGS `$PKG_CONFIG --cflags gnutls`"
++		NETWORK_LIBS="$NETWORK_LIBS `$PKG_CONFIG --libs gnutls`"
++	else
++		CPPFLAGS="$CPPFLAGS `libgnutls-config --cflags`"
++		NETWORK_LIBS="$NETWORK_LIBS `libgnutls-config --libs`"
++	fi
+ else
+ 	CHECK_OPENSSL
+ fi
+
+commit 24c18c4fd625938dfed7508b402577eb03037407
+Author: freddy77 <freddy77>
+Date:   Mon Aug 17 16:52:31 2009 +0000
+
+    applied David Wood patch for Sybase host process
+
+diff --git a/ChangeLog b/ChangeLog
+index 16197e5..6f32d10 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Aug 17 18:52:20 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: applied David Wood patch for Sybase host process
++
+ Fri Aug 14 15:53:01 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac:
+ 	- use pkg-config instead of libgnutls-config if possible
+@@ -1712,4 +1715,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2837 2009/08/14 13:53:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2838 2009/08/17 16:52:31 freddy77 Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index a51290c..0c64fda 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.185 2009/07/20 17:38:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.186 2009/08/17 16:52:31 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -593,7 +593,8 @@ tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	tds_put_login_string(tds, tds_dstr_cstr(&connection->client_host_name), TDS_MAX_LOGIN_STR_SZ);	/* client host name */
+ 	tds_put_login_string(tds, tds_dstr_cstr(&connection->user_name), TDS_MAX_LOGIN_STR_SZ);	/* account name */
+ 	tds_put_login_string(tds, tds_dstr_cstr(&connection->password), TDS_MAX_LOGIN_STR_SZ);	/* account password */
+-	tds_put_login_string(tds, "37876", TDS_MAX_LOGIN_STR_SZ);	/* host process */
++	sprintf(blockstr, "%d", (int) getpid());
++	tds_put_login_string(tds, blockstr, TDS_MAX_LOGIN_STR_SZ);	/* host process */
+ #ifdef WORDS_BIGENDIAN
+ 	if (tds->emul_little_endian) {
+ 		tds_put_n(tds, le1, 6);
+
+commit d395cfa55e026367b5d18217b2aaf95afc610748
+Author: freddy77 <freddy77>
+Date:   Tue Aug 18 07:26:46 2009 +0000
+
+    remove too strict test
+
+diff --git a/ChangeLog b/ChangeLog
+index 6f32d10..b8e1207 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Aug 18 09:27:03 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/tds_checks.c:
++	- remove too strict test (fails for Sybase LONGCHAR)
++
+ Mon Aug 17 18:52:20 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/login.c: applied David Wood patch for Sybase host process
+ 
+@@ -1715,4 +1719,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2838 2009/08/17 16:52:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2839 2009/08/18 07:26:46 freddy77 Exp $
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index 50f60de..628277d 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.23 2009/06/12 08:53:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.24 2009/08/18 07:26:46 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -203,8 +203,6 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 		varint_ok = 1;
+ 	} else if (column->column_type == SYBVARIANT) {
+ 		assert(column->column_varint_size == 4);
+-	} else {
+-		assert(column->column_varint_size < 3);
+ 	}
+ 	tds.minor_version = 0;
+ 	tds.major_version = 5;
+
+commit a659e3bb2b942e5b7ad700490ad6794ff1470972
+Author: freddy77 <freddy77>
+Date:   Tue Aug 18 11:09:13 2009 +0000
+
+    fix empty string binding for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index b8e1207..0fb54fb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Aug 18 13:09:13 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/query.c: fix empty string binding for Sybase
++
+ Tue Aug 18 09:27:03 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/tds_checks.c:
+ 	- remove too strict test (fails for Sybase LONGCHAR)
+@@ -1719,4 +1722,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2839 2009/08/18 07:26:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2840 2009/08/18 11:09:13 freddy77 Exp $
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 3e07f95..346ddaf 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.237 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.238 2009/08/18 11:09:13 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1481,7 +1481,7 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	s = (char *) src;
+ 
+ 	/* convert string if needed */
+-	if (curcol->char_conv && curcol->char_conv->flags != TDS_ENCODING_MEMCPY) {
++	if (curcol->char_conv && curcol->char_conv->flags != TDS_ENCODING_MEMCPY && colsize) {
+ 		size_t output_size;
+ #if 0
+ 		/* TODO this case should be optimized */
+@@ -1582,6 +1582,14 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		case 1:
+ 			if (is_numeric_type(curcol->column_type))
+ 				colsize = tds_numeric_bytes_per_prec[((TDS_NUMERIC *) src)->precision];
++			if (!colsize) {
++				tds_put_byte(tds, 1);
++				if (is_char_type(curcol->column_type))
++					tds_put_byte(tds, ' ');
++				else
++					tds_put_byte(tds, 0);
++				return TDS_SUCCEED;
++			}
+ 			colsize = MIN(colsize, 255);
+ 			tds_put_byte(tds, colsize);
+ 			break;
+
+commit 0763c772c2198c6eeefd9d62a1bb1912cc8ebc09
+Author: freddy77 <freddy77>
+Date:   Tue Aug 18 12:23:41 2009 +0000
+
+    autobuild script update
+
+diff --git a/ChangeLog b/ChangeLog
+index 0fb54fb..99733bc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Aug 18 14:23:46 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild:
++	- remove 0.64 support
++	- reuse a new function
++
+ Tue Aug 18 13:09:13 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/query.c: fix empty string binding for Sybase
+ 
+@@ -1722,4 +1727,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2840 2009/08/18 11:09:13 freddy77 Exp $
++$Id: ChangeLog,v 1.2841 2009/08/18 12:23:41 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 17b9ab1..f77f187 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -15,8 +15,6 @@ OUTDIR=out
+ # additional flags for Autogen (current version)
+ #FLAGS_ADD=--enable-developing
+ FLAGS_ADD=
+-# additional flags for Autogen (old version)
+-FLAGS_ADD_OLD=
+ WORKDIR=ftds_comp
+ 
+ upload()
+@@ -64,6 +62,14 @@ read_pwd_fields()
+ 	tDB=`grep '^DB=' < PWD | sed 's,^...,,'`
+ }
+ 
++init_log()
++{
++	rm -rf logs
++	mkdir logs
++	touch logs/log.txt
++	ln -f logs/log.txt ../${WORKDIR}_log.txt
++}
++
+ rm ~/freetds.log /tmp/sql.log
+ 
+ ignore=
+@@ -74,12 +80,6 @@ do
+ 	$ignore)
+ 		ignore=
+ 		;;
+-	--previous)
+-		OUTDIR=out0
+-		FTDSDIR=freetds64
+-		FLAGS_ADD="$FLAGS_ADD_OLD"
+-		WORKDIR=ftds_comp_old
+-		;;
+ 	--version)
+ 		ignore=$1
+ 		OUTDIR=out$1
+@@ -129,11 +129,10 @@ cp -f ../PWD PWD
+ read_pwd_fields
+ make clean
+ export LD_LIBRARY_PATH=$PWD/src/odbc/.libs/
+-rm -rf logs
+-mkdir logs
+-./misc/test-auto.sh > logs/log.txt
++init_log
++./misc/test-auto.sh >> logs/log.txt
+ 
+-if test "$OUTDIR" = "out" -a -r doc/doxy.log; then
++if test \( "$OUTDIR" = "out" -o "$OUTDIR" = "out82" \) -a -r doc/doxy.log; then
+ 	fixdoxyres < doc/doxy.log > doc/doxy.html
+ 	upload_file "doxy.html" "doc/doxy.html"
+ 	if test -d doc/doc/freetds-*/reference; then
+@@ -206,40 +205,34 @@ fi
+ # do tests with sybase server
+ cp -f ../PWD.sybase PWD
+ read_pwd_fields
+-rm -rf logs
+-mkdir logs
+-./misc/test-auto.sh --no-build > logs/log.txt
++init_log
++./misc/test-auto.sh --no-build >> logs/log.txt
+ cd logs
+ ../misc/online.pl < log.txt
+ upload "$OUTDIR/test2" '*.html'
+ cd ..
+ 
+ # do tests with sybase 15 server
+-if test "$OUTDIR" != "out0"; then
+-	cp -f ../PWD.sybase15 PWD
+-	read_pwd_fields
+-	rm -rf logs
+-	mkdir logs
+-	./misc/test-auto.sh --no-build > logs/log.txt
+-	cd logs
+-	../misc/online.pl < log.txt
+-	upload "$OUTDIR/test3" '*.html'
+-	cd ..
+-fi
++cp -f ../PWD.sybase15 PWD
++read_pwd_fields
++init_log
++./misc/test-auto.sh --no-build >> logs/log.txt
++cd logs
++../misc/online.pl < log.txt
++upload "$OUTDIR/test3" '*.html'
++cd ..
+ 
+ # test autodiscovery
+-if test "$OUTDIR" != "out0"; then
+-	save_coverage
+-	# using tsql directly with grep do not update coverage informations
+-	echo -e 'select @@version\ngo\nbye' | TDSVER=0.0 ./src/apps/tsql -S "$tSRV" -U "$tUID" -P "$tPWD" > out.txt || true
+-	if grep -q 'Adaptive Server Enterprise' out.txt; then
+-		echo "autodiscovery ok"
+-	else
+-		echo "autodiscovery failed!"
+-		restore_coverage
+-	fi
+-	rm -f out.txt
++save_coverage
++# using tsql directly with grep do not update coverage informations
++echo -e 'select @@version\ngo\nbye' | TDSVER=0.0 ./src/apps/tsql -S "$tSRV" -U "$tUID" -P "$tPWD" > out.txt || true
++if grep -q 'Adaptive Server Enterprise' out.txt; then
++	echo "autodiscovery ok"
++else
++	echo "autodiscovery failed!"
++	restore_coverage
+ fi
++rm -f out.txt
+ 
+ # restore PWD file
+ cp -f ../PWD PWD
+
+commit 33e4633c9001c3488986b04720b08fa53b59a506
+Author: freddy77 <freddy77>
+Date:   Tue Aug 18 15:04:13 2009 +0000
+
+    small fix for empty strings
+
+diff --git a/ChangeLog b/ChangeLog
+index 99733bc..0afc8a0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Aug 18 17:04:42 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c: small fix for empty strings
++
+ Tue Aug 18 14:23:46 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild:
+ 	- remove 0.64 support
+@@ -1727,4 +1730,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2841 2009/08/18 12:23:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2842 2009/08/18 15:04:13 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 2ec1695..e7cc8f8 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.197 2009/06/25 20:51:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.198 2009/08/18 15:04:13 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -3958,7 +3958,7 @@ paraminfoalloc(TDSSOCKET * tds, CS_PARAM * first_param)
+ 						temp_datalen = (*(p->datalen) == CS_UNUSED) ? 0 : *(p->datalen);
+ 					}
+ 
+-					if (temp_datalen && p->value) {
++					if (p->value) {
+ 						temp_value = p->value;
+ 					} else {
+ 						temp_value = NULL;
+
+commit 345dc5c4b95d96c4d1c7e645e1e8974d30ceed50
+Author: freddy77 <freddy77>
+Date:   Tue Aug 18 15:07:11 2009 +0000
+
+    fix silly error
+
+diff --git a/ChangeLog b/ChangeLog
+index 0afc8a0..acee624 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Aug 18 17:07:18 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix silly error
++
+ Tue Aug 18 17:04:42 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c: small fix for empty strings
+ 
+@@ -1730,4 +1733,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2842 2009/08/18 15:04:13 freddy77 Exp $
++$Id: ChangeLog,v 1.2843 2009/08/18 15:07:11 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 05546d9..6f80816 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.364 2009/07/24 15:06:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.365 2009/08/18 15:07:11 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1971,7 +1971,7 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			curcol->column_cur_size = offset;
+ 			return TDS_SUCCEED;
+ 		}
+-		if (*p)
++		if (*p == NULL)
+ 			tmp = (TDS_CHAR*) malloc(chunk_len);
+ 		else
+ 			tmp = (TDS_CHAR*) realloc(*p, offset + chunk_len);
+
+commit 48506c80dea1a9760c62bb68e0ffe6eba5e2e4be
+Author: freddy77 <freddy77>
+Date:   Tue Aug 18 15:11:12 2009 +0000
+
+    improve ms xml support
+
+diff --git a/ChangeLog b/ChangeLog
+index acee624..cc6f105 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Aug 18 17:11:07 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/tds_checks.c src/tds/token.c misc/types.txt:
++	* src/odbc/odbc_util.c:
++	- improve ms xml support
++
+ Tue Aug 18 17:07:18 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: fix silly error
+ 
+@@ -1733,4 +1738,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2843 2009/08/18 15:07:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2844 2009/08/18 15:11:12 freddy77 Exp $
+diff --git a/misc/types.txt b/misc/types.txt
+index b7c8488..537f385 100644
+--- a/misc/types.txt
++++ b/misc/types.txt
+@@ -27,7 +27,7 @@ SYBMONEY	ALL	0	1	0	0	0	0	0	0	8	SYBMONEYN
+ SYBMONEY4	ALL	0	1	0	0	0	0	0	0	4	SYBMONEYN
+ SYBMONEYN	ALL	1	0	1	0	0	0	0	0	-1	0
+ SYBMSUDT	MS	??	0	1	1	??	0	??	??	-1	0
+-SYBMSXML	MS	8	0	1	1	1	0	0	0	-1	0
++SYBMSXML	MS	8	0	1	1	1	0	1	0	-1	0
+ SYBNTEXT	MS	4	0	1	1	1	0	1	0	-1	0
+ SYBNUMERIC	ALL	1	0	1	0	0	1	0	0	-1	0
+ SYBNVARCHAR	MS	??	0	1	1	0	0	1	0	-1	0	# Same as XSYBNVARCHAR ??
+@@ -63,5 +63,5 @@ XSYBVARCHAR	MS	2	0	1	1	0	0	0	1	-1	0
+ # tds_get_conversion_type from nullable to not nullable
+ # tds_get_cardinal_type ??
+ 
+-# $Id: types.txt,v 1.2 2009/05/28 16:23:31 freddy77 Exp $
++# $Id: types.txt,v 1.3 2009/08/18 15:11:12 freddy77 Exp $
+ 
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 2665bda..901cab2 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.108 2009/06/10 18:54:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.109 2009/08/18 15:11:12 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -341,6 +341,8 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBVARIANT:
+ 		break;
+ #endif
++	case SYBMSXML:
++		return SQL_CHAR;
+ 		/*
+ 		 * TODO what should I do with these types ?? 
+ 		 * return other types can cause additional problems
+@@ -361,7 +363,6 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBUNITEXT:
+ 	case SYBXML:
+ 	case SYBMSUDT:
+-	case SYBMSXML:
+ 		break;
+ 	}
+ 	return SQL_UNKNOWN_TYPE;
+@@ -523,6 +524,8 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ 		/* SET_INFO("sql_variant", "", ""); */
+ 		break;
+ #endif
++	case SYBMSXML:
++		SET_INFO("xml", "'", "'");
+ 	}
+ 	SET_INFO("", "", "");
+ #undef SET_INFO
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index 628277d..a3bfa1c 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.24 2009/08/18 07:26:46 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.25 2009/08/18 15:11:12 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -199,7 +199,7 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	if (is_blob_type(column->column_type)) {
+ 		assert(column->column_varint_size >= 4);
+ 	} else if (column->column_varint_size == 8) {
+-		assert(column->on_server.column_type == XSYBVARCHAR || column->on_server.column_type == XSYBVARBINARY || column->on_server.column_type == XSYBNVARCHAR);
++		assert(column->on_server.column_type == XSYBVARCHAR || column->on_server.column_type == XSYBVARBINARY || column->on_server.column_type == XSYBNVARCHAR || column->on_server.column_type == SYBMSXML);
+ 		varint_ok = 1;
+ 	} else if (column->column_type == SYBVARIANT) {
+ 		assert(column->column_varint_size == 4);
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 6f80816..61dcfb0 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.365 2009/08/18 15:07:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.366 2009/08/18 15:11:12 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1432,6 +1432,9 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	curcol->column_timestamp = (curcol->column_type == SYBBINARY && curcol->column_usertype == TDS_UT_TIMESTAMP);
+ 
+ 	switch (curcol->column_varint_size) {
++	case 8:
++		curcol->column_size = 0x7ffffffflu;
++		break;
+ 	case 4:
+ 		curcol->column_size = tds_get_int(tds);
+ 		break;
+@@ -1440,7 +1443,7 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ #ifdef ENABLE_DEVELOPING
+ 		/* under TDS9 this means ?var???(MAX) */
+ 		if (curcol->column_size < 0 && IS_TDS90(tds)) {
+-			curcol->column_size = 0x1ffffffflu;
++			curcol->column_size = 0x3ffffffflu;
+ 			curcol->column_varint_size = 8;
+ 		}
+ #endif
+@@ -1485,7 +1488,8 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			tds_get_byte(tds);
+ 		curcol->table_namelen =
+ 			tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1);
+-	}
++	} else if (IS_TDS90(tds) && curcol->column_type == SYBMSXML)
++		tds_get_byte(tds);
+ 
+ 	/*
+ 	 * under 7.0 lengths are number of characters not
+
+commit 183c6e07c836112c136a2a29b7fced7af978fbdb
+Author: freddy77 <freddy77>
+Date:   Wed Aug 19 09:50:37 2009 +0000
+
+    small improve
+
+diff --git a/ChangeLog b/ChangeLog
+index cc6f105..034e192 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Aug 19 11:51:14 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: small improve
++
+ Tue Aug 18 17:11:07 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/tds_checks.c src/tds/token.c misc/types.txt:
+ 	* src/odbc/odbc_util.c:
+@@ -1738,4 +1741,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2844 2009/08/18 15:11:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2845 2009/08/19 09:50:37 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index c9bd4ee..b3e8270 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.350 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.351 2009/08/19 09:50:37 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4551,7 +4551,7 @@ RETCODE
+ dbsqlok(DBPROCESS * dbproc)
+ {
+ 	TDSSOCKET *tds;
+-	int done = 0, done_flags;
++	int done_flags;
+ 	TDS_INT result_type;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsqlok(%p)\n", dbproc);
+@@ -4573,7 +4573,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 	 * We want to skip any messages which are not processable. 
+ 	 * We're looking for a result token or a done token.
+          */
+-	while (!done) {
++	for (;;) {
+ 		/* 
+ 		 * If we hit an end token -- e.g. if the command
+ 		 * submitted returned no data (like an insert) -- then
+
+commit db3c687f1a5c60d634be0440047fcf1ba2573f36
+Author: freddy77 <freddy77>
+Date:   Wed Aug 19 11:47:52 2009 +0000
+
+    handle variant data
+
+diff --git a/ChangeLog b/ChangeLog
+index 034e192..752091f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Aug 19 13:48:28 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c src/tds/token.c: handle variant data
++
+ Wed Aug 19 11:51:14 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: small improve
+ 
+@@ -1741,4 +1744,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2845 2009/08/19 09:50:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2846 2009/08/19 11:47:52 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 39ea5eb..3e957dd 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.28 2009/06/12 08:53:49 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.29 2009/08/19 11:47:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -180,15 +180,13 @@ main(int argc, char *argv[])
+ 	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_WCHAR, "23 2006-06-09 11:22:44.000");
+ 	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_WCHAR, "19 2006-06-12 22:37:00");
+ 
+-#ifdef ENABLE_DEVELOPING
+ 	if (db_is_microsoft() && db_version_int() >= 0x08000000u) {
+ 		Test("SQL_VARIANT", "CAST('123' AS INT)", SQL_C_CHAR, "3 123");
+ 		Test("SQL_VARIANT", "CAST('ciao' AS VARCHAR(10))", SQL_C_CHAR, "4 ciao");
+ 		Test("SQL_VARIANT", "CAST('321' AS VARBINARY(10))", SQL_C_CHAR, "6 333231");
+ 		Test("SQL_VARIANT", "CAST('-123.4' AS FLOAT)", SQL_C_CHAR, "6 -123.4");
+-		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "6 -123.4");
++		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "7 -123.40");
+ 	}
+-#endif
+ 
+ 	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
+ 		Test("VARCHAR(MAX)", "goodbye!", SQL_C_CHAR, "8 goodbye!");
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 61dcfb0..39f4b66 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.366 2009/08/18 15:11:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.367 2009/08/19 11:47:52 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1992,7 +1992,6 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ static int
+ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ {
+-#ifdef ENABLE_DEVELOPING
+ 	int colsize = tds_get_int(tds), varint;
+ 	TDS_UCHAR type, info_len;
+ 	TDSVARIANT *v;
+@@ -2026,13 +2025,14 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			TDS_ZERO_FREE(v->data);
+ 		v->data_len = sizeof(TDS_NUMERIC);
+ 		num = (TDS_NUMERIC*) calloc(1, sizeof(TDS_NUMERIC));
+-		v->data = num;
++		v->data = (TDS_CHAR *) num;
+ 		num->precision = tds_get_byte(tds);
+ 		num->scale     = tds_get_byte(tds);
+ 		colsize -= 2;
+ 		/* FIXME check prec/scale, don't let server crash us */
+ 		if (colsize > sizeof(num->array))
+ 			goto error_type;
++		curcol->column_cur_size = colsize;
+ 		tds_get_n(tds, num->array, colsize);
+ 		if (IS_TDS7_PLUS(tds))
+ 			tds_swap_numeric(num);
+@@ -2068,12 +2068,6 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ error_type:
+ 	tds_get_n(tds, NULL, colsize);
+ 	return TDS_FAIL;
+-#else
+-	int colsize = tds_get_int(tds);
+-	tds_get_n(tds, NULL, colsize);
+-	curcol->column_cur_size = -1;
+-	return TDS_SUCCEED;
+-#endif
+ }
+ 
+ /**
+
+commit f50b6823ea28f4fc00d899988bc3d73fdf2a7a69
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 15:14:18 2009 +0000
+
+    fix describecol test
+
+diff --git a/ChangeLog b/ChangeLog
+index 752091f..932a125 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 20 17:14:29 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix describecol test
++
+ Wed Aug 19 13:48:28 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c src/tds/token.c: handle variant data
+ 
+@@ -1744,4 +1747,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2846 2009/08/19 11:47:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2847 2009/08/20 15:14:18 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index e7ba3a6..4c55639 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.512 2009/06/10 18:54:38 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.513 2009/08/20 15:14:19 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -1891,6 +1891,8 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 		break;
+ #if SQL_COLUMN_TYPE != SQL_DESC_CONCISE_TYPE
+ 	case SQL_COLUMN_TYPE:
++#endif
++	case SQL_DESC_CONCISE_TYPE:
+ 		/* special case, get ODBC 2 type, not ODBC 3 SQL_DESC_CONCISE_TYPE (different for datetime) */
+ 		if (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 			IOUT(SQLSMALLINT, drec->sql_desc_concise_type);
+@@ -1915,11 +1917,6 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 			IOUT(SQLSMALLINT, type);
+ 		}
+ 		break;
+-#else
+-	case SQL_DESC_CONCISE_TYPE:
+-		IOUT(SQLSMALLINT, drec->sql_desc_concise_type);
+-		break;
+-#endif
+ 	case SQL_DESC_DISPLAY_SIZE:
+ 		IOUT(SQLLEN, drec->sql_desc_display_size);
+ 		break;
+
+commit d7da3378e7997a3596dbd79985e7271e1db7050c
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 17:49:07 2009 +0000
+
+    use iconv on variant
+
+diff --git a/ChangeLog b/ChangeLog
+index 932a125..3530cbe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Aug 20 19:48:56 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/data.c src/tds/token.c src/tds/types.pl:
++	- use iconv on variant
++
+ Thu Aug 20 17:14:29 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix describecol test
+ 
+@@ -1747,4 +1751,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2847 2009/08/20 15:14:18 freddy77 Exp $
++$Id: ChangeLog,v 1.2848 2009/08/20 17:49:07 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index a61e13b..974f0d4 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.316 2009/07/20 17:38:12 freddy77 Exp $ */
++/* $Id: tds.h,v 1.317 2009/08/20 17:49:07 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1429,6 +1429,7 @@ BCPCOLDATA * tds_alloc_bcp_column_data(int column_size);
+ unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsigned char *crypt_pass);
+ TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, const char *id);
+ /*@observer@*/ const char *tds_prtype(int token);
++int tds_get_varint_size(TDSSOCKET * tds, int datatype);
+ 
+ 
+ 
+diff --git a/src/tds/data.c b/src/tds/data.c
+index 1455667..f9d08c9 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,11 +35,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.21 2009/06/09 06:50:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: data.c,v 1.22 2009/08/20 17:49:07 freddy77 Exp $");
+ 
+ #if !ENABLE_EXTRA_CHECKS
+ static int tds_get_cardinal_type(int datatype);
+-static int tds_get_varint_size(TDSSOCKET * tds, int datatype);
+ #endif
+ 
+ /**
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 39f4b66..c015b96 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.367 2009/08/19 11:47:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.368 2009/08/20 17:49:07 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2015,6 +2015,9 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		tds_get_n(tds, v->collation, sizeof(v->collation));
+ 		colsize -= sizeof(v->collation);
+ 		info_len -= sizeof(v->collation);
++		curcol->char_conv =
++			tds_iconv_from_collate(tds, v->collation[4],
++					       v->collation[1] * 256 + v->collation[0]);
+ 	}
+ 	/* special case for numeric */
+ 	if (is_numeric_type(type)) {
+@@ -2058,11 +2061,22 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	curcol->column_cur_size = colsize;
+ 	if (v->data)
+ 		TDS_ZERO_FREE(v->data);
+-	v->data_len = colsize;
+ 	if (colsize) {
+-		v->data = (TDS_CHAR*) malloc(colsize);
+-		tds_get_n(tds, v->data, colsize);
++		if (USE_ICONV && curcol->char_conv) {
++			curcol->column_cur_size = colsize = determine_adjusted_size(curcol->char_conv, colsize);
++			v->data = (TDS_CHAR*) malloc(colsize);
++			if (!v->data)
++				return TDS_FAIL;
++			if (tds_get_char_data(tds, (char *) v->data, colsize, curcol) == TDS_FAIL)
++				return TDS_FAIL;
++		} else {
++			v->data = (TDS_CHAR*) malloc(colsize);
++			if (!v->data)
++				return TDS_FAIL;
++			tds_get_n(tds, v->data, colsize);
++		}
+ 	}
++	v->data_len = colsize;
+ 	return TDS_SUCCEED;
+ 
+ error_type:
+diff --git a/src/tds/types.pl b/src/tds/types.pl
+index a4cd760..bcdf973 100755
+--- a/src/tds/types.pl
++++ b/src/tds/types.pl
+@@ -31,7 +31,7 @@ while ($line = readLine()) {
+ 	$types{$type{'name'}} = \%type;
+ }
+ 
+-my $id = '$Id: types.pl,v 1.1 2008/09/17 12:16:09 freddy77 Exp $';
++my $id = '$Id: types.pl,v 1.2 2009/08/20 17:49:07 freddy77 Exp $';
+ $id =~ s/\$Id/CVS Id/;
+ $id =~ s/\$\s*$//;
+ print qq|/*
+@@ -78,9 +78,6 @@ print q|/**
+  * tds_get_varint_size() returns the size of a variable length integer
+  * returned in a TDS 7.0 result string
+  */
+-#if !ENABLE_EXTRA_CHECKS
+-static
+-#endif
+ int
+ tds_get_varint_size(TDSSOCKET * tds, int datatype)
+ {
+
+commit 3ce55109c3797e4b21410b0a3d089a336458d864
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 17:50:05 2009 +0000
+
+    small tds_get_n improve
+
+diff --git a/ChangeLog b/ChangeLog
+index 3530cbe..d652de6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 20 19:49:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/read.c: small tds_get_n improve
++
+ Thu Aug 20 19:48:56 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/data.c src/tds/token.c src/tds/types.pl:
+ 	- use iconv on variant
+@@ -1751,4 +1754,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2848 2009/08/20 17:49:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2849 2009/08/20 17:50:05 freddy77 Exp $
+diff --git a/src/tds/read.c b/src/tds/read.c
+index d655cf4..2a38f51 100644
+--- a/src/tds/read.c
++++ b/src/tds/read.c
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: read.c,v 1.110 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: read.c,v 1.111 2009/08/20 17:50:05 freddy77 Exp $");
+ 
+ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ 			    size_t * wire_size, char **outbuf, size_t * outbytesleft);
+@@ -289,12 +289,13 @@ tds_get_char_data(TDSSOCKET * tds, char *row_buffer, size_t wire_size, TDSCOLUMN
+ void *
+ tds_get_n(TDSSOCKET * tds, void *dest, int need)
+ {
+-	int have;
+-
+ 	assert(need >= 0);
+ 
+-	have = (tds->in_len - tds->in_pos);
+-	while (need > have) {
++	for (;;) {
++		int have = tds->in_len - tds->in_pos;
++
++		if (need <= have)
++			break;
+ 		/* We need more than is in the buffer, copy what is there */
+ 		if (dest != NULL) {
+ 			memcpy((char *) dest, tds->in_buf + tds->in_pos, have);
+@@ -303,7 +304,6 @@ tds_get_n(TDSSOCKET * tds, void *dest, int need)
+ 		need -= have;
+ 		if (tds_read_packet(tds) < 0)
+ 			return NULL;
+-		have = tds->in_len - tds->in_pos;
+ 	}
+ 	if (need > 0) {
+ 		/* get the remainder if there is any */
+
+commit b4cfd50708535c0f9da4538cd6944d4cf4656924
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 17:51:15 2009 +0000
+
+    enable tds 7.2 support for odbc
+
+diff --git a/ChangeLog b/ChangeLog
+index d652de6..09d23d9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Aug 20 19:51:03 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c src/tds/login.c src/tds/query.c src/tds/token.c:
++	- enable tds 7.2 support for odbc
++
+ Thu Aug 20 19:49:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/read.c: small tds_get_n improve
+ 
+@@ -1754,4 +1758,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2849 2009/08/20 17:50:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2850 2009/08/20 17:51:15 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 8baab11..f1ba176 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.143 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.144 2009/08/20 17:51:15 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -717,12 +717,10 @@ tds_config_verstr(const char *tdsver, TDSCONNECTION * connection)
+ 		version = 0x50;
+ 	else if (!strcmp(tdsver, "70") || !strcmp(tdsver, "7.0"))
+ 		version = 0x70;
+-	else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0"))
++	else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0") || !strcmp(tdsver, "7.1"))
+ 		version = 0x80;
+-#ifdef ENABLE_DEVELOPING
+-	else if (!strcmp(tdsver, "90") || !strcmp(tdsver, "9.0"))
++	else if (!strcmp(tdsver, "7.2"))
+ 		version = 0x90;
+-#endif
+ 	else if (!strcmp(tdsver, "0.0"))
+ 		version = 0;
+ 	else 
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 0c64fda..3f5de67 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.186 2009/08/17 16:52:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.187 2009/08/20 17:51:15 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -337,12 +337,17 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		TDS_TINYINT major_version;
+ 		TDS_TINYINT minor_version;
+ 	} versions[] =
+-		{ { 8, 0 }
++		{ { 9, 0 }
++		, { 8, 0 }
+ 		, { 7, 0 }
+ 		, { 5, 0 }
+ 		, { 4, 2 }
+ 		};
+ 
++	/* disable tds9 if iconv wanted, currently not supported */
++	if (connection->major_version == 9 && tds->use_iconv)
++		connection->major_version = 8;
++
+ 	if (connection->major_version == 0) {
+ 		unsigned int i;
+ 		TDSSAVECONTEXT save_ctx;
+@@ -358,7 +363,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		tds->env_chg_func = tds_save_env;
+ 		mod_ctx->err_handler = NULL;
+ 
+-		for (i=0; i < TDS_VECTOR_SIZE(versions); ++i) {
++		for (i=tds->use_iconv ? 1: 0; i < TDS_VECTOR_SIZE(versions); ++i) {
+ 			connection->major_version = versions[i].major_version;
+ 			connection->minor_version = versions[i].minor_version;
+ 			reset_save_context(&save_ctx);
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 346ddaf..41d2b0f 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.238 2009/08/18 11:09:13 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.239 2009/08/20 17:51:15 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -234,7 +234,6 @@ tds5_fix_dot_query(const char *query, size_t *query_len, TDSPARAMINFO * params)
+ 	return out;
+ }
+ 
+-#ifdef ENABLE_DEVELOPING
+ static const TDS_UCHAR tds9_query_start[] = {
+ 	/* total length */
+ 	0x16, 0, 0, 0,
+@@ -261,9 +260,6 @@ tds_start_query(TDSSOCKET *tds)
+ 	tds_put_n(tds, tds->tds9_transaction, 8);
+ 	tds_put_n(tds, tds9_query_start + 10 + 8, 4);
+ }
+-#else
+-#define START_QUERY do { ; } while(0)
+-#endif
+ 
+ /**
+  * tds_submit_query_params() sends a language string to the database server for
+diff --git a/src/tds/token.c b/src/tds/token.c
+index c015b96..021601f 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.368 2009/08/20 17:49:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.369 2009/08/20 17:51:15 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1440,13 +1440,11 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		break;
+ 	case 2:
+ 		curcol->column_size = tds_get_smallint(tds);
+-#ifdef ENABLE_DEVELOPING
+ 		/* under TDS9 this means ?var???(MAX) */
+ 		if (curcol->column_size < 0 && IS_TDS90(tds)) {
+ 			curcol->column_size = 0x3ffffffflu;
+ 			curcol->column_varint_size = 8;
+ 		}
+-#endif
+ 		break;
+ 	case 1:
+ 		curcol->column_size = tds_get_byte(tds);
+@@ -1949,7 +1947,6 @@ tds_process_compute(TDSSOCKET * tds, TDS_INT * pcomputeid)
+ 	return TDS_SUCCEED;
+ }
+ 
+-#ifdef ENABLE_DEVELOPING
+ static int
+ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ {
+@@ -1987,7 +1984,6 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	}
+ 	return TDS_SUCCEED;
+ }
+-#endif
+ 
+ static int
+ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+@@ -2139,10 +2135,8 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		blob = (TDSBLOB *) curcol->column_data;
+ 		colsize = tds_get_int(tds);
+ 		break;
+-#ifdef ENABLE_DEVELOPING
+ 	case 8:
+ 		return tds9_get_varmax(tds, curcol);
+-#endif
+ 	case 2:
+ 		colsize = tds_get_smallint(tds);
+ 		break;
+
+commit f24a7ca7be01d5f2c57e1363933b942172af6f1a
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 17:51:46 2009 +0000
+
+    small fix for ms xml type
+
+diff --git a/ChangeLog b/ChangeLog
+index 09d23d9..ed5b821 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 20 19:51:40 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: small fix for ms xml type
++
+ Thu Aug 20 19:51:03 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c src/tds/login.c src/tds/query.c src/tds/token.c:
+ 	- enable tds 7.2 support for odbc
+@@ -1758,4 +1761,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2850 2009/08/20 17:51:15 freddy77 Exp $
++$Id: ChangeLog,v 1.2851 2009/08/20 17:51:46 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 974f0d4..9c7b094 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.317 2009/08/20 17:49:07 freddy77 Exp $ */
++/* $Id: tds.h,v 1.318 2009/08/20 17:51:46 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -758,7 +758,7 @@ typedef enum tds_encryption_level {
+ /* large type means it has a two byte size field */
+ /* define is_large_type(x) (x>128) */
+ #define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL)
+-#define is_unicode_type(x) (x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
++#define is_unicode_type(x) (x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT || x==SYBMSXML)
+ #define is_collate_type(x) (x==XSYBVARCHAR || x==XSYBCHAR || x==SYBTEXT || x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
+ #define is_ascii_type(x) ( x==XSYBCHAR || x==XSYBVARCHAR || x==SYBTEXT || x==SYBCHAR || x==SYBVARCHAR)
+ #define is_char_type(x) (is_unicode_type(x) || is_ascii_type(x))
+
+commit 7eba12bf26487ef242fcd833bee6d81a1f5e3bb3
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 17:53:06 2009 +0000
+
+    pass raw collation structure to tds_iconv_from_collate
+
+diff --git a/ChangeLog b/ChangeLog
+index ed5b821..2269500 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Aug 20 19:52:58 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/iconv.c src/tds/token.c:
++	- pass raw collation structure to tds_iconv_from_collate
++
+ Thu Aug 20 19:51:40 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h: small fix for ms xml type
+ 
+@@ -1761,4 +1765,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2851 2009/08/20 17:51:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2852 2009/08/20 17:53:06 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 9c7b094..a85315c 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.318 2009/08/20 17:51:46 freddy77 Exp $ */
++/* $Id: tds.h,v 1.319 2009/08/20 17:53:06 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1440,7 +1440,7 @@ void tds_srv_charset_changed(TDSSOCKET * tds, const char *charset);
+ void tds7_srv_charset_changed(TDSSOCKET * tds, int sql_collate, int lcid);
+ int tds_iconv_alloc(TDSSOCKET * tds);
+ void tds_iconv_free(TDSSOCKET * tds);
+-TDSICONV *tds_iconv_from_collate(TDSSOCKET * tds, int sql_collate, int lcid);
++TDSICONV *tds_iconv_from_collate(TDSSOCKET * tds, TDS_UCHAR collate[5]);
+ 
+ /* threadsafe.c */
+ char *tds_timestamp_str(char *str, int maxlen);
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 42645d7..cfe6a4e 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.139 2009/06/17 17:07:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.140 2009/08/20 17:53:06 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -1470,8 +1470,10 @@ collate2charset(int sql_collate, int lcid)
+  * Get iconv information from a LCID (to support different column encoding under MSSQL2K)
+  */
+ TDSICONV *
+-tds_iconv_from_collate(TDSSOCKET * tds, int sql_collate, int lcid)
++tds_iconv_from_collate(TDSSOCKET * tds, TDS_UCHAR collate[5])
+ {
++	const int sql_collate = collate[4];
++	const int lcid = collate[1] * 256 + collate[0];
+ 	const char *charset = collate2charset(sql_collate, lcid);
+ 
+ #if ENABLE_EXTRA_CHECKS
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 021601f..3cb854b 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.369 2009/08/20 17:51:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.370 2009/08/20 17:53:06 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1472,8 +1472,7 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		 */
+ 		tds_get_n(tds, curcol->column_collation, 5);
+ 		curcol->char_conv =
+-			tds_iconv_from_collate(tds, curcol->column_collation[4],
+-					       curcol->column_collation[1] * 256 + curcol->column_collation[0]);
++			tds_iconv_from_collate(tds, curcol->column_collation);
+ 	}
+ 
+ 	/* NOTE adjustements must be done after curcol->char_conv initialization */
+@@ -1681,8 +1680,7 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 	if (IS_TDS8_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) {
+ 		tds_get_n(tds, curcol->column_collation, 5);
+ 		curcol->char_conv =
+-			tds_iconv_from_collate(tds, curcol->column_collation[4],
+-					       curcol->column_collation[1] * 256 + curcol->column_collation[0]);
++			tds_iconv_from_collate(tds, curcol->column_collation);
+ 	}
+ 
+ 	/* Adjust column size according to client's encoding */
+@@ -2012,8 +2010,7 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		colsize -= sizeof(v->collation);
+ 		info_len -= sizeof(v->collation);
+ 		curcol->char_conv =
+-			tds_iconv_from_collate(tds, v->collation[4],
+-					       v->collation[1] * 256 + v->collation[0]);
++			tds_iconv_from_collate(tds, v->collation);
+ 	}
+ 	/* special case for numeric */
+ 	if (is_numeric_type(type)) {
+
+commit 7d3ae877c99f99e2a6eebb9acde800a70aa703b8
+Author: freddy77 <freddy77>
+Date:   Thu Aug 20 18:59:29 2009 +0000
+
+    fix N(VAR)CHAR inside variant
+
+diff --git a/ChangeLog b/ChangeLog
+index 2269500..d7775e9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Aug 20 20:59:22 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/odbc/unittests/data.c:
++	* src/tds/token.c:
++	- fix N(VAR)CHAR inside variant
++
+ Thu Aug 20 19:52:58 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/iconv.c src/tds/token.c:
+ 	- pass raw collation structure to tds_iconv_from_collate
+@@ -1765,4 +1770,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2852 2009/08/20 17:53:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2853 2009/08/20 18:59:29 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 750d3b5..8160f4a 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.64 2009/06/12 08:53:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.65 2009/08/20 18:59:29 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -154,8 +154,11 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 	assert(desttype != SQL_C_DEFAULT);
+ 
+ 	if (curcol) {
+-		if (is_blob_col(curcol) && curcol->column_type != SYBVARIANT)
++		if (is_blob_col(curcol)) {
++			if (curcol->column_type == SYBVARIANT)
++				srctype = ((TDSVARIANT *) src)->type;
+ 			src = ((TDSBLOB *) src)->textvalue;
++		}
+ 		if (is_variable_type(curcol->column_type)) {
+ 			src += curcol->column_text_sqlgetdatapos;
+ 			srclen -= curcol->column_text_sqlgetdatapos;
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 3e957dd..d811938 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.29 2009/08/19 11:47:52 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.30 2009/08/20 18:59:29 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -182,7 +182,10 @@ main(int argc, char *argv[])
+ 
+ 	if (db_is_microsoft() && db_version_int() >= 0x08000000u) {
+ 		Test("SQL_VARIANT", "CAST('123' AS INT)", SQL_C_CHAR, "3 123");
++		Test("SQL_VARIANT", "CAST('hello' AS CHAR(6))", SQL_C_CHAR, "6 hello ");
+ 		Test("SQL_VARIANT", "CAST('ciao' AS VARCHAR(10))", SQL_C_CHAR, "4 ciao");
++		Test("SQL_VARIANT", "CAST('foo' AS NVARCHAR(10))", SQL_C_CHAR, "3 foo");
++		Test("SQL_VARIANT", "CAST('Super' AS NCHAR(8))", SQL_C_CHAR, "8 Super   ");
+ 		Test("SQL_VARIANT", "CAST('321' AS VARBINARY(10))", SQL_C_CHAR, "6 333231");
+ 		Test("SQL_VARIANT", "CAST('-123.4' AS FLOAT)", SQL_C_CHAR, "6 -123.4");
+ 		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "7 -123.40");
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 3cb854b..680b740 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.370 2009/08/20 17:53:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.371 2009/08/20 18:59:29 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2009,8 +2009,8 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		tds_get_n(tds, v->collation, sizeof(v->collation));
+ 		colsize -= sizeof(v->collation);
+ 		info_len -= sizeof(v->collation);
+-		curcol->char_conv =
+-			tds_iconv_from_collate(tds, v->collation);
++		curcol->char_conv = is_unicode_type(type) ? 
++			tds->char_convs[client2ucs2] : tds_iconv_from_collate(tds, v->collation);
+ 	}
+ 	/* special case for numeric */
+ 	if (is_numeric_type(type)) {
+
+commit e25889cc0f06909ddbfac96a8248a4f90491bd21
+Author: freddy77 <freddy77>
+Date:   Fri Aug 21 09:58:30 2009 +0000
+
+    small optimization for method constant
+
+diff --git a/ChangeLog b/ChangeLog
+index d7775e9..73819bd 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Aug 21 11:57:54 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: small optimization for method constant
++
+ Thu Aug 20 20:59:22 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/odbc/unittests/data.c:
+ 	* src/tds/token.c:
+@@ -1770,4 +1773,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2853 2009/08/20 18:59:29 freddy77 Exp $
++$Id: ChangeLog,v 1.2854 2009/08/21 09:58:30 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index caa0626..ce1d21f 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,7 +103,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.91 2009/03/27 09:22:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.92 2009/08/21 09:58:30 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL)
+@@ -347,11 +347,12 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ {
+ 	int rc, seconds;
+ 	unsigned int poll_seconds;
+-	const char *method = "poll(2)";
+-#if !USE_POLL
++#if USE_POLL
++	static const char method[] = "poll(2)";
++#else
++	static const char method[] = "select(2)";
+ 	fd_set fds[3];
+ 	fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
+-	method = "select(2)";
+ #endif
+ 
+ 	assert(tds != NULL);
+
+commit 299d7be56ccb3dcc20bd495a7a93182cf34c427a
+Author: freddy77 <freddy77>
+Date:   Fri Aug 21 10:00:07 2009 +0000
+
+    fix a problem with Interix (cfr http://debian-interix.net/bugs/libs/)
+
+diff --git a/ChangeLog b/ChangeLog
+index 73819bd..b0fcae9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Aug 21 11:59:39 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- fix a problem with Interix (cfr
++	  http://debian-interix.net/bugs/libs/)
++
+ Fri Aug 21 11:57:54 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: small optimization for method constant
+ 
+@@ -1773,4 +1778,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2854 2009/08/21 09:58:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2855 2009/08/21 10:00:07 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index ce1d21f..777dbf3 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -103,10 +103,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.92 2009/08/21 09:58:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.93 2009/08/21 10:00:07 freddy77 Exp $");
+ 
+ #undef USE_POLL
+-#if defined(HAVE_POLL_H) && defined(HAVE_POLL)
++#if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+ # define USE_POLL 1
+ # define TDSSELREAD  POLLIN
+ # define TDSSELWRITE POLLOUT
+
+commit d7d1d41119ab3951452af606850d54d3558e05f1
+Author: freddy77 <freddy77>
+Date:   Fri Aug 21 10:01:52 2009 +0000
+
+    make ssl more threadsafe using pthread in libgcrypt if possible
+
+diff --git a/ChangeLog b/ChangeLog
+index b0fcae9..008665a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Aug 21 12:01:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c:
++	- make ssl more threadsafe using pthread in libgcrypt if possible
++
+ Fri Aug 21 11:59:39 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c:
+ 	- fix a problem with Interix (cfr
+@@ -1778,4 +1782,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2855 2009/08/21 10:00:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2856 2009/08/21 10:01:52 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 777dbf3..394ac99 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -94,6 +94,10 @@
+ #include <assert.h>
+ 
+ #ifdef HAVE_GNUTLS
++#if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX)
++#include "tdsthread.h"
++#include <gcrypt.h>
++#endif
+ #include <gnutls/gnutls.h>
+ #elif defined(HAVE_OPENSSL)
+ #include <openssl/ssl.h>
+@@ -103,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.93 2009/08/21 10:00:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.94 2009/08/21 10:01:52 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -1355,6 +1359,13 @@ tds_tls_deinit(void)
+ }
+ #endif
+ 
++#if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX)
++GCRY_THREAD_OPTION_PTHREAD_IMPL;
++#define tds_gcry_init() gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread)
++#else
++#define tds_gcry_init() do {} while(0)
++#endif
++
+ int
+ tds_ssl_init(TDSSOCKET *tds)
+ {
+@@ -1388,8 +1399,10 @@ tds_ssl_init(TDSSOCKET *tds)
+ 
+ 	/* FIXME place somewhere else, deinit at end */
+ 	ret = 0;
+-	if (!tls_initialized)
++	if (!tls_initialized) {
++		tds_gcry_init();
+ 		ret = gnutls_global_init();
++	}
+ 	if (ret == 0) {
+ 		tls_initialized = 1;
+ 
+
+commit 8ef35a37143669ee148cc655f3cc52bab0ec7158
+Author: freddy77 <freddy77>
+Date:   Fri Aug 21 10:11:19 2009 +0000
+
+    fix variant type for data converted to client encoding
+
+diff --git a/ChangeLog b/ChangeLog
+index 008665a..d029572 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Aug 21 12:10:57 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/data.c src/tds/token.c:
++	- fix variant type for data converted to client encoding
++
+ Fri Aug 21 12:01:24 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c:
+ 	- make ssl more threadsafe using pthread in libgcrypt if possible
+@@ -1782,4 +1786,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2856 2009/08/21 10:01:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2857 2009/08/21 10:11:19 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index a85315c..744ae2e 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.319 2009/08/20 17:53:06 freddy77 Exp $ */
++/* $Id: tds.h,v 1.320 2009/08/21 10:11:19 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1430,6 +1430,7 @@ unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsi
+ TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, const char *id);
+ /*@observer@*/ const char *tds_prtype(int token);
+ int tds_get_varint_size(TDSSOCKET * tds, int datatype);
++int tds_get_cardinal_type(int datatype);
+ 
+ 
+ 
+diff --git a/src/tds/data.c b/src/tds/data.c
+index f9d08c9..c8a4767 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,11 +35,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.22 2009/08/20 17:49:07 freddy77 Exp $");
+-
+-#if !ENABLE_EXTRA_CHECKS
+-static int tds_get_cardinal_type(int datatype);
+-#endif
++TDS_RCSID(var, "$Id: data.c,v 1.23 2009/08/21 10:11:20 freddy77 Exp $");
+ 
+ /**
+  * Set type of column initializing all dependency 
+@@ -137,9 +133,6 @@ tds_set_param_type(TDSSOCKET * tds, TDSCOLUMN * curcol, TDS_SERVER_TYPE type)
+ 	}
+ }
+ 
+-#if !ENABLE_EXTRA_CHECKS
+-static
+-#endif
+ int
+ tds_get_cardinal_type(int datatype)
+ {
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 680b740..22cfb0a 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.371 2009/08/20 18:59:29 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.372 2009/08/21 10:11:20 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2062,6 +2062,7 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 				return TDS_FAIL;
+ 			if (tds_get_char_data(tds, (char *) v->data, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
++			v->type = tds_get_cardinal_type(type);
+ 		} else {
+ 			v->data = (TDS_CHAR*) malloc(colsize);
+ 			if (!v->data)
+
+commit 1bfc8054cc817d8b89c687967af9ecab1d0a8b84
+Author: freddy77 <freddy77>
+Date:   Fri Aug 21 11:30:37 2009 +0000
+
+    give error if no seletecd
+
+diff --git a/misc/commit b/misc/commit
+index 2bcfba0..721fb58 100755
+--- a/misc/commit
++++ b/misc/commit
+@@ -1,6 +1,6 @@
+ #!/usr/bin/perl
+ 
+-# $Id: commit,v 1.6 2009/04/23 13:29:40 freddy77 Exp $
++# $Id: commit,v 1.7 2009/08/21 11:30:37 freddy77 Exp $
+ 
+ use strict;
+ 
+@@ -172,7 +172,7 @@ for (;;) {
+ 	die("error reading reply: $!") if !defined($answer);
+ 	chomp $answer;
+ 	last if $answer eq 'yes';
+-	exit(0) if $answer eq 'no';
++	exit(2) if $answer eq 'no';
+ }
+ 
+ # change ChangeLog if needed
+
+commit d3ed4e951dc19fd85123808627e29d588982b799
+Author: freddy77 <freddy77>
+Date:   Tue Aug 25 05:00:53 2009 +0000
+
+    updated
+
+diff --git a/TODO b/TODO
+index b18f209..223fd95 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.172 2009/02/28 17:38:43 jklowden Exp $
++To Do List	$Id: TODO,v 1.173 2009/08/25 05:00:53 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -31,8 +31,6 @@ Must be fixed:
+          (actually a ct_cancel() error)" 
+ 
+ Broken:
+-. HAVE_FUNC_GETSERVBYNAME_R_6 is defined by configure as 1 on 
+-  NetBSD 2.0 even though it's not defined by the OS.  
+ . Passing invalid character set names to server with tsql?
+   tsql (and so libTDS) can pass invalid charset names to Sybase
+   libTDS assume Sybase can handle this charset but it's false
+@@ -82,7 +80,6 @@ For future versions (in priority order within library):
+ . review the way parameters are packed 
+   (too complicate, see ctlib bulk, cf "bulk copy and row buffer")
+ . improve cursor support on dblib and ctlib
+-. support for VARIANT type (requested one time, 2003-8-1)
+ . support for NT named pipe (requested long ago for mssql6.5 server, only
+   for completeness). If the reader knows a library to handle named pipes
+   compatible with LGPL please tell us.
+
+commit d541ba2a54c2521c1cb01bfd6b0013f1563ef2f4
+Author: freddy77 <freddy77>
+Date:   Tue Aug 25 14:25:35 2009 +0000
+
+    Use MS protocol version (7.1 for mssql2k and 7.2 for mssql2k5)
+
+diff --git a/ChangeLog b/ChangeLog
+index d029572..1444d24 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,13 @@
++Tue Aug 25 16:23:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/freebcp.txt doc/freetds.conf.5 doc/tds_ssl.html:
++	* doc/userguide.sgml include/sybdb.h include/tds.h src/dblib/bcp.c:
++	* src/dblib/dblib.c src/dblib/unittests/t0022.c src/pool/util.c:
++	* src/server/login.c src/server/server.c src/server/unittest.c:
++	* src/tds/bulk.c src/tds/config.c src/tds/login.c src/tds/mem.c:
++	* src/tds/net.c src/tds/query.c src/tds/tds_checks.c:
++	* src/tds/token.c src/tds/util.c win32/winsetup.c:
++	- Use MS protocol version (7.1 for mssql2k and 7.2 for mssql2k5)
++
+ Fri Aug 21 12:10:57 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/data.c src/tds/token.c:
+ 	- fix variant type for data converted to client encoding
+@@ -1786,4 +1796,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2857 2009/08/21 10:11:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2858 2009/08/25 14:25:35 freddy77 Exp $
+diff --git a/doc/freebcp.txt b/doc/freebcp.txt
+index 1e00e77..6a841e7 100644
+--- a/doc/freebcp.txt
++++ b/doc/freebcp.txt
+@@ -122,7 +122,7 @@ OPTIONS
+ NOTES
+   When connecting to a Sybase database server, it is required that the
+   TDS 5.0 protocol be used. When connecting to a Microsoft SQL Server
+-  2000 database server, the TDS 8.0 protocol is required.
++  2000 database server, the TDS 7.1 protocol is required.
+ 
+   Theoretically both Sybase and Microsoft support the TDS 4.2 protocol,
+   but in reality they implement the bcp portion of TDS 4.2 differently.
+diff --git a/doc/freetds.conf.5 b/doc/freetds.conf.5
+index c3890a5..524bbb9 100644
+--- a/doc/freetds.conf.5
++++ b/doc/freetds.conf.5
+@@ -1,4 +1,4 @@
+-.\" $Id: freetds.conf.5,v 1.2 2007/12/26 18:45:17 freddy77 Exp $
++.\" $Id: freetds.conf.5,v 1.3 2009/08/25 14:25:35 freddy77 Exp $
+ .Dd December 23, 2007
+ .Os [FreeTDS] [@version@]
+ .Dt FREETDS.CONF 5
+@@ -146,7 +146,7 @@ TDS 5.0, 5000; TDS 7.0 and up, 1433
+ TDS protocol version to use
+ .Bl -tag -width "default:" -compact
+ .It Domain:
+-4.2, 5.0, 7.0, 8.0
++4.2, 5.0, 7.0, 7.1, 7.2
+ .It Default:
+ .Fl -with-tdsver
+ value (5.0 if unspecified)
+diff --git a/doc/tds_ssl.html b/doc/tds_ssl.html
+index b8d4867..3cf0157 100644
+--- a/doc/tds_ssl.html
++++ b/doc/tds_ssl.html
+@@ -42,7 +42,7 @@ REGEDIT4
+ 
+ <h2>Encryption protocol</h2>
+ 
+-<p>Prelogin packet (tds 8.0 only)
++<p>Prelogin packet (tds 7.1 only)
+ 
+ <p>&gt;From client to server 
+ 
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 1c42309..2c34cab 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -5,8 +5,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2009/06/06 16:24:11 $</date>
+-		<releaseinfo>$Revision: 1.124 $</releaseinfo>
++		<date>$Date: 2009/08/25 14:25:35 $</date>
++		<releaseinfo>$Revision: 1.125 $</releaseinfo>
+ 		<title><productname>FreeTDS</productname> User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
+ 		<author>
+@@ -57,9 +57,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.124 $</>
+-<member>$Date: 2009/06/06 16:24:11 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.124 2009/06/06 16:24:11 freddy77 Exp $.</>
++<member>$Revision: 1.125 $</>
++<member>$Date: 2009/08/25 14:25:35 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.125 2009/08/25 14:25:35 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the <productname>FreeTDS</productname> 
+@@ -153,7 +153,7 @@ Introduced for <productname>SQL Server 7.0</productname>.  Includes support for
+ 			</para>
+ 			</listitem></varlistentry>
+ 
+-			<varlistentry><term>TDS 8.0
++			<varlistentry><term>TDS 7.1
+ 			  Microsoft</term>
+ 			<listitem>
+ 			<para>
+@@ -161,6 +161,14 @@ Introduced for <productname>SQL Server 2000</productname>.  Includes support for
+ 			</para>
+ 			</listitem></varlistentry>
+ 
++			<varlistentry><term>TDS 7.2
++			  Microsoft</term>
++			<listitem>
++			<para>
++Introduced for <productname>SQL Server 2005</productname>.  Includes support for varchar(max), varbinary(max), xml datatypes and MARS.
++			</para>
++			</listitem></varlistentry>
++
+ 			</variablelist>
+ 		  </sect1>
+ 
+@@ -172,7 +180,7 @@ Introduced for <productname>SQL Server 2000</productname>.  Includes support for
+ In early 1997, the only option for connecting to a Sybase server from Linux or other free systems was an aging Sybase-released version of <productname>OpenClient</productname>.  Unfortunately it had a few problems.  The original release was <symbol>a.out</>-based, although Greg Thain did a great service in converting the library to ELF.  Secondly, it included only the newer <systemitem class="library">ct-lib</systemitem> <acronym>API</>.  The older <systemitem class="library">db-lib</systemitem> <acronym>API</> was missing.
+ 			</para>
+ 			<para>
+-Brian Bruns, a Sybase DBA and originator of the <productname>FreeTDS</productname> project, had some <systemitem class="library">db-lib</systemitem> programs he wanted to run under Linux, and thus began the <productname>FreeTDS</productname> project. The original work focused on <systemitem class="library">db-lib</systemitem> and version 5.0 of the protocol, but quickly expanded to include a <systemitem class="library">ct-lib</systemitem> compatible layer and <acronym>TDS</> version 4.2.  Later support for <systemitem class="library">ODBC</systemitem> and <acronym>TDS 7.0 and 8.0</> was added. Craig Spannring wrote a Java  <acronym>JDBC</> driver which became <productname>FreeTDS/JDBC</productname>.
++Brian Bruns, a Sybase DBA and originator of the <productname>FreeTDS</productname> project, had some <systemitem class="library">db-lib</systemitem> programs he wanted to run under Linux, and thus began the <productname>FreeTDS</productname> project. The original work focused on <systemitem class="library">db-lib</systemitem> and version 5.0 of the protocol, but quickly expanded to include a <systemitem class="library">ct-lib</systemitem> compatible layer and <acronym>TDS</> version 4.2.  Later support for <systemitem class="library">ODBC</systemitem> and <acronym>TDS 7.0 and 7.1</> was added. Craig Spannring wrote a Java  <acronym>JDBC</> driver which became <productname>FreeTDS/JDBC</productname>.
+ 			</para>
+ 			<para>
+ As the project matured, it gained new participants.  Frediano Ziglio greatly expanded the <systemitem class="library">ODBC</systemitem> driver, and continues to improve both it and the underlying TDS library.  Bill Thompson wrote most of the present BCP system and added cursors to our <systemitem class="library">ct-lib</systemitem>.  Your humble author joined the project to add documentation, and wound up as the project's maintainer.  Such are the rewards for doing a good deed.  
+@@ -392,7 +400,7 @@ There are a few optional arguments to <Command>configure</> that may be importan
+ 			<varlistentry>
+ 				<term><Option>--with-tdsver=<replaceable>VER</>
+ 					</Option></term>
+-				<listitem><para>Specifies the default <acronym>TDS</> version.  (There are a couple of ways to set the <acronym>TDS</> version at run-time.  This parameter takes effect if no run-time settings are provided.) Acceptable values of <parameter>VER</> are <literal>4.2</literal>, <literal>4.6</literal>, <literal>5.0</literal>, <literal>7.0</literal>, and <literal>8.0</literal>.</para>
++				<listitem><para>Specifies the default <acronym>TDS</> version.  (There are a couple of ways to set the <acronym>TDS</> version at run-time.  This parameter takes effect if no run-time settings are provided.) Acceptable values of <parameter>VER</> are <literal>4.2</literal>, <literal>4.6</literal>, <literal>5.0</literal>, <literal>7.0</literal>, <literal>7.1</literal> and <literal>7.2</literal>.</para>
+ 					<para>The default is <literal>5.0</literal> if this argument is not passed to <Command>configure</Command>.</para>
+ 					</listitem>
+ 				</varlistentry>
+@@ -569,7 +577,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2009/06/06 16:24:11 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2009/08/25 14:25:35 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -703,8 +711,8 @@ The <acronym>TDS</> protocol version is probably something you'd rather not know
+ 	</row>
+ 	<row>
+ 	<entry>Microsoft SQL Server 2000</entry>
+-	<entry>8.0</entry>
+-	<entry>Include support for <symbol>bigint</> (64 bit integers), <symbol>variant</> and collation on all fields. <symbol>variant</> is not supported; collation is not widely used. </entry>
++	<entry>7.1</entry>
++	<entry>Include support for <symbol>bigint</> (64 bit integers), <symbol>variant</> and collation on all fields. Collation is not widely used. </entry>
+ 	</row>
+ </tbody>	
+ </tgroup>
+@@ -801,11 +809,11 @@ The <filename>freetds.conf</filename> file is composed of two types of sections:
+ [myserver3]
+ 	host = instancebox.mydomain.com
+ 	instance = foo
+-	tds version = 8.0
++	tds version = 7.1
+ </programlisting>
+ </example>
+ 	<para>
+-In this example, the default  <acronym>TDS</> version for all dataservers is set to <literal>4.2</>.  It is then overridden for <literal>myserver2</literal> (a Sybase server) which uses <literal>5.0</literal>, and <literal>myserver3</literal> (a MSSQL 2000 server) which uses <literal>8.0</literal>.
++In this example, the default  <acronym>TDS</> version for all dataservers is set to <literal>4.2</>.  It is then overridden for <literal>myserver2</literal> (a Sybase server) which uses <literal>5.0</literal>, and <literal>myserver3</literal> (a MSSQL 2000 server) which uses <literal>7.1</literal>.
+ 	</para>
+ 	<para>
+ Usually, it is sufficient to state just the server's hostname and TDS protocol version.  Everything else can be inferred, unless your setup (or your server's) strays from the defaults.  
+@@ -832,7 +840,7 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 		Overridden by <link  linkend="TDSVER">TDSVER</link>.  
+ 		</entry> 
+ 	<entry>The <acronym>TDS</> protocol version to use when connecting.</entry>
+-	<entry>4.2, 5.0, 7.0, 8.0</entry>
++	<entry>4.2, 5.0, 7.0, 7.1, 7.2</entry>
+ 	</row>
+ 	<row>
+ 	<entry>host</entry>
+@@ -929,13 +937,13 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	<entry>emulate little endian</entry>
+ 	<entry>yes/no</entry>
+ 	<entry>no</entry>
+-	<entry>Forces big endian machines (Sparc, PPC, PARISC) to act as little endian to communicate with MS Servers. Set automatically for <acronym>TDS</> 7.0/8.0 on big endian hosts</entry>
++	<entry>Forces big endian machines (Sparc, PPC, PARISC) to act as little endian to communicate with MS Servers. Set automatically for <acronym>TDS</> 7.0 or above on big endian hosts</entry>
+ 	</row>
+ 	<row>
+ 	<entry id="clientcharset">client charset</entry>
+ 	<entry>any valid iconv character set</entry>
+ 	<entry>ISO-8859-1<footnote><para>Valid for ISO 8859-1 character set.  See <link linkend="Localization">Localization and <acronym>TDS</> 7.0</link> for more information.  </para></footnote></entry>
+-	<entry>Makes <productname>FreeTDS</productname> use iconv to convert to and from the specified character set from UCS-2 in <acronym>TDS</> 7.0/8.0.
++	<entry>Makes <productname>FreeTDS</productname> use iconv to convert to and from the specified character set from UCS-2 in <acronym>TDS</> 7.0 or above.
+ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need to match the server's charset to insert any characters the server supports.</entry>
+ 	</row>
+ 	<row>
+@@ -1155,7 +1163,7 @@ In a typical system, no environment variables need be used.  They're sometimes h
+ 	<varlistentry>
+ 		<term id="TDSPORT"><envar>TDSPORT</envar></term>
+ 		<listitem>
+-			<para>specifies a TCP port number at which the dataserver is listening.  It overrides the default port (1433 for TDS 4.2/7.0/8.0, 4000 for TDS 5.0) as well as any port specified in the <filename>freetds.conf</filename> file.</para>
++			<para>specifies a TCP port number at which the dataserver is listening.  It overrides the default port (1433 for TDS 4.2/7.0/7.1/7.2, 4000 for TDS 5.0) as well as any port specified in the <filename>freetds.conf</filename> file.</para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>
+@@ -1785,7 +1793,7 @@ found this section:
+         [machine]
+                 host = machine.example.com
+                 port = 2500
+-                tds version = 8.0
++                tds version = 7.1
+ 
+ machine.example.com has address 10.82.32.177
+ 
+@@ -1829,8 +1837,8 @@ Several version of Microsoft SQL server have a bug that affects big endian clien
+ <Note><para>The terms <emphasis>big endian</emphasis> and <emphasis>little endian</emphasis> come originally from Gulliver's Travels.  In computer science they refer to the the integer byte-order for a processor.  Big endian processors, such as Sparc and PowerPC store the most significant byte in the first memory location of a multi-byte integer.  Little endian processors, such as Intel and Alpha do it the other way around.  So the 16-bit number 258 would be 0x0102 on big endian and 0x0201 on little endian machines.</para></Note>
+ 
+ <para>
+-In this example we want to force connections to a server named <literal>mssql</literal> to emulate a little endian client.  We are using protocol version 4.2 here, version 7.0 and 8.0 will automatically emulate little endian mode regardless of the <filename>freetds.conf</filename> setting.
+-<emphasis>You shouldn't use this option, set another protocol version instead (7.0 or 8.0)</emphasis>.
++In this example we want to force connections to a server named <literal>mssql</literal> to emulate a little endian client.  We are using protocol version 4.2 here, version 7.0 or above will automatically emulate little endian mode regardless of the <filename>freetds.conf</filename> setting.
++<emphasis>You shouldn't use this option, set another protocol version instead (7.0, 7.1 or 7.2)</emphasis>.
+ </para>
+ <example id="e.g.LittleEndian">
+ <title>Emulate Little Endian <filename>freetds.conf</filename> setting</title>
+@@ -1932,7 +1940,7 @@ Why this happens is anyone's guess.  Here's one: it makes the datatype of the co
+ 		</sect1>
+ 		<sect1 id="domains">
+ 			<title>Domain Logins</title>
+-<Note><para>Domain logins can be used only with TDS protocol versions 7.0 and 8.0.</para></Note>
++<Note><para>Domain logins can be used only with TDS protocol versions 7.0 or above.</para></Note>
+ 			<para>
+ As mentioned in the installation chapter, <productname>Microsoft SQL Server</productname> includes the ability to use domain logins instead of standard server logins.  The advantage of doing this is that the passwords are encrypted on the wire using a challenge-response protocol.
+ <productname>FreeTDS</productname> began supporting domain logins in version 0.60.
+@@ -4239,7 +4247,7 @@ While UTF-8 solves many technical problems, it doesn't magically transform every
+ 		</section>
+ 		<section id="UnicodeFreeTDS"><title>Unicode and FreeTDS</title>
+ 			<para>
+-Microsoft servers using TDS 7.0 and above (anything since SQL Server 6.5) transmit their data in UCS-2 format (16-bit integers).  Because most applications linked to <productname>FreeTDS</productname> are not prepared to deal with UCS-2 data, <productname>FreeTDS</productname> can convert the data to something more acceptable, including <acronym>ASCII</>.  To do so, it employs an  <productname>iconv</productname>  library.  <productname>FreeTDS</productname> determines the server's encoding from the TDS protocol and information reported by the server (generally per connection, but in the case of TDS 8.0, per result set column).  It discovers the client's encoding in <filename>freetds.conf</filename>.  <productname>FreeTDS</productname> will happily convert and convey your data in any <emphasis>single-byte</emphasis> format that <productname>iconv</productname> can provide.  In practice, this normally means some form of ISO 8859-x or UTF-8.  
++Microsoft servers using TDS 7.0 and above (anything since SQL Server 6.5) transmit their data in UCS-2 format (16-bit integers).  Because most applications linked to <productname>FreeTDS</productname> are not prepared to deal with UCS-2 data, <productname>FreeTDS</productname> can convert the data to something more acceptable, including <acronym>ASCII</>.  To do so, it employs an  <productname>iconv</productname>  library.  <productname>FreeTDS</productname> determines the server's encoding from the TDS protocol and information reported by the server (generally per connection, but in the case of TDS 7.1, per result set column).  It discovers the client's encoding in <filename>freetds.conf</filename>.  <productname>FreeTDS</productname> will happily convert and convey your data in any <emphasis>single-byte</emphasis> format that <productname>iconv</productname> can provide.  In practice, this normally means some form of ISO 8859-x or UTF-8.
+ 			</para>
+ 			<para>
+ At some future time, <productname>FreeTDS</productname> aims to support Unicode and other multi-byte character sets.  It does not do so at the current time.  
+diff --git a/include/sybdb.h b/include/sybdb.h
+index d642612..8f0cb20 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.90 2009/04/18 19:35:38 jklowden Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.91 2009/08/25 14:25:35 freddy77 Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -73,7 +73,9 @@ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_s
+ #define DBVERSION_100     2
+ #define DBVERSION_42      3
+ #define DBVERSION_70      4
+-#define DBVERSION_80      5
++#define DBVERSION_71      5
++#define DBVERSION_80      DBVERSION_71
++#define DBVERSION_72      6
+ 
+ /* these two are defined by Microsoft for dbsetlversion() */
+ #define DBVER42 	  DBVERSION_42
+@@ -94,6 +96,8 @@ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_s
+ #define DBTDS_7_0               8	/* Microsoft SQL Server 7.0 */
+ #define DBTDS_8_0               9	/* Microsoft SQL Server 2000 */
+ #define DBTDS_9_0               10	/* Microsoft SQL Server 2005 */
++#define DBTDS_7_1               9	/* Microsoft SQL Server 2000 */
++#define DBTDS_7_2               10	/* Microsoft SQL Server 2005 */
+ 
+ #define DBTXPLEN 16
+ 
+diff --git a/include/tds.h b/include/tds.h
+index 744ae2e..12278b8 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.320 2009/08/21 10:11:19 freddy77 Exp $ */
++/* $Id: tds.h,v 1.321 2009/08/25 14:25:35 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -776,24 +776,22 @@ typedef enum tds_encryption_level {
+ #define TDS_DEF_CHARSET		"iso_1"
+ #define TDS_DEF_LANG		"us_english"
+ #if TDS42
+-#define TDS_DEF_MAJOR		4
+-#define TDS_DEF_MINOR		2
++#define TDS_DEFAULT_VERSION	0x402
+ #define TDS_DEF_PORT		1433
+ #elif TDS46
+-#define TDS_DEF_MAJOR		4
+-#define TDS_DEF_MINOR		6
++#define TDS_DEFAULT_VERSION	0x406
+ #define TDS_DEF_PORT		4000
+ #elif TDS70
+-#define TDS_DEF_MAJOR		7
+-#define TDS_DEF_MINOR		0
++#define TDS_DEFAULT_VERSION	0x700
+ #define TDS_DEF_PORT		1433
+-#elif TDS80
+-#define TDS_DEF_MAJOR		8
+-#define TDS_DEF_MINOR		0
++#elif TDS71
++#define TDS_DEFAULT_VERSION	0x701
++#define TDS_DEF_PORT		1433
++#elif TDS72
++#define TDS_DEFAULT_VERSION	0x702
+ #define TDS_DEF_PORT		1433
+ #else
+-#define TDS_DEF_MAJOR		5
+-#define TDS_DEF_MINOR		0
++#define TDS_DEFAULT_VERSION	0x500
+ #define TDS_DEF_PORT		4000
+ #endif
+ 
+@@ -842,8 +840,7 @@ typedef struct tds_login
+ 	DSTR server_name;
+ 	DSTR server_addr;
+ 	int port;
+-	TDS_TINYINT major_version;	/* TDS version */
+-	TDS_TINYINT minor_version;	/* TDS version */
++	TDS_USMALLINT tds_version;	/* TDS version */
+ 	int block_size;
+ 	DSTR language;			/* e.g. us-english */
+ 	DSTR server_charset;		/* e.g. iso_1 */
+@@ -868,8 +865,7 @@ typedef struct tds_connection
+ 	/* first part of structure is the same of login one */
+ 	DSTR server_name; /**< server name (in freetds.conf) */
+ 	int port;	   /**< port of database service */
+-	TDS_TINYINT major_version;
+-	TDS_TINYINT minor_version;
++	TDS_USMALLINT tds_version;
+ 	int block_size;
+ 	DSTR language;
+ 	DSTR server_charset;	/**< charset of server */
+@@ -1314,8 +1310,7 @@ struct tds_socket
+ {
+ 	TDS_SYS_SOCKET s;		/**< tcp socket, INVALID_SOCKET if not connected */
+ 	int oserr;
+-	TDS_SMALLINT major_version;
+-	TDS_SMALLINT minor_version;
++	TDS_USMALLINT tds_version;
+ 	TDS_UINT product_version;	/**< version of product (Sybase/MS and full version) */
+ 	char *product_name;
+ 
+@@ -1417,7 +1412,7 @@ int tds_read_conf_file(TDSCONNECTION * connection, const char *server);
+ void tds_parse_conf_section(const char *option, const char *value, void *param);
+ TDSCONNECTION *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale);
+ void tds_fix_connection(TDSCONNECTION * connection);
+-unsigned char tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
++TDS_USMALLINT tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
+ void tds_lookup_host(const char *servername, char *ip);
+ int tds_set_interfaces_file_loc(const char *interfloc);
+ extern const char STD_DATETIME_FMT[];
+@@ -1647,15 +1642,18 @@ int tds_writetext_continue(TDSSOCKET *tds, const TDS_UCHAR *text, TDS_UINT size)
+ int tds_writetext_end(TDSSOCKET *tds);
+ 
+ 
+-#define IS_TDS42(x) (x->major_version==4 && x->minor_version==2)
+-#define IS_TDS46(x) (x->major_version==4 && x->minor_version==6)
+-#define IS_TDS50(x) (x->major_version==5 && x->minor_version==0)
+-#define IS_TDS70(x) (x->major_version==7 && x->minor_version==0)
+-#define IS_TDS80(x) (x->major_version==8 && x->minor_version==0)
+-#define IS_TDS90(x) (x->major_version==9 && x->minor_version==0)
++#define IS_TDS42(x) (x->tds_version==0x402)
++#define IS_TDS46(x) (x->tds_version==0x406)
++#define IS_TDS50(x) (x->tds_version==0x500)
++#define IS_TDS70(x) (x->tds_version==0x700)
++#define IS_TDS71(x) (x->tds_version==0x701)
++#define IS_TDS72(x) (x->tds_version==0x702)
++
++#define IS_TDS7_PLUS(x) ((x)->tds_version>=0x700)
++#define IS_TDS71_PLUS(x) ((x)->tds_version>=0x701)
+ 
+-#define IS_TDS7_PLUS(x) ((x)->major_version>=7)
+-#define IS_TDS8_PLUS(x) ((x)->major_version>=8)
++#define TDS_MAJOR(x) ((x)->tds_version >> 8)
++#define TDS_MINOR(x) ((x)->tds_version & 0xff)
+ 
+ #define IS_TDSDEAD(x) (((x) == NULL) || TDS_IS_SOCKET_INVALID((x)->s))
+ 
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index d23172e..0c03301 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.187 2009/07/10 18:03:52 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.188 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -183,7 +183,7 @@ bcp_init(DBPROCESS * dbproc, const char *tblname, const char *hfile, const char
+ 	/* 
+ 	 * Validate other parameters 
+ 	 */
+-	if (dbproc->tds_socket->major_version < 5) {
++	if (dbproc->tds_socket->tds_version < 0x500) {
+ 		dbperror(dbproc, SYBETDSVER, 0);
+ 		return (FAIL);
+ 	}
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index b3e8270..f80892b 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.351 2009/08/19 09:50:37 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.352 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -222,8 +222,11 @@ DBVERSION_46;
+ #ifdef TDS70
+ DBVERSION_70;
+ #endif
+-#ifdef TDS80
+-DBVERSION_80;
++#ifdef TDS71
++DBVERSION_71;
++#endif
++#ifdef TDS72
++DBVERSION_72;
+ #endif
+ 
+ 
+@@ -890,12 +893,10 @@ dbsetlversion (LOGINREC * login, BYTE version)
+ 		
+ 	switch (version) {
+ 	case DBVER42:
+-		login->tds_login->major_version = 4;
+-		login->tds_login->minor_version = 2;
++		login->tds_login->tds_version = 0x402;
+ 		return SUCCEED;
+ 	case DBVER60:
+-		login->tds_login->major_version = 6;
+-		login->tds_login->minor_version = 0;
++		login->tds_login->tds_version = 0x600;
+ 		return SUCCEED;
+ 	}
+ 	
+@@ -6505,24 +6506,19 @@ dbtds(DBPROCESS * dbproc)
+ 	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	if (dbproc->tds_socket) {
+-		switch (dbproc->tds_socket->major_version) {
+-		case 4:
+-			switch (dbproc->tds_socket->minor_version) {
+-			case 2:
+-				return DBTDS_4_2;
+-			case 6:
+-				return DBTDS_4_6;
+-			default:
+-				return DBTDS_UNKNOWN;
+-			}
+-		case 5:
++		switch (dbproc->tds_socket->tds_version) {
++		case 0x402:
++			return DBTDS_4_2;
++		case 0x406:
++			return DBTDS_4_6;
++		case 0x500:
+ 			return DBTDS_5_0;
+-		case 7:
++		case 0x700:
+ 			return DBTDS_7_0;
+-		case 8:
+-			return DBTDS_8_0;
+-		case 9:
+-			return DBTDS_9_0;
++		case 0x701:
++			return DBTDS_7_1;
++		case 0x702:
++			return DBTDS_7_2;
+ 		default:
+ 			return DBTDS_UNKNOWN;
+ 		}
+diff --git a/src/dblib/unittests/t0022.c b/src/dblib/unittests/t0022.c
+index 89f823d..bf2912c 100644
+--- a/src/dblib/unittests/t0022.c
++++ b/src/dblib/unittests/t0022.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: t0022.c,v 1.28 2009/07/21 06:40:16 freddy77 Exp $";
++static char software_version[] = "$Id: t0022.c,v 1.29 2009/08/25 14:25:35 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -104,11 +104,11 @@ main(int argc, char **argv)
+ 
+ 	add_bread_crumb();
+ 
+-#if defined(DBTDS_7_0) && defined(DBTDS_8_0) && defined(DBTDS_9_0)
++#if defined(DBTDS_7_0) && defined(DBTDS_7_1) && defined(DBTDS_7_2)
+ 	if ((dbnumrets(dbproc) == 0)
+ 	    && ((DBTDS(dbproc) == DBTDS_7_0)
+-		|| (DBTDS(dbproc) == DBTDS_8_0)
+-		|| (DBTDS(dbproc) == DBTDS_9_0))) {
++		|| (DBTDS(dbproc) == DBTDS_7_1)
++		|| (DBTDS(dbproc) == DBTDS_7_2))) {
+ 		fprintf(stdout, "WARNING:  Received no return parameters from server!\n");
+ 		fprintf(stdout, "WARNING:  This is likely due to a bug in Microsoft\n");
+ 		fprintf(stdout, "WARNING:  SQL Server 7.0 SP3 and later.\n");
+diff --git a/src/pool/util.c b/src/pool/util.c
+index 1977f6d..7bb6610 100644
+--- a/src/pool/util.c
++++ b/src/pool/util.c
+@@ -33,7 +33,7 @@
+ #include "pool.h"
+ #include "tdsstring.h"
+ 
+-static char software_version[] = "$Id: util.c,v 1.13 2006/12/26 14:56:20 freddy77 Exp $";
++static char software_version[] = "$Id: util.c,v 1.14 2009/08/25 14:25:35 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void
+@@ -73,7 +73,7 @@ dump_login(TDSLOGIN * login)
+ 	fprintf(stderr, "pass %s\n", tds_dstr_cstr(&login->password));
+ 	fprintf(stderr, "app  %s\n", tds_dstr_cstr(&login->app_name));
+ 	fprintf(stderr, "srvr %s\n", tds_dstr_cstr(&login->server_name));
+-	fprintf(stderr, "vers %d.%d\n", login->major_version, login->minor_version);
++	fprintf(stderr, "vers %d.%d\n", TDS_MAJOR(login), TDS_MINOR(login));
+ 	fprintf(stderr, "lib  %s\n", tds_dstr_cstr(&login->library));
+ 	fprintf(stderr, "lang %s\n", tds_dstr_cstr(&login->language));
+ 	fprintf(stderr, "char %s\n", tds_dstr_cstr(&login->server_charset));
+diff --git a/src/server/login.c b/src/server/login.c
+index db0163d..c240162 100644
+--- a/src/server/login.c
++++ b/src/server/login.c
+@@ -58,7 +58,7 @@
+ #include "tdssrv.h"
+ #include "tdsstring.h"
+ 
+-static char software_version[] = "$Id: login.c,v 1.54 2009/02/27 10:11:43 freddy77 Exp $";
++static char software_version[] = "$Id: login.c,v 1.55 2009/08/25 14:25:35 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ unsigned char *
+@@ -122,6 +122,7 @@ void
+ tds_read_login(TDSSOCKET * tds, TDSLOGIN * login)
+ {
+ 	DSTR blockstr;
++	TDS_USMALLINT major;
+ 
+ /*
+ 	while (len = tds_read_packet(tds)) {
+@@ -138,8 +139,8 @@ tds_read_login(TDSSOCKET * tds, TDSLOGIN * login)
+ 	tds_read_string(tds, &login->app_name, 30);
+ 	tds_read_string(tds, &login->server_name, 30);
+ 	tds_get_n(tds, NULL, 256);	/* secondary passwd...encryption? */
+-	login->major_version = tds_get_byte(tds);
+-	login->minor_version = tds_get_byte(tds);
++	major = tds_get_byte(tds);
++	login->tds_version = (major << 8) | tds_get_byte(tds);
+ 	tds_get_smallint(tds);	/* unused part of protocol field */
+ 	tds_read_string(tds, &login->library, 10);
+ 	tds_get_byte(tds);	/* program version, junk it */
+@@ -183,8 +184,7 @@ tds7_read_login(TDSSOCKET * tds, TDSLOGIN * login)
+ 	a = tds_get_int(tds);	/*total packet size */
+ 	a = tds_get_int(tds);	/*TDS version */
+ 	a &= 0xff;
+-	login->major_version = a >> 4;
+-	login->minor_version = a << 4;
++	login->tds_version = ((a << 4) & 0xff00) | (a & 0xf);
+ 	a = tds_get_int(tds);	/*desired packet size being requested by client */
+ 	tds_get_n(tds, NULL, 24);	/*magic1 */
+ 	a = tds_get_smallint(tds);	/*current position */
+@@ -297,8 +297,7 @@ tds_alloc_read_login(TDSSOCKET * tds)
+ 	/* Use the packet type to determine which login format to expect */
+ 	switch (tds->in_flag) {
+ 	case 0x02: /* TDS4/5 login */
+-		tds->major_version = 4;
+-		tds->minor_version = 2;
++		tds->tds_version = 0x402;
+ 		tds_read_login(tds, login);
+ 		if (login->block_size == 0) {
+ 			login->block_size = 512;
+@@ -306,14 +305,12 @@ tds_alloc_read_login(TDSSOCKET * tds)
+ 		break;
+ 
+ 	case 0x10: /* TDS7+ login */
+-		tds->major_version = 7;
+-		tds->minor_version = 0;
++		tds->tds_version = 0x700;
+ 		tds7_read_login(tds, login);
+ 		break;
+ 
+ 	case 0x12: /* TDS8+ prelogin, hopefully followed by a login */
+-		tds->major_version = 8;
+-		tds->minor_version = 0;
++		tds->tds_version = 0x701;
+ 		/* ignore client and just send our reply TODO... finish */
+ 		tds8_send_prelogin(tds);
+ 		tds_flush_packet(tds);
+diff --git a/src/server/server.c b/src/server/server.c
+index 673b36f..13ba955 100644
+--- a/src/server/server.c
++++ b/src/server/server.c
+@@ -30,7 +30,7 @@
+ #include "tds.h"
+ #include "tdssrv.h"
+ 
+-static char software_version[] = "$Id: server.c,v 1.25 2008/05/28 21:08:33 freddy77 Exp $";
++static char software_version[] = "$Id: server.c,v 1.26 2009/08/25 14:25:35 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void
+@@ -166,8 +166,8 @@ tds_send_login_ack(TDSSOCKET * tds, const char *progname)
+ 		tds_put_byte(tds, 0);
+ 	} else {
+ 		tds_put_byte(tds, 1);
+-		tds_put_byte(tds, tds->major_version);
+-		tds_put_byte(tds, tds->minor_version);
++		tds_put_byte(tds, TDS_MAJOR(tds));
++		tds_put_byte(tds, TDS_MINOR(tds));
+ 	}
+ 	tds_put_byte(tds, 0);	/* unknown */
+ 	tds_put_byte(tds, 0);	/* unknown */
+@@ -230,7 +230,7 @@ tds_send_done(TDSSOCKET * tds, int token, TDS_SMALLINT flags, TDS_INT numrows)
+ 	tds_put_byte(tds, token);
+ 	tds_put_smallint(tds, flags);
+ 	tds_put_smallint(tds, 2); /* are these two bytes the transaction status? */
+-	if (IS_TDS90(tds))
++	if (IS_TDS72(tds))
+ 		tds_put_int8(tds, numrows);
+ 	else
+ 		tds_put_int(tds, numrows);
+@@ -399,7 +399,7 @@ tds7_send_result(TDSSOCKET * tds, TDSRESULTINFO * resinfo)
+  */
+ void tds_send_table_header(TDSSOCKET * tds, TDSRESULTINFO * resinfo)
+ {
+-	switch (tds->major_version) {
++	switch (TDS_MAJOR(tds)) {
+ 	case 4:
+ 		/*
+ 		 * TDS4 uses TDS_COLNAME_TOKEN to send column names, and
+@@ -416,8 +416,6 @@ void tds_send_table_header(TDSSOCKET * tds, TDSRESULTINFO * resinfo)
+ 		break;
+ 
+ 	case 7:
+-	case 8:
+-	case 9:
+ 		/*
+ 		 * TDS7+ uses a TDS7_RESULT_TOKEN to send all column
+ 		 * information.
+diff --git a/src/server/unittest.c b/src/server/unittest.c
+index 970c2f2..e1595fc 100644
+--- a/src/server/unittest.c
++++ b/src/server/unittest.c
+@@ -44,7 +44,7 @@
+ #define sleep(s) Sleep((s)*1000)
+ #endif
+ 
+-static char software_version[] = "$Id: unittest.c,v 1.18 2008/01/07 14:07:21 freddy77 Exp $";
++static char software_version[] = "$Id: unittest.c,v 1.19 2009/08/25 14:25:35 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void dump_login(TDSLOGIN * login);
+@@ -126,7 +126,7 @@ dump_login(TDSLOGIN * login)
+ 	printf("pass %s\n", tds_dstr_cstr(&login->password));
+ 	printf("app  %s\n", tds_dstr_cstr(&login->app_name));
+ 	printf("srvr %s\n", tds_dstr_cstr(&login->server_name));
+-	printf("vers %d.%d\n", login->major_version, login->minor_version);
++	printf("vers %d.%d\n", TDS_MAJOR(login), TDS_MINOR(login));
+ 	printf("lib  %s\n", tds_dstr_cstr(&login->library));
+ 	printf("lang %s\n", tds_dstr_cstr(&login->language));
+ 	printf("char %s\n", tds_dstr_cstr(&login->server_charset));
+diff --git a/src/tds/bulk.c b/src/tds/bulk.c
+index f549571..e0c4ffb 100644
+--- a/src/tds/bulk.c
++++ b/src/tds/bulk.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bulk.c,v 1.9 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: bulk.c,v 1.10 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ #ifndef MAX
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+@@ -829,7 +829,7 @@ tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 			continue;
+ 		}
+ 
+-		if (IS_TDS90(tds))
++		if (IS_TDS72(tds))
+ 			tds_put_int(tds, bcpcol->column_usertype);
+ 		else
+ 			tds_put_smallint(tds, bcpcol->column_usertype);
+@@ -856,7 +856,7 @@ tds7_bcp_send_colmetadata(TDSSOCKET *tds, TDSBCPINFO *bcpinfo)
+ 			tds_put_byte(tds, bcpcol->column_prec);
+ 			tds_put_byte(tds, bcpcol->column_scale);
+ 		}
+-		if (IS_TDS8_PLUS(tds)
++		if (IS_TDS71_PLUS(tds)
+ 			&& is_collate_type(bcpcol->on_server.column_type)) {
+ 			tds_put_n(tds, bcpcol->column_collation, 5);
+ 		}
+diff --git a/src/tds/config.c b/src/tds/config.c
+index f1ba176..faa32eb 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.144 2009/08/20 17:51:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.145 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -209,8 +209,8 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 		tdsdump_log(TDS_DBG_INFO1, "Final connection parameters:\n");
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_name", tds_dstr_cstr(&connection->server_name));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "port", connection->port);
+-		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "major_version", (int)connection->major_version);
+-		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "minor_version", (int)connection->minor_version);
++		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "major_version", TDS_MAJOR(connection));
++		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "minor_version", TDS_MINOR(connection));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "block_size", connection->block_size);
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "language", tds_dstr_cstr(&connection->language));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_charset", tds_dstr_cstr(&connection->server_charset));
+@@ -582,10 +582,8 @@ tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login)
+ 	if (!tds_dstr_isempty(&login->server_name) && tds_dstr_isempty(&connection->server_name)) {
+ 		tds_dstr_dup(&connection->server_name, &login->server_name);
+ 	}
+-	if (login->major_version || login->minor_version) {
+-		connection->major_version = login->major_version;
+-		connection->minor_version = login->minor_version;
+-	}
++	if (login->tds_version)
++		connection->tds_version = login->tds_version;
+ 	if (!tds_dstr_isempty(&login->language)) {
+ 		tds_dstr_dup(&connection->language, &login->language);
+ 	}
+@@ -704,32 +702,30 @@ tds_config_env_tdshost(TDSCONNECTION * connection)
+  * @param connection where to store information
+  * @return as encoded hex value: high nybble major, low nybble minor.
+  */
+-unsigned char
++TDS_USMALLINT
+ tds_config_verstr(const char *tdsver, TDSCONNECTION * connection)
+ {
+-	unsigned char version;
++	TDS_USMALLINT version;
+ 
+ 	if (!strcmp(tdsver, "42") || !strcmp(tdsver, "4.2"))
+-		version = 0x42;
++		version = 0x402;
+ 	else if (!strcmp(tdsver, "46") || !strcmp(tdsver, "4.6"))
+-		version = 0x46;
++		version = 0x406;
+ 	else if (!strcmp(tdsver, "50") || !strcmp(tdsver, "5.0"))
+-		version = 0x50;
++		version = 0x500;
+ 	else if (!strcmp(tdsver, "70") || !strcmp(tdsver, "7.0"))
+-		version = 0x70;
++		version = 0x700;
+ 	else if (!strcmp(tdsver, "80") || !strcmp(tdsver, "8.0") || !strcmp(tdsver, "7.1"))
+-		version = 0x80;
++		version = 0x701;
+ 	else if (!strcmp(tdsver, "7.2"))
+-		version = 0x90;
++		version = 0x702;
+ 	else if (!strcmp(tdsver, "0.0"))
+ 		version = 0;
+ 	else 
+ 		return 0;
+ 
+-	if (connection) {
+-		connection->major_version = version >> 4;
+-		connection->minor_version = version & 0xf;
+-	}
++	if (connection)
++		connection->tds_version = version;
+ 
+ 	return version;
+ }
+@@ -1143,21 +1139,17 @@ tds_get_compiletime_settings(void)
+ #		endif
+ #		ifdef TDS46
+ 			, "4.6"
+-#		else
+-#		ifdef TDS50
++#		elif TDS50
+ 			, "5.0"
+-#		else
+-#		ifdef TDS70
++#		elif TDS70
+ 			, "7.0"
+-#		else
+-#		ifdef TDS80
+-			, "8.0"
++#		elif TDS71
++			, "7.1"
++#		elif TDS72
++			, "7.2"
+ #		else
+ 			, "4.2"
+ #		endif
+-#		endif
+-#		endif
+-#		endif
+ #		ifdef IODBC
+ 			, 1
+ #		else
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 3f5de67..cc49cf8 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.187 2009/08/20 17:51:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.188 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -60,8 +60,7 @@ static int tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ void
+ tds_set_version(TDSLOGIN * tds_login, TDS_TINYINT major_ver, TDS_TINYINT minor_ver)
+ {
+-	tds_login->major_version = major_ver;
+-	tds_login->minor_version = minor_ver;
++	tds_login->tds_version = ((TDS_USMALLINT) major_ver << 8) + minor_ver;
+ }
+ 
+ void
+@@ -333,22 +332,19 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	 * A major version of 0 means try to guess the TDS version. 
+ 	 * We try them in an order that should work. 
+ 	 */
+-	const static struct tdsver {
+-		TDS_TINYINT major_version;
+-		TDS_TINYINT minor_version;
+-	} versions[] =
+-		{ { 9, 0 }
+-		, { 8, 0 }
+-		, { 7, 0 }
+-		, { 5, 0 }
+-		, { 4, 2 }
++	const static TDS_USMALLINT versions[] =
++		{ 0x702
++		, 0x701
++		, 0x700
++		, 0x500
++		, 0x402
+ 		};
+ 
+ 	/* disable tds9 if iconv wanted, currently not supported */
+-	if (connection->major_version == 9 && tds->use_iconv)
+-		connection->major_version = 8;
++	if (IS_TDS72(connection) && tds->use_iconv)
++		connection->tds_version = 0x701;
+ 
+-	if (connection->major_version == 0) {
++	if (TDS_MAJOR(connection) == 0) {
+ 		unsigned int i;
+ 		TDSSAVECONTEXT save_ctx;
+ 		const TDSCONTEXT *old_ctx = tds->tds_ctx;
+@@ -364,8 +360,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		mod_ctx->err_handler = NULL;
+ 
+ 		for (i=tds->use_iconv ? 1: 0; i < TDS_VECTOR_SIZE(versions); ++i) {
+-			connection->major_version = versions[i].major_version;
+-			connection->minor_version = versions[i].minor_version;
++			connection->tds_version = versions[i];
+ 			reset_save_context(&save_ctx);
+ 
+ 			if ((erc = tds_connect_and_login(tds, connection)) != TDS_SUCCEED) {
+@@ -400,8 +395,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	tds->connection = connection;
+ 
+-	tds->major_version = connection->major_version;
+-	tds->minor_version = connection->minor_version;
++	tds->tds_version = connection->tds_version;
+ 	tds->emul_little_endian = connection->emul_little_endian;
+ #ifdef WORDS_BIGENDIAN
+ 	if (IS_TDS7_PLUS(tds)) {
+@@ -462,7 +456,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		
+ 	tds_set_state(tds, TDS_IDLE);
+ 
+-	if (IS_TDS8_PLUS(tds)) {
++	if (IS_TDS71_PLUS(tds)) {
+ 		erc = tds8_do_login(tds, connection);
+ 		db_selected = 1;
+ 	} else if (IS_TDS7_PLUS(tds)) {
+@@ -747,7 +741,7 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	if (password_len > 128)
+ 		password_len = 128;
+ 
+-	current_pos = IS_TDS90(tds) ? 86 + 8 : 86;	/* ? */
++	current_pos = IS_TDS72(tds) ? 86 + 8 : 86;	/* ? */
+ 
+ 	packet_size = current_pos + (host_name_len + app_name_len + server_name_len + library_len + language_len + database_len) * 2;
+ 
+@@ -777,9 +771,9 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	tdsdump_off();
+ #endif
+ 	TDS_PUT_INT(tds, packet_size);
+-	if (IS_TDS90(tds)) {
++	if (IS_TDS72(tds)) {
+ 		tds_put_n(tds, tds9Version, 4);
+-	} else if (IS_TDS8_PLUS(tds)) {
++	} else if (IS_TDS71_PLUS(tds)) {
+ 		tds_put_n(tds, tds8Version, 4);
+ 	} else {
+ 		tds_put_n(tds, tds7Version, 4);
+@@ -873,7 +867,7 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	TDS_PUT_SMALLINT(tds, current_pos);
+ 	tds_put_smallint(tds, 0);
+ 
+-	if (IS_TDS90(tds)) {
++	if (IS_TDS72(tds)) {
+ 		TDS_PUT_SMALLINT(tds, current_pos);
+ 		tds_put_smallint(tds, 0);
+ 
+@@ -965,7 +959,7 @@ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	TDS_UCHAR *p;
+ 
+ 	SET_UI16BE(13, instance_name_len);
+-	if (!IS_TDS90(tds)) {
++	if (!IS_TDS72(tds)) {
+ 		SET_UI16BE(16, START_POS + 6 + 1 + instance_name_len);
+ 		buf[20] = 0xff;
+ 	} else {
+@@ -987,7 +981,7 @@ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	tds_put_n(tds, buf, start_pos);
+ 	/* netlib version */
+-	tds_put_n(tds, IS_TDS90(tds) ? netlib9 : netlib8, 6);
++	tds_put_n(tds, IS_TDS72(tds) ? netlib9 : netlib8, 6);
+ 	/* encryption */
+ #if !defined(HAVE_GNUTLS) && !defined(HAVE_OPENSSL)
+ 	/* not supported */
+@@ -1000,7 +994,7 @@ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	/* pid */
+ 	tds_put_int(tds, getpid());
+ 	/* MARS (1 enabled) */
+-	if (IS_TDS90(tds))
++	if (IS_TDS72(tds))
+ 		tds_put_byte(tds, 0);
+ 	if (tds_flush_packet(tds) == TDS_FAIL)
+ 		return TDS_FAIL;
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 33edd1a..3616d78 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.190 2009/07/20 17:38:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.191 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -812,8 +812,7 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 	/* fill in all hardcoded defaults */
+ 	if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER))
+ 		goto Cleanup;
+-	connection->major_version = TDS_DEF_MAJOR;
+-	connection->minor_version = TDS_DEF_MINOR;
++	connection->tds_version = TDS_DEFAULT_VERSION;
+ 	connection->port = TDS_DEF_PORT;
+ 	connection->block_size = 0;
+ 	/* TODO use system default ?? */
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 394ac99..f93cdff 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.94 2009/08/21 10:01:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.95 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -220,7 +220,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 
+ 	tdsdump_log(TDS_DBG_INFO1, "Connecting to %s port %d (TDS version %d.%d)\n", 
+ 			tds_inet_ntoa_r(sin.sin_addr, ip, sizeof(ip)), ntohs(sin.sin_port), 
+-			tds->major_version, tds->minor_version);
++			TDS_MAJOR(tds), TDS_MINOR(tds));
+ 
+ 	if (TDS_IS_SOCKET_INVALID(tds->s = socket(AF_INET, SOCK_STREAM, 0))) {
+ 		tds->oserr = sock_errno;
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 41d2b0f..0e96adb 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.239 2009/08/20 17:51:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.240 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -249,7 +249,7 @@ static const TDS_UCHAR tds9_query_start[] = {
+ 
+ #define START_QUERY \
+ do { \
+-	if (IS_TDS90(tds)) \
++	if (IS_TDS72(tds)) \
+ 		tds_start_query(tds); \
+ } while(0)
+ 
+@@ -353,7 +353,7 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 		tds->out_flag = TDS_RPC;
+ 		START_QUERY;
+ 		/* procedure name */
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_EXECUTESQL);
+ 		} else {
+@@ -368,7 +368,7 @@ tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * param
+ 			tds_put_byte(tds, 0);
+ 			tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+ 			TDS_PUT_INT(tds, converted_query_len);
+-			if (IS_TDS8_PLUS(tds))
++			if (IS_TDS71_PLUS(tds))
+ 				tds_put_n(tds, tds->collation, 5);
+ 			TDS_PUT_INT(tds, converted_query_len);
+ 			tds_put_n(tds, converted_query, converted_query_len);
+@@ -948,7 +948,7 @@ tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len)
+ 	tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+ 	len = 2u * len + query_len;
+ 	TDS_PUT_INT(tds, len);
+-	if (IS_TDS8_PLUS(tds))
++	if (IS_TDS71_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+ 	TDS_PUT_INT(tds, len);
+ 	s = query;
+@@ -977,7 +977,7 @@ tds7_put_params_definition(TDSSOCKET * tds, const char *param_definition, size_t
+ 
+ 	/* put parameters definitions */
+ 	TDS_PUT_INT(tds, param_length);
+-	if (IS_TDS8_PLUS(tds))
++	if (IS_TDS71_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+ 	TDS_PUT_INT(tds, param_length ? param_length : -1);
+ 	tds_put_n(tds, param_definition, param_length);
+@@ -1056,7 +1056,7 @@ tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMI
+ 		tds->out_flag = TDS_RPC;
+ 		START_QUERY;
+ 		/* procedure name */
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_PREPARE);
+ 		} else {
+@@ -1170,7 +1170,7 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ 		tds->out_flag = TDS_RPC;
+ 		START_QUERY;
+ 		/* procedure name */
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_EXECUTESQL);
+ 		} else {
+@@ -1386,7 +1386,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 	}
+ 
+ 	/* TDS8 output collate information */
+-	if (IS_TDS8_PLUS(tds) && is_collate_type(curcol->on_server.column_type))
++	if (IS_TDS71_PLUS(tds) && is_collate_type(curcol->on_server.column_type))
+ 		tds_put_n(tds, tds->collation, 5);
+ 
+ 	/* TODO needed in TDS4.2 ?? now is called only is TDS >= 5 */
+@@ -1787,7 +1787,7 @@ tds_submit_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn)
+ 		tds->out_flag = TDS_RPC;
+ 		START_QUERY;
+ 		/* procedure name */
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			/* save some byte for mssql2k */
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_UNPREPARE);
+@@ -2165,7 +2165,7 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 
+ 		/* procedure identifier by number */
+ 
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_CURSOROPEN);
+ 		} else {
+@@ -2190,7 +2190,7 @@ tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *
+ 			tds_put_byte(tds, 0);
+ 			tds_put_byte(tds, SYBNTEXT);	/* must be Ntype */
+ 			TDS_PUT_INT(tds, converted_query_len);
+-			if (IS_TDS8_PLUS(tds))
++			if (IS_TDS71_PLUS(tds))
+ 				tds_put_n(tds, tds->collation, 5);
+ 			TDS_PUT_INT(tds, converted_query_len);
+ 			tds_put_n(tds, converted_query, (int)converted_query_len);
+@@ -2296,7 +2296,7 @@ tds_cursor_setrows(TDSSOCKET * tds, TDSCURSOR * cursor, int *something_to_send)
+ static void
+ tds7_put_cursor_fetch(TDSSOCKET * tds, TDS_INT cursor_id, TDS_TINYINT fetch_type, TDS_INT i_row, TDS_INT num_rows)
+ {
+-	if (IS_TDS8_PLUS(tds)) {
++	if (IS_TDS71_PLUS(tds)) {
+ 		tds_put_smallint(tds, -1);
+ 		tds_put_smallint(tds, TDS_SP_CURSORFETCH);
+ 	} else {
+@@ -2413,7 +2413,7 @@ tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_typ
+ 			/* strangely dynamic cursor do not support absolute so emulate it with first + relative */
+ 			tds7_put_cursor_fetch(tds, cursor->cursor_id, 1, 0, 0);
+ 			/* TODO define constant */
+-			tds_put_byte(tds, IS_TDS90(tds) ? 0xff : 0x80);
++			tds_put_byte(tds, IS_TDS72(tds) ? 0xff : 0x80);
+ 			tds7_put_cursor_fetch(tds, cursor->cursor_id, 0x20, i_row, cursor->cursor_rows);
+ 		} else {
+ 			/* TODO check fetch_type ?? */
+@@ -2459,7 +2459,7 @@ tds_cursor_get_cursor_info(TDSSOCKET *tds, TDSCURSOR *cursor, TDS_UINT *prow_num
+ 		START_QUERY;
+ 
+ 		/* Create and send query to server */
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_CURSORFETCH);
+ 		} else {
+@@ -2583,7 +2583,7 @@ tds_cursor_close(TDSSOCKET * tds, TDSCURSOR * cursor)
+ 		tds->out_flag = TDS_RPC;
+ 		START_QUERY;
+ 
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_CURSORCLOSE);
+ 		} else {
+@@ -2633,7 +2633,7 @@ tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor)
+ 	tds->out_flag = TDS_RPC;
+ 	START_QUERY;
+ 
+-	if (IS_TDS8_PLUS(tds)) {
++	if (IS_TDS71_PLUS(tds)) {
+ 		tds_put_smallint(tds, -1);
+ 		tds_put_smallint(tds, TDS_SP_CURSOROPTION);
+ 	} else {
+@@ -2666,7 +2666,7 @@ tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor)
+ 	tds_put_byte(tds, XSYBVARCHAR);
+ 	len = (int)strlen(cursor->cursor_name);
+ 	tds_put_smallint(tds, len);
+-	if (IS_TDS8_PLUS(tds))
++	if (IS_TDS71_PLUS(tds))
+ 		tds_put_n(tds, tds->collation, 5);
+ 	tds_put_smallint(tds, len);
+ 	tds_put_n(tds, cursor->cursor_name, len);
+@@ -2709,7 +2709,7 @@ tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op,
+ 		tds->out_flag = TDS_RPC;
+ 		START_QUERY;
+ 
+-		if (IS_TDS8_PLUS(tds)) {
++		if (IS_TDS71_PLUS(tds)) {
+ 			tds_put_smallint(tds, -1);
+ 			tds_put_smallint(tds, TDS_SP_CURSOR);
+ 		} else {
+@@ -2774,7 +2774,7 @@ tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op,
+ 				}
+ 			}
+ 			TDS_PUT_SMALLINT(tds, converted_table_len);
+-			if (IS_TDS8_PLUS(tds))
++			if (IS_TDS71_PLUS(tds))
+ 				tds_put_n(tds, tds->collation, 5);
+ 			TDS_PUT_SMALLINT(tds, converted_table_len);
+ 			tds_put_n(tds, converted_table, converted_table_len);
+@@ -3071,7 +3071,7 @@ tds_multiple_execute(TDSSOCKET *tds, TDSMULTIPLE *multiple, TDSDYNAMIC * dyn)
+ 	if (IS_TDS7_PLUS(tds)) {
+ 		if (multiple->flags & MUL_STARTED) {
+ 			/* TODO define constant */
+-			tds_put_byte(tds, IS_TDS90(tds) ? 0xff : 0x80);
++			tds_put_byte(tds, IS_TDS72(tds) ? 0xff : 0x80);
+ 		}
+ 		multiple->flags |= MUL_STARTED;
+ 
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index a3bfa1c..108c247 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.25 2009/08/18 15:11:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.26 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -204,10 +204,9 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	} else if (column->column_type == SYBVARIANT) {
+ 		assert(column->column_varint_size == 4);
+ 	}
+-	tds.minor_version = 0;
+-	tds.major_version = 5;
++	tds.tds_version = 0x500;
+ 	varint_ok = varint_ok || tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
+-	tds.major_version = 7;
++	tds.tds_version = 0x700;
+ 	varint_ok = varint_ok || tds_get_varint_size(&tds, column->on_server.column_type) == column->column_varint_size;
+ 	assert(varint_ok);
+ 
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 22cfb0a..0223375 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.372 2009/08/21 10:11:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.373 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1100,7 +1100,7 @@ tds_process_tabname(TDSSOCKET *tds)
+ 	hdrsize = tds_get_smallint(tds);
+ 
+ 	/* different structure for tds8 */
+-	if (IS_TDS8_PLUS(tds))
++	if (IS_TDS71_PLUS(tds))
+ 		num_names = tds8_read_table_names(tds, hdrsize, &head);
+ 	else
+ 		num_names = tds_read_namelist(tds, hdrsize, &head, 1);
+@@ -1419,7 +1419,7 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	CHECK_COLUMN_EXTRA(curcol);
+ 
+ 	/*  User defined data type of the column */
+-	curcol->column_usertype = IS_TDS90(tds) ? tds_get_int(tds) : tds_get_smallint(tds);
++	curcol->column_usertype = IS_TDS72(tds) ? tds_get_int(tds) : tds_get_smallint(tds);
+ 
+ 	curcol->column_flags = tds_get_smallint(tds);	/*  Flags */
+ 
+@@ -1441,7 +1441,7 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	case 2:
+ 		curcol->column_size = tds_get_smallint(tds);
+ 		/* under TDS9 this means ?var???(MAX) */
+-		if (curcol->column_size < 0 && IS_TDS90(tds)) {
++		if (curcol->column_size < 0 && IS_TDS72(tds)) {
+ 			curcol->column_size = 0x3ffffffflu;
+ 			curcol->column_varint_size = 8;
+ 		}
+@@ -1463,7 +1463,7 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		/* FIXME check prec/scale, don't let server crash us */
+ 	}
+ 
+-	if (IS_TDS8_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) {
++	if (IS_TDS71_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) {
+ 		/* based on true type as sent by server */
+ 		/*
+ 		 * first 2 bytes are windows code (such as 0x409 for english)
+@@ -1481,11 +1481,11 @@ tds7_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	if (is_blob_type(curcol->column_type)) {
+ 		/* discard this additional byte */
+ 		/* TODO discover its meaning */
+-		if (IS_TDS90(tds))
++		if (IS_TDS72(tds))
+ 			tds_get_byte(tds);
+ 		curcol->table_namelen =
+ 			tds_get_string(tds, tds_get_smallint(tds), curcol->table_name, sizeof(curcol->table_name) - 1);
+-	} else if (IS_TDS90(tds) && curcol->column_type == SYBMSXML)
++	} else if (IS_TDS72(tds) && curcol->column_type == SYBMSXML)
+ 		tds_get_byte(tds);
+ 
+ 	/*
+@@ -1619,7 +1619,7 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 			, might_be_nullable	= 0x0800 
+ 		};
+ 		/* TODO: implement members in TDSCOLUMN */
+-		if (IS_TDS90(tds)) {
++		if (IS_TDS72(tds)) {
+ 			curcol->is_computed = 		(curcol->column_flags & (1 << 4)) > 1;
+ 			curcol->us_reserved_odbc1 = 	(curcol->column_flags & (1 << 5)) > 1;
+ 			curcol->us_reserved_odbc2 = 	(curcol->column_flags & (1 << 6)) > 1;
+@@ -1628,7 +1628,7 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ #endif 
+ 	} 
+ 
+-	if (IS_TDS90(tds)) {
++	if (IS_TDS72(tds)) {
+ 		tds_get_n(tds, NULL, 2);
+ #if 0
+ 		/* TODO: implement members in TDSCOLUMN, values untested */
+@@ -1677,7 +1677,7 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 
+ 	/* read sql collation info */
+ 	/* TODO: we should use it ! */
+-	if (IS_TDS8_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) {
++	if (IS_TDS71_PLUS(tds) && is_collate_type(curcol->on_server.column_type)) {
+ 		tds_get_n(tds, curcol->column_collation, 5);
+ 		curcol->char_conv =
+ 			tds_iconv_from_collate(tds, curcol->column_collation);
+@@ -2413,7 +2413,7 @@ tds_process_end(TDSSOCKET * tds, int marker, int *flags_parm)
+ 	 * have no result set.
+ 	 */
+ 
+-	rows_affected = IS_TDS90(tds) ? tds_get_int8(tds) : tds_get_int(tds);
++	rows_affected = IS_TDS72(tds) ? tds_get_int8(tds) : tds_get_int(tds);
+ 	tdsdump_log(TDS_DBG_FUNC, "                rows_affected = %" TDS_I64_FORMAT "\n", rows_affected);
+ 	if (done_count_valid)
+ 		tds->rows_affected = rows_affected;
+@@ -2496,7 +2496,7 @@ tds_process_env_chg(TDSSOCKET * tds)
+ 
+ 	/* discard byte values, not still supported */
+ 	/* TODO support them */
+-	if (IS_TDS8_PLUS(tds) && type > TDS_ENV_PACKSIZE) {
++	if (IS_TDS71_PLUS(tds) && type > TDS_ENV_PACKSIZE) {
+ 		/* discard new one */
+ 		tds_get_n(tds, NULL, tds_get_byte(tds));
+ 		/* discard old one */
+@@ -2653,7 +2653,7 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 	rc += tds_alloc_get_string(tds, &msg.proc_name, tds_get_byte(tds));
+ 
+ 	/* line number in the sql statement where the problem occured */
+-	msg.line_number = IS_TDS90(tds) ? tds_get_int(tds) : tds_get_smallint(tds);
++	msg.line_number = IS_TDS72(tds) ? tds_get_int(tds) : tds_get_smallint(tds);
+ 
+ 	/*
+ 	 * If the server doesen't provide an sqlstate, map one via server native errors
+diff --git a/src/tds/util.c b/src/tds/util.c
+index 6b6cd48..c4034d8 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.86 2009/04/18 19:35:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.87 2009/08/25 14:25:35 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -194,10 +194,10 @@ tds_version(TDSSOCKET * tds_socket, char *pversion_string)
+ 	int iversion = 0;
+ 
+ 	if (tds_socket) {
+-		iversion = 10 * tds_socket->major_version + tds_socket->minor_version;
++		iversion = 10 * TDS_MAJOR(tds_socket) + TDS_MINOR(tds_socket);
+ 
+ 		if (pversion_string) {
+-			sprintf(pversion_string, "%d.%d", tds_socket->major_version, tds_socket->minor_version);
++			sprintf(pversion_string, "%d.%d", TDS_MAJOR(tds_socket), TDS_MINOR(tds_socket));
+ 		}
+ 	}
+ 
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index e33dc76..6970710 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -159,7 +159,7 @@ write_all_strings(DSNINFO * di)
+ 	sprintf(tmp, "%u", di->connection->port);
+ 	WRITESTR("Port", tmp);
+ 
+-	sprintf(tmp, "%d.%d", di->connection->major_version, di->connection->minor_version);
++	sprintf(tmp, "%d.%d", TDS_MAJOR(di->connection), TDS_MINOR(di->connection));
+ 	WRITESTR("TDS_Version", tmp);
+ 
+ 	sprintf(tmp, "%u", di->connection->text_size);
+@@ -215,7 +215,7 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 	const char *pstr;
+ 	int major, minor, i;
+ 	static const char *protocols[] = {
+-		"TDS 4.2", "TDS 4.6", "TDS 5.0", "TDS 7.0", "TDS 8.0", NULL
++		"TDS 4.2", "TDS 4.6", "TDS 5.0", "TDS 7.0", "TDS 7.1", "TDS 7.2", NULL
+ 	};
+ 
+ 	switch (message) {
+@@ -232,7 +232,7 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 
+ 		/* copy info from DSNINFO to the dialog */
+ 		SendDlgItemMessage(hDlg, IDC_DSNNAME, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&di->dsn));
+-		sprintf(tmp, "TDS %d.%d", di->connection->major_version, di->connection->minor_version);
++		sprintf(tmp, "TDS %d.%d", TDS_MAJOR(di->connection), TDS_MINOR(di->connection));
+ 		SendDlgItemMessage(hDlg, IDC_PROTOCOL, CB_SELECTSTRING, -1, (LPARAM) tmp);
+ 		SendDlgItemMessage(hDlg, IDC_ADDRESS, WM_SETTEXT, 0, (LPARAM) tds_dstr_cstr(&di->connection->server_name));
+ 		sprintf(tmp, "%u", di->connection->port);
+@@ -261,8 +261,11 @@ DSNDlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
+ 		SendDlgItemMessage(hDlg, IDC_PROTOCOL, WM_GETTEXT, sizeof tmp, (LPARAM) tmp);
+ 		minor = 0;
+ 		if (sscanf(tmp, "%*[^0-9]%d.%d", &major, &minor) > 1) {
+-			di->connection->major_version = major;
+-			di->connection->minor_version = minor;
++			if (major == 8 && minor == 0) {
++				major = 7;
++				minor = 1;
++			}
++			di->connection->tds_version = (major << 8) | minor;
+ 		}
+ 		SendDlgItemMessage(hDlg, IDC_ADDRESS, WM_GETTEXT, sizeof tmp, (LPARAM) tmp);
+ 		tds_dstr_copy(&di->connection->server_name, tmp);
+
+commit 5acbbd11c741b81515fa8074a034bdac2c87c456
+Author: freddy77 <freddy77>
+Date:   Tue Aug 25 14:31:56 2009 +0000
+
+    update DBD::ODBC test, fix for config.rpath required
+
+diff --git a/ChangeLog b/ChangeLog
+index 1444d24..384ee4c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Aug 25 16:31:41 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild:
++	- update DBD::ODBC test, fix for config.rpath required
++
+ Tue Aug 25 16:23:49 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/freebcp.txt doc/freetds.conf.5 doc/tds_ssl.html:
+ 	* doc/userguide.sgml include/sybdb.h include/tds.h src/dblib/bcp.c:
+@@ -1796,4 +1800,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2858 2009/08/25 14:25:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2859 2009/08/25 14:31:56 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index f77f187..848e34c 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -1,5 +1,12 @@
+ #!/bin/bash
+ 
++# Requirements:
++# - DBD-ODBC in upper directory
++# - PWD* files
++# - gawk, lcov packages
++# - fixdoxyres, vg_test, classifier commands
++# - freetds_autobuild.sh and suppressions.supp configurations
++
+ export PATH="/usr/kerberos/bin:/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/usr/lib/jre/bin:$HOME/bin:$HOME/install/bin"
+ 
+ . $HOME/.bashrc
+@@ -116,12 +123,13 @@ find . \( -name \*.bb -o -name \*.bbg -o -name \*.da -o -name \*.gc\* \) -exec r
+ rm -rf autom4te.cache doc/doc covtmp coverage DBD-*
+ cvsclean || true
+ if test "$(uname -m)" = "x86_64"; then
+-	cp ../DBD-ODBC-1.16.tar.gz .
++	cp ../DBD-ODBC-1.22.tar.gz .
+ else
+ 	cp ../DBD-ODBC-1.13.tar.gz .
+ fi
+ cp ../php5.2-latest.tar.bz2 .
+ 
++cp ../freetds83/config.rpath .
+ LDFLAGS='-lgcov' CFLAGS='-O0 -pipe -g -fprofile-arcs -ftest-coverage' sh autogen.sh --enable-extra-checks --prefix=$HOME/install --with-odbc-nodm=/usr --with-gnutls $FLAGS_ADD
+ 
+ # compile, test with mssql server
+
+commit 5aac5caedc607d043b5368fde235913aba252221
+Author: freddy77 <freddy77>
+Date:   Wed Aug 26 12:17:31 2009 +0000
+
+    test-dist now works with new configure script
+
+diff --git a/ChangeLog b/ChangeLog
+index 384ee4c..3c83547 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Aug 26 14:16:00 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-dist.sh: test-dist now works with new configure script
++
+ Tue Aug 25 16:31:41 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild:
+ 	- update DBD::ODBC test, fix for config.rpath required
+@@ -1800,4 +1803,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2859 2009/08/25 14:31:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2860 2009/08/26 12:17:31 freddy77 Exp $
+diff --git a/misc/test-dist.sh b/misc/test-dist.sh
+index 73cbf7f..02b5080 100755
+--- a/misc/test-dist.sh
++++ b/misc/test-dist.sh
+@@ -69,16 +69,15 @@ cd fakebin
+ echo "#!/bin/sh
+ exit 1" > openjade
+ cp openjade doxygen
+-# gawk it's used by txt2man
+-cp openjade gawk
++cp openjade txt2man
+ cp openjade autoheader
+ # perl is used by some perl rules
+ cp openjade perl
+-chmod +x openjade doxygen gawk autoheader perl
++chmod +x openjade doxygen txt2man autoheader perl
+ cd ..
+ if ! openjade --help; then true; else echo 'succedeed ?'; false; fi
+ if ! doxygen --help; then true; else echo 'succeeded ?'; false; fi
+-if ! gawk --help; then true; else echo 'succeeded ?'; false; fi
++if ! txt2man --help; then true; else echo 'succeeded ?'; false; fi
+ if ! autoheader --help; then true; else echo 'succeeded ?'; false; fi
+ if ! perl --help; then true; else echo 'succeeded ?'; false; fi
+ echo "fakebin ok" >> "$LOG"
+
+commit 946b07897ec3db52d5d1c98d3aed4266d7b401e7
+Author: freddy77 <freddy77>
+Date:   Wed Aug 26 12:19:01 2009 +0000
+
+    make check now works if configure was launched from another directory
+
+diff --git a/ChangeLog b/ChangeLog
+index 3c83547..8e46f72 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Aug 26 14:18:35 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c:
++	- make check now works if configure was launched from another
++	  directory
++
+ Wed Aug 26 14:16:00 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/test-dist.sh: test-dist now works with new configure script
+ 
+@@ -1803,4 +1808,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2860 2009/08/26 12:17:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2861 2009/08/26 12:19:01 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 337c4d7..016466e 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.36 2009/04/17 09:54:27 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.37 2009/08/26 12:19:01 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -245,7 +245,7 @@ read_login_info(int argc, char **argv)
+ #if 0
+ 	dbrecftos(BASENAME);
+ #endif
+-	len = snprintf(sql_file, sizeof(sql_file), "%s.sql", BASENAME);
++	len = snprintf(sql_file, sizeof(sql_file), "%s/%s.sql", FREETDS_SRCDIR, BASENAME);
+ 	assert(len <= sizeof(sql_file));
+ 
+ 	if ((input_file = fopen(sql_file, "r")) == NULL) {
+
+commit 78abd84383a8eac4cee167b49abfb245b3762419
+Author: freddy77 <freddy77>
+Date:   Wed Aug 26 12:32:11 2009 +0000
+
+    more fixes for varchar(max)/varbinary(max)
+
+diff --git a/ChangeLog b/ChangeLog
+index 8e46f72..6558e6f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Aug 26 14:31:33 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c src/tds/data.c:
++	* src/tds/query.c src/tds/tds_checks.c src/tds/token.c:
++	- more fixes for varchar(max)/varbinary(max)
++
+ Wed Aug 26 14:18:35 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c:
+ 	- make check now works if configure was launched from another
+@@ -1808,4 +1813,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2861 2009/08/26 12:19:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2862 2009/08/26 12:32:11 freddy77 Exp $
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index 7d57bc4..d5493e5 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.83 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.84 2009/08/26 12:32:11 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -366,7 +366,7 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+ 			if (curcol->column_data && curcol->column_data_free)
+ 				curcol->column_data_free(curcol);
+ 			curcol->column_data_free = NULL;
+-			if (dest_type == SYBNTEXT || dest_type == SYBTEXT) {
++			if (is_blob_col(curcol)) {
+ 				TDSBLOB *blob = (TDSBLOB *) calloc(1, sizeof(TDSBLOB));
+ 				if (!blob) {
+ 					odbc_errs_add(&stmt->errs, "HY001", NULL);
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 8411ed6..29ba46d 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.43 2009/05/27 17:58:02 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.44 2009/08/26 12:32:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -432,6 +432,13 @@ AllTests(void)
+ 		TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
+ 		TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
+ 	}
++	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
++		TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARCHAR(MAX)", "1EasyTest");
++		TestInput(SQL_C_BINARY, "VARBINARY(20)", SQL_LONGVARBINARY, "VARBINARY(MAX)", "Anything will suite!");
++#ifdef ENABLE_DEVELOPING
++		TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARBINARY(MAX)", "1EasyTest");
++#endif
++	}
+ }
+ 
+ int
+diff --git a/src/tds/data.c b/src/tds/data.c
+index c8a4767..c9a5866 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,7 +35,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.23 2009/08/21 10:11:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: data.c,v 1.24 2009/08/26 12:32:11 freddy77 Exp $");
+ 
+ /**
+  * Set type of column initializing all dependency 
+@@ -128,6 +128,24 @@ tds_set_param_type(TDSSOCKET * tds, TDSCOLUMN * curcol, TDS_SERVER_TYPE type)
+ 		curcol->column_varint_size = 1;
+ 		curcol->column_cur_size = -1;
+ 		break;
++	case SYBNTEXT:
++		if (IS_TDS72(tds)) {
++			curcol->column_varint_size = 8;
++			curcol->on_server.column_type = XSYBNVARCHAR;
++		}
++		break;
++	case SYBTEXT:
++		if (IS_TDS72(tds)) {
++			curcol->column_varint_size = 8;
++			curcol->on_server.column_type = XSYBVARCHAR;
++		}
++		break;
++	case SYBIMAGE:
++		if (IS_TDS72(tds)) {
++			curcol->column_varint_size = 8;
++			curcol->on_server.column_type = XSYBVARBINARY;
++		}
++		break;
+ 	default:
+ 		break;
+ 	}
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 0e96adb..6723a0b 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.240 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.241 2009/08/26 12:32:11 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -624,7 +624,10 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 		break;
+ 	case SYBVARCHAR:
+ 	case XSYBVARCHAR:
+-		fmt = "VARCHAR(%u)";
++		if (curcol->column_varint_size == 8)
++			fmt = "VARCHAR(MAX)";
++		else
++			fmt = "VARCHAR(%u)";
+ 		break;
+ 	case SYBINT1:
+ 		fmt = "TINYINT";
+@@ -673,7 +676,10 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 		break;
+ 	case SYBVARBINARY:
+ 	case XSYBVARBINARY:
+-		fmt = "VARBINARY(%u)";
++		if (curcol->column_varint_size == 8)
++			fmt = "VARBINARY(MAX)";
++		else
++			fmt = "VARBINARY(%u)";
+ 		break;
+ 	case SYBNUMERIC:
+ 		fmt = "NUMERIC(%d,%d)";
+@@ -694,7 +700,9 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 		break;
+ 	case SYBNVARCHAR:
+ 	case XSYBNVARCHAR:
+-		if (IS_TDS7_PLUS(tds)) {
++		if (curcol->column_varint_size == 8) {
++			fmt = "NVARCHAR(MAX)";
++		} else if (IS_TDS7_PLUS(tds)) {
+ 			fmt = "NVARCHAR(%u)";
+ 			max_len = 4000;
+ 			size /= 2u;
+@@ -1382,6 +1390,9 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 		case 4:
+ 			tds_put_int(tds, size);
+ 			break;
++		case 8:
++			tds_put_smallint(tds, 0xffff);
++			break;
+ 		}
+ 	}
+ 
+@@ -1456,6 +1467,9 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		case 2:
+ 			tds_put_smallint(tds, -1);
+ 			break;
++		case 8:
++			tds_put_int8(tds, -1);
++			break;
+ 		default:
+ 			assert(curcol->column_varint_size);
+ 			/* FIXME not good for SYBLONGBINARY/SYBLONGCHAR (still not supported) */
+@@ -1511,6 +1525,10 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			    curcol->column_varint_size);
+ 
+ 		switch (curcol->column_varint_size) {
++		case 8:
++			tds_put_int8(tds, colsize);
++			tds_put_int(tds, colsize);
++			break;
+ 		case 4:	/* It's a BLOB... */
+ 			colsize = MIN(colsize, size);
+ 			/* mssql require only size */
+@@ -1560,6 +1578,9 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ #endif
+ 			tds_put_n(tds, s, colsize);
+ 		}
++		/* finish chunk for varchar/varbinary(max) */
++		if (curcol->column_varint_size == 8 && colsize)
++			tds_put_int(tds, 0);
+ 	} else {
+ 		/* TODO ICONV handle charset conversions for data */
+ 		/* put size of data */
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index 108c247..fbe6857 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.26 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.27 2009/08/26 12:32:11 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -191,16 +191,21 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	assert(strlen(column->column_name) < sizeof(column->column_name));
+ 
+ 	/* check type and server type same or SQLNCHAR -> SQLCHAR */
++#define SPECIAL(type, server_type, varint) \
++	if (column->column_type == type && column->on_server.column_type == server_type && column->column_varint_size == varint) {} else
++	SPECIAL(SYBTEXT, XSYBVARCHAR, 8)
++	SPECIAL(SYBTEXT, XSYBNVARCHAR, 8)
++	SPECIAL(SYBIMAGE, XSYBVARBINARY, 8)
+ 	assert(tds_get_cardinal_type(column->on_server.column_type) == column->column_type
+-		|| (tds_get_null_type(column->column_type) == column->on_server.column_type 
++		|| (tds_get_null_type(column->column_type) == column->on_server.column_type
+ 		&& column->column_varint_size == 1 && is_fixed_type(column->column_type)));
+ 
+ 	varint_ok = 0;
+-	if (is_blob_type(column->column_type)) {
+-		assert(column->column_varint_size >= 4);
+-	} else if (column->column_varint_size == 8) {
++	if (column->column_varint_size == 8) {
+ 		assert(column->on_server.column_type == XSYBVARCHAR || column->on_server.column_type == XSYBVARBINARY || column->on_server.column_type == XSYBNVARCHAR || column->on_server.column_type == SYBMSXML);
+ 		varint_ok = 1;
++	} else if (is_blob_type(column->column_type)) {
++		assert(column->column_varint_size >= 4);
+ 	} else if (column->column_type == SYBVARIANT) {
+ 		assert(column->column_varint_size == 4);
+ 	}
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 0223375..f61eef6 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.373 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.374 2009/08/26 12:32:11 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1659,6 +1659,11 @@ tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param)
+ 	case 2:
+ 		/* assure > 0 */
+ 		curcol->column_size = tds_get_smallint(tds);
++                /* under TDS9 this means ?var???(MAX) */
++		if (curcol->column_size < 0 && IS_TDS72(tds)) {
++			curcol->column_size = 0x3ffffffflu;
++			curcol->column_varint_size = 8;
++		}
+ 		break;
+ 	case 1:
+ 		curcol->column_size = tds_get_byte(tds);
+
+commit b54a9ab7c4ad113eb14d8211807e8c36257472d3
+Author: freddy77 <freddy77>
+Date:   Thu Aug 27 12:32:14 2009 +0000
+
+    update genparams test
+
+diff --git a/ChangeLog b/ChangeLog
+index 6558e6f..0edb58c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug 27 14:31:52 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/genparams.c: update genparams test
++
+ Wed Aug 26 14:31:33 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/sql2tds.c src/odbc/unittests/genparams.c src/tds/data.c:
+ 	* src/tds/query.c src/tds/tds_checks.c src/tds/token.c:
+@@ -1813,4 +1816,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2862 2009/08/26 12:32:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2863 2009/08/27 12:32:14 freddy77 Exp $
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index 29ba46d..c3eaa8d 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.44 2009/08/26 12:32:11 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.45 2009/08/27 12:32:14 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -297,11 +297,12 @@ AllTests(void)
+ 	TestOutput("NUMERIC(18,2)", "123", SQL_C_NUMERIC, SQL_NUMERIC, "38 0 1 7B");
+ 	TestInput(SQL_C_LONG, "INTEGER", SQL_VARCHAR, "VARCHAR(20)", "12345");
+ 	TestInput(SQL_C_LONG, "INTEGER", SQL_LONGVARCHAR, "TEXT", "12345");
+-	/* MS driver behavior for output parameters is different */
++	/*
++	 * MS driver behavior for output parameters is different
++	 * former returns "313233" while newer "333133323333"
++	 */
+ 	if (driver_is_freetds())
+ 		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");
+-	else
+-		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "313233");
+ 	/* FIXME our driver ignore precision for date */
+ 	precision = 3;
+ 	/* Some MS driver incorrectly prepare with smalldatetime*/
+@@ -435,9 +436,6 @@ AllTests(void)
+ 	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
+ 		TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARCHAR(MAX)", "1EasyTest");
+ 		TestInput(SQL_C_BINARY, "VARBINARY(20)", SQL_LONGVARBINARY, "VARBINARY(MAX)", "Anything will suite!");
+-#ifdef ENABLE_DEVELOPING
+-		TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARBINARY(MAX)", "1EasyTest");
+-#endif
+ 	}
+ }
+ 
+
+commit 9a2038c24dc0b211a0d9a1f84748be92ee778879
+Author: freddy77 <freddy77>
+Date:   Thu Aug 27 13:37:40 2009 +0000
+
+    override odbcinst.ini in cancel test to avoid hang using unixODBC
+
+diff --git a/ChangeLog b/ChangeLog
+index 0edb58c..5d1ab3a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Aug 27 15:36:42 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cancel.c:
++	- override odbcinst.ini in cancel test to avoid hang using unixODBC
++
+ Thu Aug 27 14:31:52 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/genparams.c: update genparams test
+ 
+@@ -1816,4 +1820,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2863 2009/08/27 12:32:14 freddy77 Exp $
++$Id: ChangeLog,v 1.2864 2009/08/27 13:37:40 freddy77 Exp $
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index be887a0..1f9a4b8 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -120,6 +120,28 @@ Test(int use_threads)
+ int
+ main(int argc, char **argv)
+ {
++	if (read_login_info())
++		exit(1);
++
++	/*
++	 * prepare our odbcinst.ini
++	 * is better to do it before connect cause uniODBC cache INIs
++	 * the name must be odbcinst.ini cause unixODBC accept only this name
++	 */
++	if (DRIVER[0]) {
++		FILE *f = fopen("odbcinst.ini", "w");
++
++		if (f) {
++			fprintf(f, "[FreeTDS]\nDriver = %s\nThreading = 0\n", DRIVER);
++			fclose(f);
++			/* force iODBC */
++			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
++			setenv("SYSODBCINSTINI", "./odbcinst.ini", 1);
++			/* force unixODBC (only directory) */
++			setenv("ODBCSYSINI", ".", 1);
++		}
++	}
++
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+
+commit 95eb12afe18d4fe2a47f548238da5fc730a8c0de
+Author: freddy77 <freddy77>
+Date:   Tue Sep 1 05:47:31 2009 +0000
+
+    add and fix test for numeric in dblib
+
+diff --git a/ChangeLog b/ChangeLog
+index 5d1ab3a..a87a933 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Tue Sep  1 07:47:25 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/rpc.c src/dblib/unittests/.cvsignore:
++	* src/dblib/unittests/Makefile.am src/dblib/unittests/common.c:
++	* src/dblib/unittests/common.h src/dblib/unittests/numeric.c:
++	* src/dblib/unittests/numeric.sql:
++	- add and fix test for numeric in dblib
++
+ Thu Aug 27 15:36:42 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cancel.c:
+ 	- override odbcinst.ini in cancel test to avoid hang using unixODBC
+@@ -1820,4 +1827,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2864 2009/08/27 13:37:40 freddy77 Exp $
++$Id: ChangeLog,v 1.2865 2009/09/01 05:47:31 freddy77 Exp $
+diff --git a/src/dblib/rpc.c b/src/dblib/rpc.c
+index a335112..fa1d1b6 100644
+--- a/src/dblib/rpc.c
++++ b/src/dblib/rpc.c
+@@ -54,7 +54,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: rpc.c,v 1.69 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: rpc.c,v 1.70 2009/09/01 05:47:31 freddy77 Exp $");
+ 
+ static void rpc_clear(DBREMOTE_PROC * rpc);
+ static void param_clear(DBREMOTE_PROC_PARAM * pparam);
+@@ -335,6 +335,8 @@ param_row_alloc(TDSPARAMINFO * params, TDSCOLUMN * curcol, int param_num, void *
+ 	if (size > 0 && value) {
+ 		tdsdump_log(TDS_DBG_FUNC, "copying %d bytes of data to parameter #%d\n", size, param_num);
+ 		if (!is_blob_col(curcol)) {
++			if (is_numeric_type(curcol->column_type))
++				memset(curcol->column_data, 0, sizeof(TDS_NUMERIC));
+ 			memcpy(curcol->column_data, value, size);
+ 		} else {
+ 			TDSBLOB *blob = (TDSBLOB *) curcol->column_data;
+@@ -398,6 +400,15 @@ param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc)
+ 
+ 		tdsdump_log(TDS_DBG_INFO1, "parm_info_alloc(): parameter null-ness = %d\n", param_is_null);
+ 
++		pcol = params->columns[i];
++
++		if (temp_value && is_numeric_type(temp_type)) {
++			DBDECIMAL *dec = (DBDECIMAL*) temp_value;
++			pcol->column_prec = dec->precision;
++			pcol->column_scale = dec->scale;
++			if (dec->precision > 0 && dec->precision <= MAXPRECISION)
++				temp_datalen = tds_numeric_bytes_per_prec[dec->precision] + 2;
++		}
+ 		if (param_is_null || (p->status & DBRPCRETURN)) {
+ 			if (param_is_null) {
+ 				temp_datalen = 0;
+@@ -410,8 +421,6 @@ param_info_alloc(TDSSOCKET * tds, DBREMOTE_PROC * rpc)
+ 			temp_datalen = tds_get_size_by_type(temp_type);
+ 		}
+ 
+-		pcol = params->columns[i];
+-
+ 		/* meta data */
+ 		if (p->name) {
+ 			tds_strlcpy(pcol->column_name, p->name, sizeof(pcol->column_name));
+diff --git a/src/dblib/unittests/.cvsignore b/src/dblib/unittests/.cvsignore
+index 691f42b..2d8e014 100644
+--- a/src/dblib/unittests/.cvsignore
++++ b/src/dblib/unittests/.cvsignore
+@@ -45,4 +45,5 @@ hang
+ null
+ null2
+ setnull
++numeric
+ 
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index 3fec4e6..df43a20 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.48 2009/03/17 13:34:39 freddy77 Exp $
++# $Id: Makefile.am,v 1.49 2009/09/01 05:47:31 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -10,13 +10,13 @@ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			bcp$(EXEEXT) thread$(EXEEXT) text_buffer$(EXEEXT)\
+ 			done_handling$(EXEEXT) timeout$(EXEEXT) \
+ 			hang$(EXEEXT) null$(EXEEXT) null2$(EXEEXT) \
+-			setnull$(EXEEXT)
++			setnull$(EXEEXT) numeric$(EXEEXT)
+ check_PROGRAMS	=	$(TESTS)
+ 
+ SQL_DIST = 	bcp.sql dbmorecmds.sql done_handling.sql rpc.sql \
+ 		t0001.sql t0002.sql t0003.sql t0004.sql t0005.sql t0006.sql t0007.sql t0009.sql \
+ 		t0011.sql t0012.sql t0013.sql t0014.sql t0015.sql t0016.sql t0017.sql t0018.sql \
+-		t0020.sql t0022.sql t0023.sql text_buffer.sql timeout.sql
++		t0020.sql t0022.sql t0023.sql text_buffer.sql timeout.sql numeric.sql
+ 
+ noinst_SCRIPTS	= $(SQL_DIST)
+ 
+@@ -53,6 +53,7 @@ hang_SOURCES	=	hang.c common.c common.h
+ null_SOURCES	=	null.c common.c common.h
+ null2_SOURCES	=	null2.c common.c common.h
+ setnull_SOURCES	=	setnull.c common.c common.h
++numeric_SOURCES =	numeric.c common.c common.h
+ 
+ AM_CPPFLAGS	= 	-DFREETDS_SRCDIR=\"$(srcdir)\" -I$(top_srcdir)/include
+ if MINGW32
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 016466e..0eedcab 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -14,7 +14,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.37 2009/08/26 12:19:01 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.38 2009/09/01 05:47:31 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -271,7 +271,12 @@ sql_cmd(DBPROCESS *dbproc)
+ 	char line[2048], *p = line;
+ 	int i = 0;
+ 	RETCODE erc=SUCCEED;
+-	
++
++	if (!input_file) {
++		fprintf(stderr, "%s: error: SQL input file \"%s\" not opened\n", BASENAME, sql_file);
++		exit(1);
++	}
++
+ 	while ((p = fgets(line, (int)sizeof(line), input_file)) != NULL && strcasecmp("go\n", p) != 0) {
+ 		printf("\t%3d: %s", ++i, p);
+ 		if ((erc = dbcmd(dbproc, p)) != SUCCEED) {
+@@ -288,6 +293,15 @@ sql_cmd(DBPROCESS *dbproc)
+ 	return erc;
+ }
+ 
++RETCODE
++sql_rewind(void)
++{
++	if (!input_file)
++		return FAIL;
++	rewind(input_file);
++	return SUCCEED;
++}
++
+ void
+ check_crumbs(void)
+ {
+diff --git a/src/dblib/unittests/common.h b/src/dblib/unittests/common.h
+index e167ce3..bfd7e5a 100644
+--- a/src/dblib/unittests/common.h
++++ b/src/dblib/unittests/common.h
+@@ -2,7 +2,7 @@
+ #ifndef COMMON_h
+ #define COMMON_h
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.19 2009/05/28 16:15:29 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.20 2009/09/01 05:47:31 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #if HAVE_CONFIG_H
+@@ -92,6 +92,7 @@ int syb_msg_handler(DBPROCESS * dbproc,
+ int syb_err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ 
+ RETCODE sql_cmd(DBPROCESS *dbproc);
++RETCODE sql_rewind(void);
+ 
+ #define int2ptr(i) ((void*)(((char*)0)+(i)))
+ #define ptr2int(p) ((int)(((char*)(p))-((char*)0)))
+diff --git a/src/dblib/unittests/numeric.c b/src/dblib/unittests/numeric.c
+new file mode 100644
+index 0000000..d23c7db
+--- /dev/null
++++ b/src/dblib/unittests/numeric.c
+@@ -0,0 +1,161 @@
++#define MSDBLIB 1
++#include "common.h"
++
++static void
++dump_addr(FILE *out, const char *msg, const void *p, size_t len)
++{
++	size_t n;
++	if (msg)
++		fprintf(out, "%s", msg);
++	for (n = 0; n < len; ++n)
++		fprintf(out, " %02X", ((unsigned char*) p)[n]);
++	fprintf(out, "\n");
++}
++
++static void
++chk(RETCODE ret, const char *msg)
++{
++	printf("res %d\n", ret);
++	if (ret == SUCCEED)
++		return;
++	fprintf(stderr, "error: %s\n", msg);
++	exit(1);
++}
++
++static void
++test(int bind_type)
++{
++	LOGINREC *login;
++	DBPROCESS *dbproc;
++	DBNUMERIC *num = NULL, *num2 = NULL;
++	RETCODE ret;
++	int i;
++
++	sql_rewind();
++	login = dblogin();
++
++	DBSETLUSER(login, USER);
++	DBSETLPWD(login, PASSWORD);
++	DBSETLAPP(login, "numeric");
++	dbsetmaxprocs(25);
++	DBSETLHOST(login, SERVER);
++
++	dbproc = dbopen(login, SERVER);
++	dbloginfree(login);
++	login = NULL;
++	if (strlen(DATABASE))
++		dbuse(dbproc, DATABASE);
++
++	sql_cmd(dbproc);
++	dbsqlexec(dbproc);
++	while (dbresults(dbproc) != NO_MORE_RESULTS) {
++		/* nop */
++	}
++
++	sql_cmd(dbproc);
++	dbsqlexec(dbproc);
++	while (dbresults(dbproc) != NO_MORE_RESULTS) {
++		/* nop */
++	}
++
++	ret = dbcmd(dbproc,
++		    "SET ARITHABORT ON;"
++		    "SET CONCAT_NULL_YIELDS_NULL ON;"
++		    "SET ANSI_NULLS ON;"
++		    "SET ANSI_NULL_DFLT_ON ON;"
++		    "SET ANSI_PADDING ON;"
++		    "SET ANSI_WARNINGS ON;"
++		    "SET ANSI_NULL_DFLT_ON ON;"
++		    "SET CURSOR_CLOSE_ON_COMMIT ON;"
++		    "SET QUOTED_IDENTIFIER ON");
++	chk(ret, "dbcmd");
++	ret = dbsqlexec(dbproc);
++	chk(ret, "dbsqlexec");
++
++	ret = dbcancel(dbproc);
++	chk(ret, "dbcancel");
++
++	ret = dbrpcinit(dbproc, "testDecimal", 0);
++	chk(ret, "dbrpcinit");
++
++	num = (DBDECIMAL *) calloc(1, sizeof(DBDECIMAL));
++	num->scale = 5;
++	num->precision = 16;
++	dbconvert(dbproc, SYBVARCHAR, (const BYTE *) "123.45", -1, SYBDECIMAL, (BYTE *) num, sizeof(*num));
++
++	ret = dbrpcparam(dbproc, "@idecimal", 0, SYBDECIMAL, -1, sizeof(DBDECIMAL), (BYTE *) num);
++	chk(ret, "dbrpcparam");
++	ret = dbrpcsend(dbproc);
++	chk(ret, "dbrpcsend");
++	ret = dbsqlok(dbproc);
++	chk(ret, "dbsqlok");
++
++	/* TODO check MS/Sybase format */
++	num2 = (DBDECIMAL *) calloc(1, sizeof(DBDECIMAL));
++	num2->precision = 20;
++	num2->scale = 10;
++	dbconvert(dbproc, SYBVARCHAR, (const BYTE *) "246.9", -1, SYBDECIMAL, (BYTE *) num2, sizeof(*num2));
++
++	for (i=0; (ret = dbresults(dbproc)) != NO_MORE_RESULTS; ++i) {
++		RETCODE row_code;
++
++		switch (ret) {
++		case SUCCEED:
++			if (DBROWS(dbproc) == FAIL)
++				continue;
++			assert(DBROWS(dbproc) == SUCCEED);
++			printf("dbrows() returned SUCCEED, processing rows\n");
++
++			memset(num, 0, sizeof(*num));
++			num->precision = num2->precision;
++			num->scale = num2->scale;
++			dbbind(dbproc, 1, bind_type, 0, (BYTE *) num);
++
++			while ((row_code = dbnextrow(dbproc)) != NO_MORE_ROWS) {
++				if (row_code == REG_ROW) {
++					if (memcmp(num, num2, sizeof(*num)) != 0) {
++						fprintf(stderr, "Failed. Output results does not match\n");
++						dump_addr(stderr, "numeric: ", num, sizeof(*num));
++						dump_addr(stderr, "numeric2:", num2, sizeof(*num2));
++						exit(1);
++					}
++				} else {
++					/* not supporting computed rows in this unit test */
++					fprintf(stderr, "Failed.  Expected a row\n");
++					exit(1);
++				}
++			}
++			break;
++		case FAIL:
++			fprintf(stderr, "dbresults returned FAIL\n");
++			exit(1);
++		default:
++			fprintf(stderr, "unexpected return code %d from dbresults\n", ret);
++			exit(1);
++		}
++	} /* while dbresults */
++
++	sql_cmd(dbproc);
++
++	free(num2);
++	free(num);
++
++	dbclose(dbproc);
++}
++
++int
++main(int argc, char **argv)
++{
++	read_login_info(argc, argv);
++
++	dbinit();
++
++	test(DECIMALBIND);
++	test(NUMERICBIND);
++
++	dbexit();
++
++	printf("Succeed\n");
++	return 0;
++}
++
+diff --git a/src/dblib/unittests/numeric.sql b/src/dblib/unittests/numeric.sql
+new file mode 100644
+index 0000000..c52b220
+--- /dev/null
++++ b/src/dblib/unittests/numeric.sql
+@@ -0,0 +1,12 @@
++IF OBJECT_ID('testDecimal') IS NOT NULL DROP PROC testDecimal
++go
++CREATE PROCEDURE testDecimal
++  @idecimal NUMERIC(20,10)
++AS
++BEGIN
++	SELECT @idecimal*2
++END
++go
++IF OBJECT_ID('testDecimal') IS NOT NULL DROP PROC testDecimal
++go
++
+
+commit fd07644252996feaf0d724e3fef0455cad7aa8e9
+Author: freddy77 <freddy77>
+Date:   Tue Sep 1 08:02:36 2009 +0000
+
+    fix numeric -> numeric conversions
+
+diff --git a/ChangeLog b/ChangeLog
+index a87a933..8ff8f21 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Sep  1 10:01:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix numeric -> numeric conversions
++
+ Tue Sep  1 07:47:25 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/rpc.c src/dblib/unittests/.cvsignore:
+ 	* src/dblib/unittests/Makefile.am src/dblib/unittests/common.c:
+@@ -1827,4 +1830,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2865 2009/09/01 05:47:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2866 2009/09/01 08:02:36 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index f80892b..15956f3 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.352 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.353 2009/09/01 08:02:36 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -2190,8 +2190,19 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 	if (srclen == -1)
+ 		srclen = (int)strlen((const char *) src);
+ 
++	/* FIXME what happen if client do not reset values ??? */
++	/* FIXME act differently for ms and sybase */
++	if (is_numeric_type(desttype)) {
++		num = (DBNUMERIC *) dest;
++		if (num->precision <= 0 || num->precision > MAXPRECISION || num->scale < 0 || num->scale > num->precision) {
++			dres.n.precision = 18;
++			dres.n.scale = 0;
++		} else {
++			dres.n.precision = num->precision;
++			dres.n.scale = num->scale;
++		}
+ 	/* oft times we are asked to convert a data type to itself */
+-	if (srctype == desttype) {
++	} else if (srctype == desttype) {
+ 		ret = -2;  /* to make sure we always set it */
+ 		tdsdump_log(TDS_DBG_INFO1, "dbconvert() srctype == desttype\n");
+ 		switch (desttype) {
+@@ -2262,12 +2273,6 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 			memcpy(dest, src, ret);
+ 			break;
+ 
+-		case SYBNUMERIC:
+-		case SYBDECIMAL:
+-			memcpy(dest, src, sizeof(DBNUMERIC));
+-			ret = sizeof(DBNUMERIC);
+-			break;
+-
+ 		default:
+ 			ret = -1;
+ 			break;
+@@ -2276,7 +2281,6 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 		return ret;
+ 	}
+ 	/* end srctype == desttype */
+-	assert(srctype != desttype);
+ 
+ 	/*
+ 	 * Character types need no conversion.  Just move the data.
+@@ -2288,20 +2292,6 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 		}
+ 	}
+ 
+-	/* FIXME what happen if client do not reset values ??? */
+-	/* FIXME act differently for ms and sybase */
+-	if (is_numeric_type(desttype)) {
+-		num = (DBNUMERIC *) dest;
+-		if (num->precision == 0)
+-			dres.n.precision = 18;
+-		else
+-			dres.n.precision = num->precision;
+-		if (num->scale == 0)
+-			dres.n.scale = 0;
+-		else
+-			dres.n.scale = num->scale;
+-	}
+-
+ 	tdsdump_log(TDS_DBG_INFO1, "dbconvert() calling tds_convert\n");
+ 
+ 	len = tds_convert(g_dblib_ctx.tds_ctx, srctype, (const TDS_CHAR *) src, srclen, desttype, &dres);
+@@ -7125,7 +7115,16 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
+ 
+ 	/* oft times we are asked to convert a data type to itself */
+ 
+-	if ((srctype == desttype) ||
++	if (is_numeric_type(desttype)) {
++		num = (DBNUMERIC *) dest;
++		if (num->precision <= 0 || num->precision > MAXPRECISION || num->scale < 0 || num->scale > num->precision) {
++			dres.n.precision = 18;
++			dres.n.scale = 0;
++		} else {
++			dres.n.precision = num->precision;
++			dres.n.scale = num->scale;
++		}
++	} else if ((srctype == desttype) ||
+ 		(is_similar_type(srctype, desttype))) {
+ 
+ 		tdsdump_log(TDS_DBG_INFO1, "copy_data_to_host_var() srctype == desttype\n");
+@@ -7220,11 +7219,6 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
+ 			memcpy(dest, src, ret);
+ 			break;
+ 
+-		case SYBNUMERIC:
+-		case SYBDECIMAL:
+-			memcpy(dest, src, sizeof(DBNUMERIC));
+-			break;
+-
+ 		default:
+ 			break;
+ 		}
+@@ -7235,20 +7229,6 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
+ 
+ 	} /* end srctype == desttype */
+ 
+-	assert(srctype != desttype);
+-
+-	if (is_numeric_type(desttype)) {
+-		num = (DBNUMERIC *) dest;
+-		if (num->precision == 0)
+-			dres.n.precision = 18;
+-		else
+-			dres.n.precision = num->precision;
+-		if (num->scale == 0)
+-			dres.n.scale = 0;
+-		else
+-			dres.n.scale = num->scale;
+-	}
+-
+ 	len = tds_convert(g_dblib_ctx.tds_ctx, srctype, (const TDS_CHAR *) src, srclen, desttype, &dres);
+ 
+ 	tdsdump_log(TDS_DBG_INFO1, "copy_data_to_host_var(): tds_convert returned %d\n", len);
+
+commit bccebe937d719f8bf2d856dae16113be8dbc62d9
+Author: freddy77 <freddy77>
+Date:   Wed Sep 2 07:22:42 2009 +0000
+
+    update check_symbols.txt
+
+diff --git a/misc/check_symbols.txt b/misc/check_symbols.txt
+index c902c46..cc67f42 100644
+--- a/misc/check_symbols.txt
++++ b/misc/check_symbols.txt
+@@ -34,6 +34,7 @@ tds_bcp_send_record
+ tds_bcp_start
+ tds_bcp_start_copy_in
+ tds_canonical_charset_name
++tds_char2hex
+ tds_check_column_extra
+ tds_check_context_extra
+ tds_check_cursor_extra
+
+commit 8dfb5598acf4356172650f5f8c35acc0d37de805
+Author: freddy77 <freddy77>
+Date:   Wed Sep 2 09:27:01 2009 +0000
+
+    fix dblib numeric test for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 8ff8f21..3c157b2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Sep  2 11:26:14 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/numeric.c: fix dblib numeric test for Sybase
++
+ Tue Sep  1 10:01:45 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: fix numeric -> numeric conversions
+ 
+@@ -1830,4 +1833,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2866 2009/09/01 08:02:36 freddy77 Exp $
++$Id: ChangeLog,v 1.2867 2009/09/02 09:27:01 freddy77 Exp $
+diff --git a/src/dblib/unittests/numeric.c b/src/dblib/unittests/numeric.c
+index d23c7db..c4cb852 100644
+--- a/src/dblib/unittests/numeric.c
++++ b/src/dblib/unittests/numeric.c
+@@ -58,22 +58,24 @@ test(int bind_type)
+ 		/* nop */
+ 	}
+ 
+-	ret = dbcmd(dbproc,
+-		    "SET ARITHABORT ON;"
+-		    "SET CONCAT_NULL_YIELDS_NULL ON;"
+-		    "SET ANSI_NULLS ON;"
+-		    "SET ANSI_NULL_DFLT_ON ON;"
+-		    "SET ANSI_PADDING ON;"
+-		    "SET ANSI_WARNINGS ON;"
+-		    "SET ANSI_NULL_DFLT_ON ON;"
+-		    "SET CURSOR_CLOSE_ON_COMMIT ON;"
+-		    "SET QUOTED_IDENTIFIER ON");
+-	chk(ret, "dbcmd");
+-	ret = dbsqlexec(dbproc);
+-	chk(ret, "dbsqlexec");
+-
+-	ret = dbcancel(dbproc);
+-	chk(ret, "dbcancel");
++	if (DBTDS_5_0 < DBTDS(dbproc)) {
++		ret = dbcmd(dbproc,
++			    "SET ARITHABORT ON;"
++			    "SET CONCAT_NULL_YIELDS_NULL ON;"
++			    "SET ANSI_NULLS ON;"
++			    "SET ANSI_NULL_DFLT_ON ON;"
++			    "SET ANSI_PADDING ON;"
++			    "SET ANSI_WARNINGS ON;"
++			    "SET ANSI_NULL_DFLT_ON ON;"
++			    "SET CURSOR_CLOSE_ON_COMMIT ON;"
++			    "SET QUOTED_IDENTIFIER ON");
++		chk(ret, "dbcmd");
++		ret = dbsqlexec(dbproc);
++		chk(ret, "dbsqlexec");
++
++		ret = dbcancel(dbproc);
++		chk(ret, "dbcancel");
++	}
+ 
+ 	ret = dbrpcinit(dbproc, "testDecimal", 0);
+ 	chk(ret, "dbrpcinit");
+
+commit bf3a44ff4192d3babf5b61a2e8c2337d924221fd
+Author: freddy77 <freddy77>
+Date:   Thu Sep 3 09:25:55 2009 +0000
+
+    fix NTLM2 check
+
+diff --git a/ChangeLog b/ChangeLog
+index 3c157b2..f4b3806 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Sep  3 11:25:04 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/challenge.c: fix NTLM2 check
++
+ Wed Sep  2 11:26:14 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/numeric.c: fix dblib numeric test for Sybase
+ 
+@@ -1833,4 +1836,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2867 2009/09/02 09:27:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2868 2009/09/03 09:25:55 freddy77 Exp $
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index dd32186..7422046 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.39 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.40 2009/09/03 09:25:55 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -272,7 +272,21 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 
+ 	memset(answer, 0, sizeof(TDSANSWER));
+ 
+-	if (!(*flags & 0x80000)) {
++	if ((*flags & 0x80000) != 0) {
++		/* NTLM2 */
++		MD5_CTX md5_ctx;
++
++		generate_random_buffer(hash, 8);
++		memset(hash + 8, 0, 16);
++		memcpy(answer->lm_resp, hash, 24);
++
++		MD5Init(&md5_ctx);
++		MD5Update(&md5_ctx, challenge, 8);
++		MD5Update(&md5_ctx, hash, 8);
++		MD5Final(&md5_ctx, ntlm2_challenge);
++		challenge = ntlm2_challenge;
++		memset(&md5_ctx, 0, sizeof(md5_ctx));
++	} else if (names_blob_len <= 0) {
+ 		/* NTLM */
+ 		size_t len, i;
+ 		unsigned char passwd_buf[MAX_PW_SZ];
+@@ -297,7 +311,7 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 
+ 		tds_encrypt_answer(hash, challenge, answer->lm_resp);
+ 		memset(passwd_buf, 0, sizeof(passwd_buf));
+-	} else if (names_blob_len > 0) {
++	} else {
+ 		/* NTLMv2 */
+ 		unsigned char *lm_v2_response;
+ 		unsigned char ntlm_v2_hash[16];
+@@ -322,21 +336,9 @@ tds_answer_challenge(TDSSOCKET * tds,
+ 		if (!*ntlm_v2_response)
+ 			return TDS_FAIL;
+ 
++		/* local not supported */
++		*flags &= 0x4000;
+ 		return TDS_SUCCEED;
+-	} else {
+-		/* NTLM2 */
+-		MD5_CTX md5_ctx;
+-
+-		generate_random_buffer(hash, 8);
+-		memset(hash + 8, 0, 16);
+-		memcpy(answer->lm_resp, hash, 24);
+-
+-		MD5Init(&md5_ctx);
+-		MD5Update(&md5_ctx, challenge, 8);
+-		MD5Update(&md5_ctx, hash, 8);
+-		MD5Final(&md5_ctx, ntlm2_challenge);
+-		challenge = ntlm2_challenge;
+-		memset(&md5_ctx, 0, sizeof(md5_ctx));
+ 	}
+ 	*flags = 0x8201;
+ 
+
+commit 8828b935009b7d3714acba0c445b350e0d071717
+Author: freddy77 <freddy77>
+Date:   Thu Sep 3 11:53:46 2009 +0000
+
+    fix NULL becaming empty strings under Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index f4b3806..3790de5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Sep  3 13:53:26 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO src/tds/token.c:
++	- fix NULL becaming empty strings under Sybase
++
+ Thu Sep  3 11:25:04 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/challenge.c: fix NTLM2 check
+ 
+@@ -1836,4 +1840,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2868 2009/09/03 09:25:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2869 2009/09/03 11:53:46 freddy77 Exp $
+diff --git a/TODO b/TODO
+index 223fd95..89eb4e9 100644
+--- a/TODO
++++ b/TODO
+@@ -8,14 +8,11 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.173 2009/08/25 05:00:53 freddy77 Exp $
++To Do List	$Id: TODO,v 1.174 2009/09/03 11:53:47 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+ 	tds_send_cancel in tds_goodwrite (wrong??)
+-BUG: ML 2009-02-10 "Problem with Set TEXT field to NULL"
+-	libtds seems to misinterpret NULL TEXT fields as 
+-	zero-length strings. 
+ BUG: sending ICONV charset name, not TDS name in 
+ 	5.0 login packet.  
+ 	
+diff --git a/src/tds/token.c b/src/tds/token.c
+index f61eef6..f1de333 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.374 2009/08/26 12:32:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.375 2009/09/03 11:53:47 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2137,6 +2137,8 @@ tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	case 5:
+ 		blob = (TDSBLOB *) curcol->column_data;
+ 		colsize = tds_get_int(tds);
++		if (colsize == 0)
++			colsize = -1;
+ 		break;
+ 	case 8:
+ 		return tds9_get_varmax(tds, curcol);
+
+commit 5fe8210de0a6262e39032b9d2bdabf8b66c85324
+Author: freddy77 <freddy77>
+Date:   Fri Sep 4 07:12:18 2009 +0000
+
+    Fix --with-tdsver option
+
+diff --git a/ChangeLog b/ChangeLog
+index 3790de5..6090ed0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Sep  4 09:11:38 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac vms/README.vms: Fix --with-tdsver option
++
+ Thu Sep  3 13:53:26 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO src/tds/token.c:
+ 	- fix NULL becaming empty strings under Sybase
+@@ -1840,4 +1843,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2869 2009/09/03 11:53:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2870 2009/09/04 07:12:18 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 28bc9d7..b65de2f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.41 2009/08/14 13:53:17 freddy77 Exp $
++dnl $Id: configure.ac,v 1.42 2009/09/04 07:12:18 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.41 $)
++AC_REVISION($Revision: 1.42 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -460,15 +460,15 @@ AC_HAVE_MALLOC_OPTIONS
+ AC_MSG_RESULT(checking compile-time options)
+ 
+ AC_ARG_WITH(tdsver,
+-AS_HELP_STRING([--with-tdsver=VERSION], [TDS protocol version (4.2/4.6/5.0/7.0/8.0) [5.0]]))
++AS_HELP_STRING([--with-tdsver=VERSION], [TDS protocol version (4.2/4.6/5.0/7.0/7.1) [5.0]]))
+ if test "$with_tdsver" = "4.2"; then
+ 	AC_DEFINE(TDS42, 1, [Define to use TDS 4.2 by default])
+ elif test "$with_tdsver" = "4.6"; then
+ 	AC_DEFINE(TDS46, 1, [Define to use TDS 4.6 by default])
+ elif test "$with_tdsver" = "7.0"; then
+ 	AC_DEFINE(TDS70, 1, [Define to use TDS 7.0 by default])
+-elif test "$with_tdsver" = "8.0"; then
+-	AC_DEFINE(TDS80, 1, [Define to use TDS 8.0 by default])
++elif test "$with_tdsver" = "7.1"; then
++	AC_DEFINE(TDS71, 1, [Define to use TDS 7.1 by default])
+ else
+ 	AC_DEFINE(TDS50, 1, [Define to use TDS 5.0 by default])
+ fi
+diff --git a/vms/README.vms b/vms/README.vms
+index ef1ec5e..3345fba 100644
+--- a/vms/README.vms
++++ b/vms/README.vms
+@@ -39,13 +39,13 @@ by sypplying the following macros to the make utility:
+ TDSVER
+ 
+ This macro expects a value that will be passed directly to the C compiler. 
+-Valid values are TDS42, TDS50 (the default), TDS70, and TDS80.  Consult the
++Valid values are TDS42, TDS50 (the default), TDS70, and TDS71.  Consult the
+ [.doc] directory for more information about the TDS protocol, what servers
+ use which versions, and the history of the versions.
+ 
+ Example:
+ 
+-    $ MMK/MACRO="TDSVER"="TDS80"
++    $ MMK/MACRO="TDSVER"="TDS71"
+ 
+ 
+ MSDBLIB
+@@ -111,4 +111,4 @@ now you'll have to roll your own.
+ 
+ 
+ Last updated: 	6-NOV-2004	Craig A. Berry	<craigberry@mac.com>
+-$Id: README.vms,v 1.3 2004/11/07 08:59:34 freddy77 Exp $
++$Id: README.vms,v 1.4 2009/09/04 07:12:18 freddy77 Exp $
+
+commit 193edf237676f4c99bced37f9a976ee52b305e44
+Author: freddy77 <freddy77>
+Date:   Mon Sep 14 10:02:13 2009 +0000
+
+    limit stack use in dblib tests
+
+diff --git a/ChangeLog b/ChangeLog
+index 6090ed0..5207092 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Sep 14 12:02:10 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/dblib/unittests/common.c:
++	- limit stack use in dblib tests
++
+ Fri Sep  4 09:11:38 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac vms/README.vms: Fix --with-tdsver option
+ 
+@@ -1843,4 +1847,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2870 2009/09/04 07:12:18 freddy77 Exp $
++$Id: ChangeLog,v 1.2871 2009/09/14 10:02:13 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index b65de2f..3653456 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.42 2009/09/04 07:12:18 freddy77 Exp $
++dnl $Id: configure.ac,v 1.43 2009/09/14 10:02:13 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.42 $)
++AC_REVISION($Revision: 1.43 $)
+ 
+ AM_INIT_AUTOMAKE
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -256,6 +256,7 @@ AC_CHECK_HEADERS([	errno.h \
+ 			sys/stat.h \
+ 			sys/time.h \
+ 			sys/types.h \
++			sys/resource.h \
+ 			sys/wait.h \
+ 			unistd.h \
+ 			wchar.h ])
+@@ -438,7 +439,7 @@ AC_CHECK_FUNCS([vsnprintf _vsnprintf gettimeofday \
+ nl_langinfo locale_charset setenv putenv \
+ getuid getpwuid getpwuid_r fstat alarm fork \
+ gethrtime localtime_r setitimer _lseeki64 _telli64 \
+-_fseeki64 _ftelli64])
++_fseeki64 _ftelli64 setrlimit])
+ OLD_LIBS="$LIBS"
+ LIBS="$LIBS $NETWORK_LIBS"
+ AC_CHECK_FUNCS([inet_ntoa_r getipnodebyaddr getipnodebyname \
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 0eedcab..93ab234 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -12,9 +12,17 @@
+ #include <sys/param.h>
+ #endif /* HAVE_SYS_PARAM_H */
+ 
++#if HAVE_SYS_TIME_H
++#include <sys/time.h>
++#endif /* HAVE_SYS_TIME_H */
++
++#if HAVE_SYS_RESOURCE_H
++#include <sys/resource.h>
++#endif /* HAVE_SYS_RESOURCE_H */
++
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.38 2009/09/01 05:47:31 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.39 2009/09/14 10:02:13 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -122,6 +130,17 @@ read_login_info(int argc, char **argv)
+ 	static const char *PWD = "../../../PWD";
+ 	struct { char *username, *password, *servername, *database; char fverbose; } options;
+ 
++#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_STACK)
++#define MAX_STACK (8*1024*1024)
++
++	struct rlimit rlim;
++
++	if (!getrlimit(RLIMIT_STACK, &rlim) && (rlim.rlim_cur == RLIM_INFINITY || rlim.rlim_cur > MAX_STACK)) {
++		rlim.rlim_cur = MAX_STACK;
++		setrlimit(RLIMIT_STACK, &rlim);
++	}
++#endif
++
+ 	setbuf(stdout, NULL);
+ 	setbuf(stderr, NULL);
+ 	
+
+commit a19b33c1b1491effec079700398461fd9fd78ac9
+Author: freddy77 <freddy77>
+Date:   Mon Sep 28 14:07:04 2009 +0000
+
+    Fix SSL connection under mssql2k
+
+diff --git a/ChangeLog b/ChangeLog
+index 5207092..6472dd2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Sep 28 16:06:37 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c: Fix SSL connection under mssql2k
++
+ Mon Sep 14 12:02:10 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/dblib/unittests/common.c:
+ 	- limit stack use in dblib tests
+@@ -1847,4 +1850,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2871 2009/09/14 10:02:13 freddy77 Exp $
++$Id: ChangeLog,v 1.2872 2009/09/28 14:07:04 freddy77 Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index cc49cf8..05be59a 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.188 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.189 2009/09/28 14:07:04 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -976,6 +976,13 @@ tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	assert(start_pos >= 21 && start_pos <= sizeof(buf));
+ 	assert(buf[start_pos-1] == 0xff);
+ 
++	/*
++	 * fix a problem with mssql2k which doesn't like
++	 * packet splitted during SSL handshake
++	 */
++	if (tds->env.block_size < 4096)
++		tds_realloc_socket(tds, 4096);
++
+ 	/* do prelogin */
+ 	tds->out_flag = TDS8_PRELOGIN;
+ 
+
+commit 7a7dd31d8ef504574418fca8e3bf6f037163e73b
+Author: freddy77 <freddy77>
+Date:   Tue Sep 29 09:16:10 2009 +0000
+
+    fix float to money precision during conversion
+
+diff --git a/ChangeLog b/ChangeLog
+index 6472dd2..1a8461d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Sep 29 11:15:56 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/convert.c: fix float to money precision during conversion
++
+ Mon Sep 28 16:06:37 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/login.c: Fix SSL connection under mssql2k
+ 
+@@ -1850,4 +1853,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2872 2009/09/28 14:07:04 freddy77 Exp $
++$Id: ChangeLog,v 1.2873 2009/09/29 09:16:10 freddy77 Exp $
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index b665b31..0d1d44b 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.192 2009/06/12 08:53:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.193 2009/09/29 09:16:10 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -1428,7 +1428,7 @@ tds_convert_real(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
+ 	case SYBMONEY:
+ 		if (the_value > (TDS_REAL) (TDS_INT8_MAX / 10000) || the_value < (TDS_REAL) (TDS_INT8_MIN / 10000))
+ 			return TDS_CONVERT_OVERFLOW;
+-		mymoney = ((TDS_INT8) the_value) * 10000;
++		mymoney = (TDS_INT8) (the_value * 10000);
+ 		cr->m.mny = mymoney;
+ 		return sizeof(TDS_MONEY);
+ 		break;
+@@ -1436,7 +1436,7 @@ tds_convert_real(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
+ 	case SYBMONEY4:
+ 		if (the_value > (TDS_REAL) (TDS_INT_MAX / 10000) || the_value < (TDS_REAL) (TDS_INT_MIN / 10000))
+ 			return TDS_CONVERT_OVERFLOW;
+-		mymoney4 = ((TDS_INT) the_value) * 10000;
++		mymoney4 = (TDS_INT) (the_value * 10000);
+ 		cr->m4.mny4 = mymoney4;
+ 		return sizeof(TDS_MONEY4);
+ 		break;
+@@ -1512,14 +1512,14 @@ tds_convert_flt8(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
+ 	case SYBMONEY:
+ 		if (the_value > (TDS_FLOAT) (TDS_INT8_MAX / 10000) || the_value < (TDS_FLOAT) (TDS_INT8_MIN / 10000))
+ 			return TDS_CONVERT_OVERFLOW;
+-		cr->m.mny = ((TDS_INT8) the_value) * 10000;
++		cr->m.mny = (TDS_INT8) (the_value * 10000);
+ 
+ 		return sizeof(TDS_MONEY);
+ 		break;
+ 	case SYBMONEY4:
+ 		if (the_value > (TDS_FLOAT) (TDS_INT_MAX / 10000) || the_value < (TDS_FLOAT) (TDS_INT_MIN / 10000))
+ 			return TDS_CONVERT_OVERFLOW;
+-		cr->m4.mny4 = ((TDS_INT) the_value) * 10000;
++		cr->m4.mny4 = (TDS_INT) (the_value * 10000);
+ 		return sizeof(TDS_MONEY4);
+ 		break;
+ 	case SYBREAL:
+
+commit 08fb2ae2ee946bda917d53b8c5873efd0dfc4ff5
+Author: freddy77 <freddy77>
+Date:   Wed Sep 30 11:52:05 2009 +0000
+
+    Avoid memory problems logging data
+
+diff --git a/ChangeLog b/ChangeLog
+index 1a8461d..5965746 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Sep 30 13:51:16 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/log.c: Avoid memory problems logging data
++
+ Tue Sep 29 11:15:56 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/convert.c: fix float to money precision during conversion
+ 
+@@ -1853,4 +1856,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2873 2009/09/29 09:16:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2874 2009/09/30 11:52:05 freddy77 Exp $
+diff --git a/src/tds/log.c b/src/tds/log.c
+index e7401b7..6f02624 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.12 2009/02/27 10:07:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.13 2009/09/30 11:52:06 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+@@ -466,15 +466,19 @@ tdsdump_col(const TDSCOLUMN *col)
+ 	
+ 	switch(type) {
+ 	case SYBCHAR: 
+-	case SYBVARCHAR: 
+-		data = calloc(1, 1 + col->column_cur_size);
+-		if( !data ) {
+-			tdsdump_log(TDS_DBG_FUNC, "no memory to log data for type %s\n", typename);
+-			return;
++	case SYBVARCHAR:
++		if (col->column_cur_size >= 0) {
++			data = calloc(1, 1 + col->column_cur_size);
++			if (!data) {
++				tdsdump_log(TDS_DBG_FUNC, "no memory to log data for type %s\n", typename);
++				return;
++			}
++			memcpy(data, col->column_data, col->column_cur_size);
++			tdsdump_log(TDS_DBG_FUNC, "type %s has value \"%s\"\n", typename, data);
++			free(data);
++		} else {
++			tdsdump_log(TDS_DBG_FUNC, "type %s has value NULL\n", typename);
+ 		}
+-		memcpy(data, col->column_data, col->column_cur_size);
+-		tdsdump_log(TDS_DBG_FUNC, "type %s has value \"%s\"\n", typename, data); 
+-		free(data);
+ 		break;
+ 	case SYBINT1: 
+ 		tdsdump_log(TDS_DBG_FUNC, "type %s has value %d\n", typename, (int)*(TDS_TINYINT*)col->column_data); 
+
+commit a551638117fd8ccf4f5611ffd1a40fead323f2ec
+Author: freddy77 <freddy77>
+Date:   Thu Oct 1 09:48:43 2009 +0000
+
+    Avoid core using SQLWCHAR and TDS 4.2
+
+diff --git a/ChangeLog b/ChangeLog
+index 5965746..ec4152a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Oct  1 11:47:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/tds/iconv.c:
++	- Avoid core using SQLWCHAR and TDS 4.2
++
+ Wed Sep 30 13:51:16 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/log.c: Avoid memory problems logging data
+ 
+@@ -1856,4 +1860,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2874 2009/09/30 11:52:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2875 2009/10/01 09:48:43 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 8160f4a..a3d4f7b 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.65 2009/08/20 18:59:29 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.66 2009/10/01 09:48:43 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -64,6 +64,8 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 	if (desttype == SQL_C_WCHAR) {
+ 		/* SQL_C_WCHAR, convert to wide encode */
+ 		conv = tds_iconv_get(tds, ODBC_WIDE_NAME, conv->server_charset.name);
++		if (!conv)
++			conv = tds_iconv_get(tds, ODBC_WIDE_NAME, "ISO-8859-1");
+ 	}
+ 
+ 	ib = src;
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index cfe6a4e..ae34f98 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.140 2009/08/20 17:53:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.141 2009/10/01 09:48:43 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -389,6 +389,10 @@ tds_iconv_open(TDSSOCKET * tds, const char *charset)
+ 		fOK = tds_iconv_info_init(tds->char_convs[client2server_chardata], charset, tds->env.charset);
+ 		if (!fOK)
+ 			return;
++	} else {
++		int canonic_charset = tds_canonical_charset(charset);
++		tds->char_convs[client2server_chardata]->client_charset = canonic_charsets[canonic_charset];
++		tds->char_convs[client2server_chardata]->server_charset = canonic_charsets[canonic_charset];
+ 	}
+ 
+ 	/* 
+
+commit e0a211f2ca0f9cce7766166bfa433e0994527a77
+Author: freddy77 <freddy77>
+Date:   Fri Oct 2 09:24:07 2009 +0000
+
+    Support RPCs using tds 4.2
+
+diff --git a/ChangeLog b/ChangeLog
+index ec4152a..b2f4998 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Oct  2 11:23:18 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c src/tds/query.c src/tds/tds_checks.c:
++	- Support RPCs using tds 4.2
++
+ Thu Oct  1 11:47:53 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/tds/iconv.c:
+ 	- Avoid core using SQLWCHAR and TDS 4.2
+@@ -1860,4 +1864,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2875 2009/10/01 09:48:43 freddy77 Exp $
++$Id: ChangeLog,v 1.2876 2009/10/02 09:24:07 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index e7cc8f8..f79f909 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.198 2009/08/18 15:04:13 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.199 2009/10/02 09:24:07 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2024,6 +2024,7 @@ _ct_get_server_type(int datatype)
+ 	case CS_BINARY_TYPE:		return SYBBINARY;
+ 	case CS_BIT_TYPE:		return SYBBIT;	
+ 	case CS_CHAR_TYPE:		return SYBCHAR;	
++	case CS_VARCHAR_TYPE:		return SYBVARCHAR;
+ 	case CS_LONG_TYPE:
+ 	case CS_BIGINT_TYPE:		return SYBINT8;	
+ 	case CS_INT_TYPE:		return SYBINT4;	
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 6723a0b..7200afb 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.241 2009/08/26 12:32:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.242 2009/10/02 09:24:08 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -57,6 +57,7 @@ static char *tds7_build_param_def_from_query(TDSSOCKET * tds, const char* conver
+ static char *tds7_build_param_def_from_params(TDSSOCKET * tds, const char* query, size_t query_len, TDSPARAMINFO * params, size_t *out_len);
+ static size_t tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ 
++static int tds_put_param_as_string(TDSSOCKET * tds, TDSPARAMINFO * params, int n);
+ static int tds_send_emulated_execute(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
+ static const char *tds_skip_comment(const char *s);
+ static int tds_count_placeholders_ucs2le(const char *query, const char *query_end);
+@@ -729,6 +730,8 @@ tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out)
+ 	case SYBUINT4:
+ 	case SYBUINT8:
+ 	case SYBVARIANT:
++	default:
++		tdsdump_log(TDS_DBG_ERROR, "Unknown type %d\n", tds_get_conversion_type(curcol->on_server.column_type, curcol->on_server.column_size));
+ 		break;
+ 	}
+ 
+@@ -1854,6 +1857,56 @@ tds_submit_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn)
+ 	return tds_query_flush_packet(tds);
+ }
+ 
++static int
++tds_send_emulated_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params)
++{
++	TDSCOLUMN *param;
++	int i, n;
++	int num_params = params ? params->num_cols : 0;
++	const char *sep = " ";
++	char buf[80];
++
++	/* create params and set */
++	for (i = 0, n = 0; i < num_params; ++i) {
++
++		param = params->columns[i];
++
++		/* declare and set output parameters */
++		if (!param->column_output)
++			continue;
++		++n;
++		sprintf(buf, " DECLARE @P%d ", n);
++		tds_get_column_declaration(tds, param, buf + strlen(buf));
++		sprintf(buf + strlen(buf), " SET @P%d=", n);
++		tds_put_string(tds, buf, -1);
++		tds_put_param_as_string(tds, params, i);
++	}
++
++	/* put exec statement */
++	tds_put_string(tds, " EXEC ", 6);
++	tds_put_string(tds, rpc_name, -1);
++
++	/* put arguments */
++	for (i = 0, n = 0; i < num_params; ++i) {
++		param = params->columns[i];
++		tds_put_string(tds, sep, -1);
++		if (param->column_namelen > 0) {
++			tds_put_string(tds, param->column_name, param->column_namelen);
++			tds_put_string(tds, "=", 1);
++		}
++		if (param->column_output) {
++			++n;
++			sprintf(buf, "@P%d OUTPUT", n);
++			tds_put_string(tds, buf, -1);
++		} else {
++			tds_put_param_as_string(tds, params, i);
++		}
++		sep = ",";
++	}
++
++	return tds_query_flush_packet(tds);
++}
++
+ /**
+  * tds_submit_rpc() call a RPC from server. Output parameters will be stored in tds->param_info
+  * \param tds      state information for the socket and the TDS protocol
+@@ -1935,7 +1988,10 @@ tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params)
+ 		return tds_query_flush_packet(tds);
+ 	}
+ 
+-	/* TODO emulate it for TDS4.x, send RPC for mssql */
++	/* emulate it for TDS4.x, send RPC for mssql */
++	if (tds->tds_version < 0x500)
++		return tds_send_emulated_rpc(tds, rpc_name, params);
++
+ 	/* TODO continue, support for TDS4?? */
+ 	tds_set_state(tds, TDS_IDLE);
+ 	return TDS_FAIL;
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index fbe6857..e24f4e1 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.27 2009/08/26 12:32:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.28 2009/10/02 09:24:08 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -186,6 +186,7 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	/* I don't like this that much... freddy77 */
+ 	if (column->column_type == 0)
+ 		return;
++	assert(column->column_type > 0);
+ 
+ 	assert(strlen(column->table_name) < sizeof(column->table_name));
+ 	assert(strlen(column->column_name) < sizeof(column->column_name));
+
+commit 611ca2dfc78b5e354cc4dfe3fa6f2c0c780bd78e
+Author: freddy77 <freddy77>
+Date:   Sat Oct 3 09:19:27 2009 +0000
+
+    unprepare optimization for emulated dynamics
+
+diff --git a/ChangeLog b/ChangeLog
+index b2f4998..772ca30 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Oct  3 11:19:20 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: unprepare optimization for emulated dynamics
++
+ Fri Oct  2 11:23:18 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c src/tds/query.c src/tds/tds_checks.c:
+ 	- Support RPCs using tds 4.2
+@@ -1864,4 +1867,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2876 2009/10/02 09:24:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2877 2009/10/03 09:19:27 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 4c55639..9ec674f 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.513 2009/08/20 15:14:19 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.514 2009/10/03 09:19:27 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -6853,7 +6853,10 @@ odbc_free_dynamic(TDS_STMT * stmt)
+ 	TDSSOCKET *tds = stmt->dbc->tds_socket;
+ 
+ 	if (stmt->dyn) {
+-		if (tds_submit_unprepare(tds, stmt->dyn) == TDS_SUCCEED) {
++		if (stmt->dyn->emulated) {
++			tds_free_dynamic(tds, stmt->dyn);
++			stmt->dyn = NULL;
++		} else if (tds_submit_unprepare(tds, stmt->dyn) == TDS_SUCCEED) {
+ 			if (tds_process_simple_query(tds) != TDS_SUCCEED)
+ 				ODBC_RETURN(stmt, SQL_ERROR);
+ 			tds_free_dynamic(tds, stmt->dyn);
+
+commit 711638e2f35787f938a6aff6bda63866360ab68d
+Author: freddy77 <freddy77>
+Date:   Mon Oct 12 07:27:50 2009 +0000
+
+    add comments to misc/prepare_win32.sh script
+
+diff --git a/ChangeLog b/ChangeLog
+index 772ca30..2e84fe5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Oct 12 09:26:46 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/prepare_win32.sh:
++	- add comments to misc/prepare_win32.sh script
++
+ Sat Oct  3 11:19:20 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: unprepare optimization for emulated dynamics
+ 
+@@ -1867,4 +1871,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2877 2009/10/03 09:19:27 freddy77 Exp $
++$Id: ChangeLog,v 1.2878 2009/10/12 07:27:50 freddy77 Exp $
+diff --git a/misc/prepare_win32.sh b/misc/prepare_win32.sh
+index 519e6ba..57999ff 100755
+--- a/misc/prepare_win32.sh
++++ b/misc/prepare_win32.sh
+@@ -1,6 +1,11 @@
+ #!/bin/bash
+ 
+-# these commands prepare for win32 distribution
++# These commands prepare for win32 distribution
++
++# It uses MingW to cross compile
++# Useful for testing ODBC under Windows
++# With --ntwdblib option you can compile dblib tests against MS dblib so
++# to test tests with MS dblib
+ 
+ errore() {
+ 	echo $* >&2
+
+commit 361a13a1bc9204a224acf26ed1d88db0d709109a
+Author: freddy77 <freddy77>
+Date:   Fri Oct 16 07:59:39 2009 +0000
+
+    Fix dbwritetext with text == NULL
+
+diff --git a/ChangeLog b/ChangeLog
+index 2e84fe5..1ec8e0b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Oct 16 09:58:46 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: Fix dbwritetext with text == NULL
++
+ Mon Oct 12 09:26:46 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/prepare_win32.sh:
+ 	- add comments to misc/prepare_win32.sh script
+@@ -1871,4 +1874,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2878 2009/10/12 07:27:50 freddy77 Exp $
++$Id: ChangeLog,v 1.2879 2009/10/16 07:59:39 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 15956f3..cea010b 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.353 2009/09/01 08:02:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.354 2009/10/16 07:59:40 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4551,8 +4551,10 @@ dbsqlok(DBPROCESS * dbproc)
+ 
+ 	tds = dbproc->tds_socket;
+ 
+-	/* dbsqlok has been called after dbmoretext() */
+-	/* This is the trigger to send the text data. */
++	/*
++	 * dbsqlok has been called after dbmoretext()
++	 * This is the trigger to send the text data.
++	 */
+ 
+ 	if (dbproc->text_sent) {
+ 		tds_flush_packet(tds);
+@@ -6298,7 +6300,6 @@ dbwritetext(DBPROCESS * dbproc, char *objname, DBBINARY * textptr, DBTINYINT tex
+ 	CHECK_NULP(textptr, "dbwritetext", 3, FAIL);
+ 	CHECK_NULP(timestamp, "dbwritetext", 5, FAIL);
+ 	CHECK_PARAMETER(size, SYBEZTXT, FAIL);
+-	CHECK_NULP(text, "dbwritetext", 8, FAIL);
+ 
+ 	if (IS_TDSDEAD(dbproc->tds_socket))
+ 		return FAIL;
+@@ -6332,6 +6333,7 @@ dbwritetext(DBPROCESS * dbproc, char *objname, DBBINARY * textptr, DBTINYINT tex
+ 
+ 	tds_writetext_continue(dbproc->tds_socket, text, size);
+ 	tds_writetext_end(dbproc->tds_socket);
++	dbproc->text_sent = 0;
+ 
+ 	if (dbsqlok(dbproc) == SUCCEED && dbresults(dbproc) == SUCCEED)
+ 		return SUCCEED;
+@@ -6440,8 +6442,10 @@ dbmoretext(DBPROCESS * dbproc, DBINT size, const BYTE text[])
+ 			return FAIL;
+ 		dbproc->text_sent += size;
+ 
+-		if (dbproc->text_sent == dbproc->text_size)
++		if (dbproc->text_sent == dbproc->text_size) {
+ 			tds_writetext_end(dbproc->tds_socket);
++			dbproc->text_sent = 0;
++		}
+ 	}
+ 
+ 	return SUCCEED;
+
+commit 3ad0cb9e5a298c79f3d5464a38b2aa87ea3e229f
+Author: jklowden <jklowden>
+Date:   Fri Oct 23 19:21:37 2009 +0000
+
+    exit after -L output
+
+diff --git a/ChangeLog b/ChangeLog
+index 1ec8e0b..5bbfe15 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Fri Oct 23 15:12:16 EDT 2009	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c exit after -L output
++	* src/dblib/dblib.c
++	* src/dblib/dbopen.c
++	- dbdatecrack follows MSDBLIB, not WIN32
++	* src/tds/config.c 
++	- do not parse freetds.conf [servername] for instance/port. 
++
+ Fri Oct 16 09:58:46 CEST 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: Fix dbwritetext with text == NULL
+ 
+@@ -1874,4 +1882,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2879 2009/10/16 07:59:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2880 2009/10/23 19:21:37 jklowden Exp $
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 7777542..c751969 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.128 2009/05/28 16:23:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.129 2009/10/23 19:21:38 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -512,6 +512,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		tds_lookup_host(hostname, ip);
+ 		tds7_get_instance_ports(stderr, ip);
+ 		tdsdump_close();
++		exit(0);
+ 	}
+ 
+ 	/* validate parameters */
+
+commit a3d244d485fd6c6755c4b2c9248f82f728a0e345
+Author: jklowden <jklowden>
+Date:   Fri Oct 23 19:21:45 2009 +0000
+
+    dbdatecrack follows MSDBLIB, not WIN32
+
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index cea010b..efbc23e 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.354 2009/10/16 07:59:40 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.355 2009/10/23 19:21:45 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -5532,7 +5532,13 @@ dbdatecmp(DBPROCESS * dbproc, DBDATETIME * d1, DBDATETIME * d2)
+  * \param datetime \em input: \c DBDATETIME to be converted.
+  * \retval SUCCEED always.
+  * \remarks The members of \a di have different names, depending on whether \c --with-msdblib was configured. 
+- * \sa dbconvert(), dbdata(), dbdatechar(), dbdatename(), dbdatepart().
++ * 
++ * If DBPROCESS is NULL, dbdatecrack() uses the compiled in default 
++ * value of MSDBLIB as of when libsybdb was compiled, irrespective of its value when the 
++ * application is compiled.  This can lead to incorrect results because Sybase and Microsoft use different
++ * ranges -- [0,11] vs. [1,12] -- for the month. 
++ * 
++ * \sa dbconvert(), dbdata(), dbdatechar(), dbdatename(), dbdatepart(), tdsdbopen().
+  */
+ RETCODE
+ dbdatecrack(DBPROCESS * dbproc, DBDATEREC * output, DBDATETIME * datetime)
+diff --git a/src/dblib/dbopen.c b/src/dblib/dbopen.c
+index 34e21ed..4e61b6d 100644
+--- a/src/dblib/dbopen.c
++++ b/src/dblib/dbopen.c
+@@ -32,13 +32,17 @@
+ #undef dbopen
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbopen.c,v 1.12 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: dbopen.c,v 1.13 2009/10/23 19:21:45 jklowden Exp $");
+ 
++/**
++ * Normally not used. 
++ * The function is linked in only if the --enable-sybase-compat configure option is used.  
++ * Cf. sybdb.h dbopen() macros, and dbdatecrack(). 
++ */
+ DBPROCESS *
+ dbopen(LOGINREC * login, const char *server)
+ {
+-	/* default it's platform specific */
+-#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(DOS32X)
++#if MSDBLIB
+ 	return tdsdbopen(login, server, 1);
+ #else
+ 	return tdsdbopen(login, server, 0);
+
+commit 8c746b7fd78220d0768b31a4376d8f6bcb631a9f
+Author: jklowden <jklowden>
+Date:   Fri Oct 23 19:21:49 2009 +0000
+
+    do not parse freetds.conf [servername] for instance/port.
+
+diff --git a/src/tds/config.c b/src/tds/config.c
+index faa32eb..96f8edd 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.145 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.146 2009/10/23 19:21:49 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -86,7 +86,9 @@ static void tds_config_env_tdshost(TDSCONNECTION * connection);
+ static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
+ static int tds_read_interfaces(const char *server, TDSCONNECTION * connection);
+ static int tds_config_boolean(const char *value);
++#if PARSE_SERVER_NAME_FOR_PORT
+ static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
++#endif
+ static int tds_lookup_port(const char *portname);
+ static void tds_config_encryption(const char * value, TDSCONNECTION * connection);
+ 
+@@ -182,11 +184,13 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 	tdsdump_log(TDS_DBG_INFO1, "Getting connection information for [%s].\n", 
+ 			    tds_dstr_cstr(&login->server_name));	/* (The server name is set in login.c.) */
+ 
++#if PARSE_SERVER_NAME_FOR_PORT
++	/* Don't parse the [servername] key to a freetds.conf section. */
+ 	if (parse_server_name_for_port(connection, login)) {
+ 		tdsdump_log(TDS_DBG_INFO1, "Parsed servername, now %s on %d.\n", 
+ 			    tds_dstr_cstr(&connection->server_name), login->port);
+ 	}
+-
++#endif
+ 	/* Read the config files. */
+ 	tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n");
+ 	if (!tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name))) {
+@@ -1068,6 +1072,7 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 	return found;
+ }
+ 
++#if PARSE_SERVER_NAME_FOR_PORT
+ /**
+  * Check the server name to find port info first
+  * Warning: connection-> & login-> are all modified when needed
+@@ -1103,7 +1108,7 @@ parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login)
+ 
+ 	return 1;
+ }
+-
++#endif
+ 
+ /**
+  * Return a structure capturing the compile-time settings provided to the
+
+commit 10182ebf2ae7bffc46e3d86a2c5294268ce93666
+Author: freddy77 <freddy77>
+Date:   Fri Nov 6 07:50:44 2009 +0000
+
+    Fix compatibility problem with "server:port" syntax
+
+diff --git a/ChangeLog b/ChangeLog
+index 5bbfe15..79ec582 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Nov  6 08:49:07 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c:
++	- Fix compatibility problem with "server:port" syntax
++
+ Fri Oct 23 15:12:16 EDT 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/tsql.c exit after -L output
+ 	* src/dblib/dblib.c
+@@ -1882,4 +1886,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2880 2009/10/23 19:21:37 jklowden Exp $
++$Id: ChangeLog,v 1.2881 2009/11/06 07:50:44 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 96f8edd..c3a1291 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.146 2009/10/23 19:21:49 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.147 2009/11/06 07:50:44 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -86,9 +86,7 @@ static void tds_config_env_tdshost(TDSCONNECTION * connection);
+ static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
+ static int tds_read_interfaces(const char *server, TDSCONNECTION * connection);
+ static int tds_config_boolean(const char *value);
+-#if PARSE_SERVER_NAME_FOR_PORT
+ static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
+-#endif
+ static int tds_lookup_port(const char *portname);
+ static void tds_config_encryption(const char * value, TDSCONNECTION * connection);
+ 
+@@ -184,16 +182,11 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 	tdsdump_log(TDS_DBG_INFO1, "Getting connection information for [%s].\n", 
+ 			    tds_dstr_cstr(&login->server_name));	/* (The server name is set in login.c.) */
+ 
+-#if PARSE_SERVER_NAME_FOR_PORT
+-	/* Don't parse the [servername] key to a freetds.conf section. */
+-	if (parse_server_name_for_port(connection, login)) {
+-		tdsdump_log(TDS_DBG_INFO1, "Parsed servername, now %s on %d.\n", 
+-			    tds_dstr_cstr(&connection->server_name), login->port);
+-	}
+-#endif
+ 	/* Read the config files. */
+ 	tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n");
+-	if (!tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name))) {
++	if (!tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name)) &&
++		(!parse_server_name_for_port(connection, login) ||
++		 !tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name)))) {
+ 		/* fallback to interfaces file */
+ 		tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file.  Trying interface files.\n");
+ 		if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) {
+@@ -1072,7 +1065,6 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 	return found;
+ }
+ 
+-#if PARSE_SERVER_NAME_FOR_PORT
+ /**
+  * Check the server name to find port info first
+  * Warning: connection-> & login-> are all modified when needed
+@@ -1108,7 +1100,6 @@ parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login)
+ 
+ 	return 1;
+ }
+-#endif
+ 
+ /**
+  * Return a structure capturing the compile-time settings provided to the
+
+commit d10b3749e77139d1e8fa5dc02f65322dd22d9821
+Author: freddy77 <freddy77>
+Date:   Thu Nov 19 08:33:36 2009 +0000
+
+    fix typo in config.c
+
+diff --git a/ChangeLog b/ChangeLog
+index 79ec582..b2f344d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Nov 19 09:32:38 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: fix typo in config.c
++
+ Fri Nov  6 08:49:07 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c:
+ 	- Fix compatibility problem with "server:port" syntax
+@@ -1886,4 +1889,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2881 2009/11/06 07:50:44 freddy77 Exp $
++$Id: ChangeLog,v 1.2882 2009/11/19 08:33:36 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index c3a1291..84f9bca 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008, 2009  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.147 2009/11/06 07:50:44 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.148 2009/11/19 08:33:36 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -557,7 +557,7 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ 		tdsdump_log(TDS_DBG_INFO1, "%s is %s.\n", option, tds_dstr_cstr(&connection->server_charset));
+ 	} else if (!strcmp(option, TDS_STR_CLCHARSET)) {
+ 		tds_dstr_copy(&connection->client_charset, value);
+-		tdsdump_log(TDS_DBG_INFO1, "tds_config_login: %s is %s.\n", option, tds_dstr_cstr(&connection->client_charset));
++		tdsdump_log(TDS_DBG_INFO1, "tds_parse_conf_section: %s is %s.\n", option, tds_dstr_cstr(&connection->client_charset));
+ 	} else if (!strcmp(option, TDS_STR_LANGUAGE)) {
+ 		tds_dstr_copy(&connection->language, value);
+ 	} else if (!strcmp(option, TDS_STR_APPENDMODE)) {
+
+commit 9c26beecd29d2d18ef56209a13fd573ff8c6a7f1
+Author: freddy77 <freddy77>
+Date:   Thu Nov 19 08:45:49 2009 +0000
+
+    fix SQLColAttributes for ODBC 2 clients
+
+diff --git a/ChangeLog b/ChangeLog
+index b2f344d..b8ada4d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Nov 19 09:44:19 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix SQLColAttributes for ODBC 2 clients
++
+ Thu Nov 19 09:32:38 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c: fix typo in config.c
+ 
+@@ -1889,4 +1892,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2882 2009/11/19 08:33:36 freddy77 Exp $
++$Id: ChangeLog,v 1.2883 2009/11/19 08:45:49 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 9ec674f..ed72926 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.514 2009/10/03 09:19:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.515 2009/11/19 08:45:49 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4763,12 +4763,12 @@ SQLGetFunctions(SQLHDBC hdbc, SQLUSMALLINT fFunction, SQLUSMALLINT FAR * pfExist
+ 		 * and then use it but I don't know how to build it...
+ 		 */
+ #undef ODBC_ALL_API
+-#undef ODBC_COLATTRIBUTES
++#undef ODBC_COLATTRIBUTE
+ 
+ #if SQL_API_SQLCOLATTRIBUTE != SQL_API_SQLCOLATTRIBUTES
+-#define ODBC_COLATTRIBUTES(s) s
++#define ODBC_COLATTRIBUTE(s) s
+ #else
+-#define ODBC_COLATTRIBUTES(s)
++#define ODBC_COLATTRIBUTE(s)
+ #endif
+ 
+ #define ODBC_ALL_API \
+@@ -4783,8 +4783,8 @@ SQLGetFunctions(SQLHDBC hdbc, SQLUSMALLINT fFunction, SQLUSMALLINT FAR * pfExist
+ 	API3_(SQL_API_SQLBULKOPERATIONS);\
+ 	API_X(SQL_API_SQLCANCEL);\
+ 	API3X(SQL_API_SQLCLOSECURSOR);\
+-	API3X(SQL_API_SQLCOLATTRIBUTE);\
+-	ODBC_COLATTRIBUTES(API_X(SQL_API_SQLCOLATTRIBUTES);)\
++	ODBC_COLATTRIBUTE(API3X(SQL_API_SQLCOLATTRIBUTE);)\
++	API_X(SQL_API_SQLCOLATTRIBUTES);\
+ 	API_X(SQL_API_SQLCOLUMNPRIVILEGES);\
+ 	API_X(SQL_API_SQLCOLUMNS);\
+ 	API_X(SQL_API_SQLCONNECT);\
+
+commit fa98e93d756314f7d0f2a6a432922783c43410ba
+Author: jklowden <jklowden>
+Date:   Sun Nov 22 21:49:48 2009 +0000
+
+    No error if valid DNS name not in freetds.conf.  Better reporting of server name on login failure.
+
+diff --git a/ChangeLog b/ChangeLog
+index b8ada4d..cae9bec 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sun Nov 22 16:46:00 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/tds/config.c src/tds/mem.c
++	- No error if valid DNS name not in freetds.conf. 
++	- Better reporting of server name on login failure. 
++
+ Thu Nov 19 09:44:19 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix SQLColAttributes for ODBC 2 clients
+ 
+@@ -1892,4 +1897,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2883 2009/11/19 08:45:49 freddy77 Exp $
++$Id: ChangeLog,v 1.2884 2009/11/22 21:49:48 jklowden Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 84f9bca..9aacc4e 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.148 2009/11/19 08:33:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.149 2009/11/22 21:49:49 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -192,7 +192,8 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 		if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) {
+ 			tdsdump_log(TDS_DBG_INFO1, "Failed to find [%s] in configuration files; trying '%s' instead.\n", 
+ 						   tds_dstr_cstr(&login->server_name), tds_dstr_cstr(&connection->server_name));
+-			tdserror(tds->tds_ctx, tds, TDSEINTF, 0);
++			if (tds_dstr_isempty(&connection->ip_addr))
++				tdserror(tds->tds_ctx, tds, TDSEINTF, 0);
+ 		}
+ 	}
+ 
+@@ -205,6 +206,9 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 	if (opened) {
+ 		tdsdump_log(TDS_DBG_INFO1, "Final connection parameters:\n");
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_name", tds_dstr_cstr(&connection->server_name));
++		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_host_name", tds_dstr_cstr(&connection->server_host_name));
++		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "ip_addr", tds_dstr_cstr(&connection->ip_addr));
++		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "instance_name", tds_dstr_cstr(&connection->instance_name));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "port", connection->port);
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "major_version", TDS_MAJOR(connection));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "minor_version", TDS_MINOR(connection));
+@@ -213,6 +217,7 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "server_charset", tds_dstr_cstr(&connection->server_charset));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "connect_timeout", connection->connect_timeout);
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_host_name", tds_dstr_cstr(&connection->client_host_name));
++		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_charset", tds_dstr_cstr(&connection->client_charset));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "app_name", tds_dstr_cstr(&connection->app_name));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "user_name", tds_dstr_cstr(&connection->user_name));
+ 		/* tdsdump_log(TDS_DBG_PASSWD, "\t%20s = %s\n", "password", tds_dstr_cstr(&connection->password)); 
+@@ -224,9 +229,6 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %d\n", "query_timeout", connection->query_timeout);
+ 		/* tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "capabilities", tds_dstr_cstr(&connection->capabilities)); 
+ 			(not null terminated) */
+-		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "client_charset", tds_dstr_cstr(&connection->client_charset));
+-		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "ip_addr", tds_dstr_cstr(&connection->ip_addr));
+-		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "instance_name", tds_dstr_cstr(&connection->instance_name));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "database", tds_dstr_cstr(&connection->database));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %s\n", "dump_file", tds_dstr_cstr(&connection->dump_file));
+ 		tdsdump_log(TDS_DBG_INFO1, "\t%20s = %x\n", "debug_flags", connection->debug_flags);
+@@ -576,8 +578,9 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ static void
+ tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login)
+ {
+-	if (!tds_dstr_isempty(&login->server_name) && tds_dstr_isempty(&connection->server_name)) {
+-		tds_dstr_dup(&connection->server_name, &login->server_name);
++	if (!tds_dstr_isempty(&login->server_name)) {
++		if (1 || tds_dstr_isempty(&connection->server_name)) 
++			tds_dstr_dup(&connection->server_name, &login->server_name);
+ 	}
+ 	if (login->tds_version)
+ 		connection->tds_version = login->tds_version;
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 3616d78..81f0eb5 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.191 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.192 2009/11/22 21:49:49 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -998,15 +998,15 @@ tds_alloc_login(void)
+ 	if ((s=getenv("TDSQUERY")) != NULL)
+ 		server_name = s;
+ 
+-	if (!tds_dstr_copy(&tds_login->server_name, server_name))
+-		goto Cleanup;
++	if (!tds_dstr_copy(&tds_login->server_name, server_name)) {
++		free(tds_login);
++		return NULL;
++	}
++
+ 	memcpy(tds_login->capabilities, defaultcaps, TDS_MAX_CAPABILITY);
+ 
++	Cleanup:
+ 	return tds_login;
+-
+-      Cleanup:
+-	free(tds_login);
+-	return NULL;
+ }
+ 
+ void
+
+commit 7caafa0227fd87cd8348ba8d7bfdb5ebe0e4d690
+Author: freddy77 <freddy77>
+Date:   Mon Nov 23 08:50:28 2009 +0000
+
+    Use strtok_r instead of strtok to be more thread safe
+
+diff --git a/ChangeLog b/ChangeLog
+index cae9bec..15af39a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Nov 23 09:48:23 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c src/dblib/bcp.c:
++	- Use strtok_r instead of strtok to be more thread safe
++
+ Sun Nov 22 16:46:00 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/config.c src/tds/mem.c
+ 	- No error if valid DNS name not in freetds.conf. 
+@@ -1897,4 +1901,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2884 2009/11/22 21:49:48 jklowden Exp $
++$Id: ChangeLog,v 1.2885 2009/11/23 08:50:28 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index f79f909..aa7b79e 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.199 2009/10/02 09:24:07 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.200 2009/11/23 08:50:28 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -395,10 +395,10 @@ ct_con_props(CS_CONNECTION * con, CS_INT action, CS_INT property, CS_VOID * buff
+ 			break;
+ 		case CS_SERVERADDR: {
+ 			/* Format of this property: "[hostname] [port]" */
+-			char *host, *port;
++			char *host, *port, *lasts;
+ 			int portno;
+-			host= strtok(set_buffer, " ");
+-			port= strtok(NULL, " ");
++			host= strtok_r(set_buffer, " ", &lasts);
++			port= strtok_r(NULL, " ", &lasts);
+ 			if (!host || !port)
+ 				return CS_FAIL;
+ 
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 0c03301..f9fa780 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -61,7 +61,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.188 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.189 2009/11/23 08:50:28 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -1976,6 +1976,7 @@ _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci)
+ 	int whichcol;
+ 	char term[30];
+ 	int i;
++	char *lasts;
+ 
+ 	enum nextcol
+ 	{
+@@ -1993,7 +1994,7 @@ _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci)
+ 	assert(ci);
+ 	tdsdump_log(TDS_DBG_FUNC, "_bcp_readfmt_colinfo(%p, %s, %p)\n", dbproc, buf, ci);
+ 
+-	tok = strtok(buf, " \t");
++	tok = strtok_r(buf, " \t", &lasts);
+ 	whichcol = HOST_COLUMN;
+ 
+ 	/* TODO use a better way to get an int atoi is very error prone */
+@@ -2112,7 +2113,7 @@ _bcp_readfmt_colinfo(DBPROCESS * dbproc, char *buf, BCP_HOSTCOLINFO * ci)
+ 			break;
+ 
+ 		}
+-		tok = strtok(NULL, " \t");
++		tok = strtok_r(NULL, " \t", &lasts);
+ 	}
+ 	if (whichcol == NO_MORE_COLS)
+ 		return (TRUE);
+
+commit 956508418bed51526194f90fc508a86b73618701
+Author: freddy77 <freddy77>
+Date:   Mon Nov 23 11:31:08 2009 +0000
+
+    Add bulk.c to msvc6 project file
+
+diff --git a/ChangeLog b/ChangeLog
+index 15af39a..e8d0e16 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Nov 23 12:30:27 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/msvc6/libTDS.dsp: Add bulk.c to msvc6 project file
++
+ Mon Nov 23 09:48:23 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c src/dblib/bcp.c:
+ 	- Use strtok_r instead of strtok to be more thread safe
+@@ -1901,4 +1904,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2885 2009/11/23 08:50:28 freddy77 Exp $
++$Id: ChangeLog,v 1.2886 2009/11/23 11:31:08 freddy77 Exp $
+diff --git a/win32/msvc6/libTDS.dsp b/win32/msvc6/libTDS.dsp
+index ece7627..13900b1 100644
+--- a/win32/msvc6/libTDS.dsp
++++ b/win32/msvc6/libTDS.dsp
+@@ -85,6 +85,10 @@ LIB32=link.exe -lib
+ # PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
+ # Begin Source File
+ 
++SOURCE=..\..\src\tds\bulk.c
++# End Source File
++# Begin Source File
++
+ SOURCE=..\..\src\tds\challenge.c
+ # End Source File
+ # Begin Source File
+
+commit 16588beac97fec29a34801176ca555b6c5901b62
+Author: freddy77 <freddy77>
+Date:   Tue Nov 24 15:48:52 2009 +0000
+
+    small optimization
+
+diff --git a/ChangeLog b/ChangeLog
+index e8d0e16..3d8adf6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Nov 24 16:48:17 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: small optimization
++
+ Mon Nov 23 12:30:27 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/msvc6/libTDS.dsp: Add bulk.c to msvc6 project file
+ 
+@@ -1904,4 +1907,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2886 2009/11/23 11:31:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2887 2009/11/24 15:48:52 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 9aacc4e..0e98808 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.149 2009/11/22 21:49:49 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.150 2009/11/24 15:48:52 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -968,11 +968,10 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 
+ 	/* read $SYBASE/interfaces */
+ 
+-	if (!server || strlen(server) == 0) {
++	if (!server || !server[0]) {
+ 		server = getenv("TDSQUERY");
+-		if (!server || strlen(server) == 0) {
++		if (!server || !server[0])
+ 			server = "SYBASE";
+-		}
+ 		tdsdump_log(TDS_DBG_INFO1, "Setting server to %s from $TDSQUERY.\n", server);
+ 
+ 	}
+
+commit 6174a64226b67a1bc05a6046525e672b60028f12
+Author: freddy77 <freddy77>
+Date:   Thu Nov 26 09:07:27 2009 +0000
+
+    Fix univarchar in Sybase servers
+
+diff --git a/ChangeLog b/ChangeLog
+index 3d8adf6..725255a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Nov 26 10:06:51 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/data.c src/tds/tds_checks.c:
++	* src/tds/tds_checks.h src/tds/token.c:
++	- Fix univarchar in Sybase servers
++
+ Tue Nov 24 16:48:17 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c: small optimization
+ 
+@@ -1907,4 +1912,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2887 2009/11/24 15:48:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2888 2009/11/26 09:07:27 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 12278b8..61c2280 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.321 2009/08/25 14:25:35 freddy77 Exp $ */
++/* $Id: tds.h,v 1.322 2009/11/26 09:07:28 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1425,7 +1425,7 @@ unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsi
+ TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, const char *id);
+ /*@observer@*/ const char *tds_prtype(int token);
+ int tds_get_varint_size(TDSSOCKET * tds, int datatype);
+-int tds_get_cardinal_type(int datatype);
++int tds_get_cardinal_type(int datatype, int usertype);
+ 
+ 
+ 
+diff --git a/src/tds/data.c b/src/tds/data.c
+index c9a5866..475a733 100644
+--- a/src/tds/data.c
++++ b/src/tds/data.c
+@@ -35,7 +35,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: data.c,v 1.24 2009/08/26 12:32:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: data.c,v 1.25 2009/11/26 09:07:28 freddy77 Exp $");
+ 
+ /**
+  * Set type of column initializing all dependency 
+@@ -47,7 +47,7 @@ tds_set_column_type(TDSSOCKET * tds, TDSCOLUMN * curcol, int type)
+ {
+ 	/* set type */
+ 	curcol->on_server.column_type = type;
+-	curcol->column_type = tds_get_cardinal_type(type);
++	curcol->column_type = tds_get_cardinal_type(type, curcol->column_usertype);
+ 
+ 	/* set size */
+ 	curcol->column_cur_size = -1;
+@@ -152,7 +152,7 @@ tds_set_param_type(TDSSOCKET * tds, TDSCOLUMN * curcol, TDS_SERVER_TYPE type)
+ }
+ 
+ int
+-tds_get_cardinal_type(int datatype)
++tds_get_cardinal_type(int datatype, int usertype)
+ {
+ 	switch (datatype) {
+ 	case XSYBVARBINARY:
+@@ -169,6 +169,13 @@ tds_get_cardinal_type(int datatype)
+ 		return SYBCHAR;
+ 	case SYB5INT8:
+ 		return SYBINT8;
++	case SYBLONGBINARY:
++		switch (usertype) {
++		case USER_UNICHAR_TYPE:
++		case USER_UNIVARCHAR_TYPE:
++			return SYBTEXT;
++		}
++		break;
+ 	}
+ 	return datatype;
+ }
+diff --git a/src/tds/tds_checks.c b/src/tds/tds_checks.c
+index e24f4e1..eae34a4 100644
+--- a/src/tds/tds_checks.c
++++ b/src/tds/tds_checks.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: tds_checks.c,v 1.28 2009/10/02 09:24:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tds_checks.c,v 1.29 2009/11/26 09:07:28 freddy77 Exp $");
+ 
+ #if ENABLE_EXTRA_CHECKS
+ 
+@@ -197,7 +197,7 @@ tds_check_column_extra(const TDSCOLUMN * column)
+ 	SPECIAL(SYBTEXT, XSYBVARCHAR, 8)
+ 	SPECIAL(SYBTEXT, XSYBNVARCHAR, 8)
+ 	SPECIAL(SYBIMAGE, XSYBVARBINARY, 8)
+-	assert(tds_get_cardinal_type(column->on_server.column_type) == column->column_type
++	assert(tds_get_cardinal_type(column->on_server.column_type, column->column_usertype) == column->column_type
+ 		|| (tds_get_null_type(column->column_type) == column->on_server.column_type
+ 		&& column->column_varint_size == 1 && is_fixed_type(column->column_type)));
+ 
+diff --git a/src/tds/tds_checks.h b/src/tds/tds_checks.h
+index 0d50055..bbb474c 100644
+--- a/src/tds/tds_checks.h
++++ b/src/tds/tds_checks.h
+@@ -20,7 +20,7 @@
+ #ifndef TDS_CHECKS_H
+ #define TDS_CHECKS_H
+ 
+-/* $Id: tds_checks.h,v 1.4 2008/12/09 09:39:14 freddy77 Exp $ */
++/* $Id: tds_checks.h,v 1.5 2009/11/26 09:07:28 freddy77 Exp $ */
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+ #endif
+@@ -48,9 +48,6 @@ void tds_check_column_extra(const TDSCOLUMN * column);
+ void tds_check_resultinfo_extra(const TDSRESULTINFO * res_info);
+ void tds_check_cursor_extra(const TDSCURSOR * cursor);
+ void tds_check_dynamic_extra(const TDSDYNAMIC * dynamic);
+-
+-int tds_get_cardinal_type(int datatype);
+-int tds_get_varint_size(TDSSOCKET * tds, int datatype);
+ #endif
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+diff --git a/src/tds/token.c b/src/tds/token.c
+index f1de333..fa9ae14 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.375 2009/09/03 11:53:47 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.376 2009/11/26 09:07:28 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2067,7 +2067,7 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 				return TDS_FAIL;
+ 			if (tds_get_char_data(tds, (char *) v->data, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
+-			v->type = tds_get_cardinal_type(type);
++			v->type = tds_get_cardinal_type(type, 0);
+ 		} else {
+ 			v->data = (TDS_CHAR*) malloc(colsize);
+ 			if (!v->data)
+
+commit 60827da1e8795827d0be2c2d7bcd7871e50fdb9c
+Author: freddy77 <freddy77>
+Date:   Thu Nov 26 09:47:40 2009 +0000
+
+    Move server_addr into ctlib
+
+diff --git a/ChangeLog b/ChangeLog
+index 725255a..2ddd0d8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Nov 26 10:46:01 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/ctlib.h include/tds.h src/ctlib/ct.c src/tds/config.c:
++	* src/tds/login.c src/tds/mem.c:
++	- Move server_addr into ctlib
++
+ Thu Nov 26 10:06:51 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/data.c src/tds/tds_checks.c:
+ 	* src/tds/tds_checks.h src/tds/token.c:
+@@ -1912,4 +1917,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2888 2009/11/26 09:07:27 freddy77 Exp $
++$Id: ChangeLog,v 1.2889 2009/11/26 09:47:40 freddy77 Exp $
+diff --git a/include/ctlib.h b/include/ctlib.h
+index a047851..98e213d 100644
+--- a/include/ctlib.h
++++ b/include/ctlib.h
+@@ -36,7 +36,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.27 2009/06/08 19:55:11 freddy77 Exp $";
++static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.28 2009/11/26 09:47:41 freddy77 Exp $";
+ static const void *const no_unused_ctlib_h_warn[] = { rcsid_ctlib_h, no_unused_ctlib_h_warn };
+ 
+ #include <tds.h>
+@@ -127,6 +127,7 @@ struct _cs_connection
+ 	CS_LOCALE *locale;
+ 	CS_COMMAND_LIST *cmds;
+ 	CS_DYNAMIC_LIST *dynlist;
++	char *server_addr;
+ };
+ 
+ /*
+diff --git a/include/tds.h b/include/tds.h
+index 61c2280..ad67cc3 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.322 2009/11/26 09:07:28 freddy77 Exp $ */
++/* $Id: tds.h,v 1.323 2009/11/26 09:47:41 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -838,7 +838,6 @@ typedef union
+ typedef struct tds_login
+ {
+ 	DSTR server_name;
+-	DSTR server_addr;
+ 	int port;
+ 	TDS_USMALLINT tds_version;	/* TDS version */
+ 	int block_size;
+@@ -1474,7 +1473,6 @@ void tds_set_bulk(TDSLOGIN * tds_login, TDS_TINYINT enabled);
+ void tds_set_user(TDSLOGIN * tds_login, const char *username);
+ void tds_set_app(TDSLOGIN * tds_login, const char *application);
+ void tds_set_host(TDSLOGIN * tds_login, const char *hostname);
+-void tds_set_server_addr(TDSLOGIN * tds_login, const char *server_addr);
+ void tds_set_library(TDSLOGIN * tds_login, const char *library);
+ void tds_set_server(TDSLOGIN * tds_login, const char *server);
+ void tds_set_client_charset(TDSLOGIN * tds_login, const char *charset);
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index aa7b79e..71b511f 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.200 2009/11/23 08:50:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.201 2009/11/26 09:47:41 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -286,6 +286,7 @@ ct_con_alloc(CS_CONTEXT * ctx, CS_CONNECTION ** con)
+ 		return CS_FAIL;
+ 	}
+ 	(*con)->tds_login = login;
++	(*con)->server_addr = NULL;
+ 
+ 	/* so we know who we belong to */
+ 	(*con)->ctx = ctx;
+@@ -347,7 +348,6 @@ ct_con_props(CS_CONNECTION * con, CS_INT action, CS_INT property, CS_VOID * buff
+ 	CS_INT intval = 0, maxcp;
+ 	TDSSOCKET *tds;
+ 	TDSLOGIN *tds_login;
+-	char *set_buffer = NULL;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_con_props(%p, %d, %d, %p, %d, %p)\n", con, action, property, buffer, buflen, out_len);
+ 
+@@ -357,6 +357,8 @@ ct_con_props(CS_CONNECTION * con, CS_INT action, CS_INT property, CS_VOID * buff
+ 	tds_login = con->tds_login;
+ 
+ 	if (action == CS_SET) {
++		char *set_buffer = NULL;
++
+ 		if (property == CS_USERNAME || property == CS_PASSWORD || property == CS_APPNAME ||
+ 			property == CS_HOSTNAME || property == CS_SERVERADDR) {
+ 			if (buflen == CS_NULLTERM) {
+@@ -402,8 +404,10 @@ ct_con_props(CS_CONNECTION * con, CS_INT action, CS_INT property, CS_VOID * buff
+ 			if (!host || !port)
+ 				return CS_FAIL;
+ 
+-			portno= (int)strtol(port, NULL, 10);
+-			tds_set_server_addr(tds_login, host);
++			portno = (int)strtol(port, NULL, 10);
++			if (portno < 1 || portno >= 65536)
++				return CS_FAIL;
++			con->server_addr = strdup(host);
+ 			tds_set_port(tds_login, portno);
+ 			break;
+ 		}
+@@ -587,8 +591,8 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "ct_connect(%p, %s, %d)\n", con, servername ? servername : "NULL", snamelen);
+ 
+-	if (!tds_dstr_isempty(&con->tds_login->server_addr)) {
+-		server = tds_dstr_buf(&con->tds_login->server_addr);
++	if (con->server_addr) {
++		server = "";
+ 	} else if (snamelen == 0 || snamelen == CS_UNUSED) {
+ 		server = NULL;
+ 	} else if (snamelen == CS_NULLTERM) {
+@@ -611,6 +615,8 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 		con->tds_socket = NULL;
+ 		return CS_FAIL;
+ 	}
++	if (con->server_addr)
++		tds_dstr_copy(&connection->server_host_name, con->server_addr);
+ 
+ 	/* override locale settings with CS_CONNECTION settings, if any */
+ 	if (con->locale) {
+@@ -1896,6 +1902,7 @@ ct_con_drop(CS_CONNECTION * con)
+ 		}
+ 		if (con->locale)
+ 			_cs_locale_free(con->locale);
++		free(con->server_addr);
+ 		free(con);
+ 	}
+ 	return CS_SUCCEED;
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 0e98808..6610c5f 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.150 2009/11/24 15:48:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.151 2009/11/26 09:47:41 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -367,6 +367,8 @@ static int
+ tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection)
+ {
+ 	tds_read_conf_section(in, "global", tds_parse_conf_section, connection);
++	if (!server[0])
++		return 0;
+ 	rewind(in);
+ 	return tds_read_conf_section(in, server, tds_parse_conf_section, connection);
+ }
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 05be59a..223d3d9 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.189 2009/09/28 14:07:04 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.190 2009/11/26 09:47:41 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -145,14 +145,6 @@ tds_set_server(TDSLOGIN * tds_login, const char *server)
+ }
+ 
+ void
+-tds_set_server_addr(TDSLOGIN * tds_login, const char *server_addr)
+-{
+-	if (server_addr) {
+-		tds_dstr_copy(&tds_login->server_addr, server_addr);
+-	}
+-}
+-
+-void
+ tds_set_library(TDSLOGIN * tds_login, const char *library)
+ {
+ 	tds_dstr_copy(&tds_login->library, library);
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 81f0eb5..43987a4 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.192 2009/11/22 21:49:49 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.193 2009/11/26 09:47:41 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -982,7 +982,6 @@ tds_alloc_login(void)
+ 	
+ 	TEST_MALLOC(tds_login, TDSLOGIN);
+ 	tds_dstr_init(&tds_login->server_name);
+-	tds_dstr_init(&tds_login->server_addr);
+ 	tds_dstr_init(&tds_login->language);
+ 	tds_dstr_init(&tds_login->server_charset);
+ 	tds_dstr_init(&tds_login->client_host_name);
+@@ -1017,7 +1016,6 @@ tds_free_login(TDSLOGIN * login)
+ 		tds_dstr_zero(&login->password);
+ 		tds_dstr_free(&login->password);
+ 		tds_dstr_free(&login->server_name);
+-		tds_dstr_free(&login->server_addr);
+ 		tds_dstr_free(&login->language);
+ 		tds_dstr_free(&login->server_charset);
+ 		tds_dstr_free(&login->client_host_name);
+
+commit e495fbb4f2dbc2f1a8d5f68c78c64845265c731d
+Author: freddy77 <freddy77>
+Date:   Fri Nov 27 16:16:38 2009 +0000
+
+    Fix SQLGetData from fixed to CHAR not returning always SQL_SUCCESS
+
+diff --git a/ChangeLog b/ChangeLog
+index 2ddd0d8..86b932a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Nov 27 17:15:36 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/getdata.c:
++	- Fix SQLGetData from fixed to CHAR not returning always
++	  SQL_SUCCESS
++
+ Thu Nov 26 10:46:01 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/ctlib.h include/tds.h src/ctlib/ct.c src/tds/config.c:
+ 	* src/tds/login.c src/tds/mem.c:
+@@ -1917,4 +1922,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2889 2009/11/26 09:47:40 freddy77 Exp $
++$Id: ChangeLog,v 1.2890 2009/11/27 16:16:38 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index ed72926..708416e 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.515 2009/11/19 08:45:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.516 2009/11/27 16:16:39 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -4732,7 +4732,7 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 				ODBC_RETURN(stmt, SQL_SUCCESS_WITH_INFO);
+ 			}
+ 		} else {
+-			colinfo->column_text_sqlgetdatapos = colinfo->column_size;
++			colinfo->column_text_sqlgetdatapos = colinfo->column_cur_size;
+ 		}
+ 	}
+ 	ODBC_RETURN_(stmt);
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 76f169f..f67701c 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.10 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.11 2009/11/27 16:16:39 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -64,7 +64,7 @@ mycmp(const char *s1, const char *s2)
+ int
+ main(int argc, char *argv[])
+ {
+-	char buf[16];
++	char buf[32];
+ 	SQLINTEGER int_buf;
+ 	SQLLEN len;
+ 
+@@ -142,19 +142,42 @@ main(int argc, char *argv[])
+ 
+ 	ResetStatement();
+ 
++	/* test with numeric */
++	Command("SELECT CONVERT(NUMERIC(18,5), 1850000000000)");
++
++	CHKFetch("S");
++
++	memset(buf, 'x', sizeof(buf));
++	CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "S");
++	buf[sizeof(buf)-1] = 0;
++	if (strcmp(buf, "1850000000000") != 0) {
++		printf("Wrong data result: %s\n", buf);
++		exit(1);
++	}
++
++	/* should give NO DATA */
++	CHKGetData(1, SQL_C_CHAR, buf, 14, NULL, "No");
++	buf[sizeof(buf)-1] = 0;
++	if (strcmp(buf, "1850000000000") != 0) {
++		printf("Wrong data result 3 res = %s\n", buf);
++		exit(1);
++	}
++
++	ResetStatement();
++
+ 	Disconnect();
+ 
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+ 	/* test error from SQLGetData */
+-	/* wrong constant */
++	/* wrong constant, SQL_VARCHAR is invalid as C type */
+ 	test_err("prova 123",           SQL_VARCHAR,     "HY003");
+ 	/* use ARD but no ARD data column */
+ 	test_err("prova 123",           SQL_ARD_TYPE,    "07009");
+ 	/* wrong conversion, int */
+ 	test_err("prova 123",           SQL_C_LONG,      "22018");
+-	/* wrong conversion, int */
++	/* wrong conversion, date */
+ 	test_err("prova 123",           SQL_C_TIMESTAMP, "22018");
+ 	/* overflow */
+ 	test_err("1234567890123456789", SQL_C_LONG,      "22003");
+
+commit d02bc9fbc65c3a4505ae7b6f4acb8cebd5bed29a
+Author: freddy77 <freddy77>
+Date:   Fri Nov 27 18:01:48 2009 +0000
+
+    Fix SQL_GUID length
+
+diff --git a/ChangeLog b/ChangeLog
+index 86b932a..6c79f91 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Nov 27 19:01:33 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c src/odbc/unittests/describecol.in:
++	- Fix SQL_GUID length
++
+ Fri Nov 27 17:15:36 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/getdata.c:
+ 	- Fix SQLGetData from fixed to CHAR not returning always
+@@ -1922,4 +1926,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2890 2009/11/27 16:16:38 freddy77 Exp $
++$Id: ChangeLog,v 1.2891 2009/11/27 18:01:48 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 901cab2..99ce907 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.109 2009/08/18 15:11:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.110 2009/11/27 18:01:48 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -519,7 +519,7 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ #if (ODBCVER >= 0x0300)
+ 	case SYBUNIQUE:
+ 		/* FIXME for Sybase ?? */
+-		SET_INFO("uniqueidentifier", "'", "'");
++		SET_INFO2("uniqueidentifier", "'", "'", 36);
+ 	case SYBVARIANT:
+ 		/* SET_INFO("sql_variant", "", ""); */
+ 		break;
+diff --git a/src/odbc/unittests/describecol.in b/src/odbc/unittests/describecol.in
+index b1aaa7f..d4ae363 100644
+--- a/src/odbc/unittests/describecol.in
++++ b/src/odbc/unittests/describecol.in
+@@ -448,6 +448,15 @@ attr SQL_DESC_PRECISION 4096
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 8192
+ 
++select uniqueidentifier 'AAAAAAAA-BBBB-CCCC-DDDD-EEEEEEEEEEEE'
++attr SQL_COLUMN_LENGTH 16
++attr SQL_COLUMN_PRECISION 36
++attr SQL_COLUMN_SCALE 0
++attr SQL_DESC_LENGTH 36
++attr SQL_DESC_OCTET_LENGTH 16
++attr SQL_DESC_PRECISION 36
++attr SQL_DESC_SCALE 0
++attr SQL_DESC_DISPLAY_SIZE 36
+ 
+ 
+ 
+
+commit 1f9ad6e06a42111bd4b872e0003709dd1dad099d
+Author: freddy77 <freddy77>
+Date:   Sun Nov 29 18:56:47 2009 +0000
+
+    Fix row number return for cursors
+
+diff --git a/ChangeLog b/ChangeLog
+index 6c79f91..1b19737 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Nov 29 19:56:38 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: Fix row number return for cursors
++
+ Fri Nov 27 19:01:33 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c src/odbc/unittests/describecol.in:
+ 	- Fix SQL_GUID length
+@@ -1926,4 +1929,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2891 2009/11/27 18:01:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2892 2009/11/29 18:56:47 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 708416e..51f2693 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.516 2009/11/27 16:16:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.517 2009/11/29 18:56:47 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -3017,6 +3017,7 @@ odbc_cursor_execute(TDS_STMT * stmt)
+ 	/* set cursor name for TDS7+ */
+ 	if (ret == TDS_SUCCEED && IS_TDS7_PLUS(tds) && !tds_dstr_isempty(&stmt->cursor_name)) {
+ 		ret = tds_process_simple_query(tds);
++		stmt->row_count = tds->rows_affected;
+ 		stmt->dbc->current_statement = NULL;
+ 		if (ret == TDS_SUCCEED && cursor->cursor_id != 0) {
+ 			ret = tds_cursor_setname(tds, cursor);
+@@ -3068,6 +3069,8 @@ _SQLExecute(TDS_STMT * stmt)
+ 	stmt->curr_param_row = 0;
+ 	stmt->num_param_rows = ODBC_MAX(1, stmt->apd->header.sql_desc_array_size);
+ 
++	stmt->row_count = TDS_NO_COUNT;
++
+ 	if (stmt->prepared_query_is_rpc) {
+ 		/* TODO support stmt->apd->header.sql_desc_array_size for RPC */
+ 		/* get rpc name */
+@@ -3148,6 +3151,7 @@ _SQLExecute(TDS_STMT * stmt)
+ 				ODBC_RETURN(stmt, SQL_ERROR);
+ 			}
+ 		}
++		stmt->row_count = TDS_NO_COUNT;
+ 		if (stmt->num_param_rows <= 1) {
+ 			dyn = stmt->dyn;
+ 			tds_free_input_params(dyn);
+@@ -3185,7 +3189,6 @@ _SQLExecute(TDS_STMT * stmt)
+ 	if (!odbc_lock_statement(stmt))
+ 		ODBC_RETURN_(stmt);
+ 
+-	stmt->row_count = TDS_NO_COUNT;
+ 	stmt->row_status = PRE_NORMAL_ROW;
+ 
+ 	stmt->curr_param_row = 0;
+
+commit 17259ddb3ecd74a6736c7b6bae62d3f942d6008d
+Author: freddy77 <freddy77>
+Date:   Sun Nov 29 19:02:45 2009 +0000
+
+    Test univarchar from server
+
+diff --git a/ChangeLog b/ChangeLog
+index 1b19737..e6395a0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Nov 29 20:02:37 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c: Test univarchar from server
++
+ Sun Nov 29 19:56:38 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: Fix row number return for cursors
+ 
+@@ -1929,4 +1932,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2892 2009/11/29 18:56:47 freddy77 Exp $
++$Id: ChangeLog,v 1.2893 2009/11/29 19:02:45 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index d811938..de96279 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,12 +13,14 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.30 2009/08/20 18:59:29 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.31 2009/11/29 19:02:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+ static char sbuf[1024];
+ 
++static int ignore_select_error = 0;
++
+ static void
+ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, const char *expected)
+ {
+@@ -37,7 +39,17 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 		sprintf(sbuf, "SELECT CONVERT(%s, %s) COLLATE Latin1_General_CI_AS AS data", type, value_to_convert);
+ 	else if (strcmp(type, "SQL_VARIANT") == 0)
+ 		sprintf(sbuf, "SELECT CONVERT(SQL_VARIANT, %s) AS data", value_to_convert);
+-	Command(sbuf);
++	else if (strncmp(value_to_convert, "u&'", 3) == 0)
++		sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert);
++	if (ignore_select_error) {
++		if (Command2(sbuf, "SENo") == SQL_ERROR) {
++			ResetStatement();
++			return;
++		}
++	} else {
++		Command(sbuf);
++	}
++	ignore_select_error = 0;
+ 	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+@@ -153,6 +165,9 @@ main(int argc, char *argv[])
+ 		Test("NVARCHAR(20)", "-24785  ", SQL_C_LONG, "-24785");
+ 	}
+ 
++	ignore_select_error = 1;
++	Test("UNIVARCHAR(10)", "u&'\\06A4\\FBA5'", SQL_C_WCHAR, "2 \\u06a4\\ufba5");
++
+ 	/* case (1) */
+ 	Test("DECIMAL", "1234.5678", SQL_C_BINARY, "120001D3040000000000000000000000000000");
+ 	Test("NUMERIC", "8765.4321", SQL_C_BINARY, "1200013D220000000000000000000000000000");
+
+commit 260b966ce924f98e100270ce040cbd0d12ea4980
+Author: freddy77 <freddy77>
+Date:   Sun Nov 29 20:06:28 2009 +0000
+
+    Fix MS ODBC problem during test
+
+diff --git a/ChangeLog b/ChangeLog
+index e6395a0..7a384df 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Nov 29 21:06:18 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/data.c: Fix MS ODBC problem during test
++
+ Sun Nov 29 20:02:37 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: Test univarchar from server
+ 
+@@ -1932,4 +1935,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2893 2009/11/29 19:02:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2894 2009/11/29 20:06:28 freddy77 Exp $
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index de96279..275e722 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.31 2009/11/29 19:02:45 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.32 2009/11/29 20:06:28 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -202,7 +202,8 @@ main(int argc, char *argv[])
+ 		Test("SQL_VARIANT", "CAST('foo' AS NVARCHAR(10))", SQL_C_CHAR, "3 foo");
+ 		Test("SQL_VARIANT", "CAST('Super' AS NCHAR(8))", SQL_C_CHAR, "8 Super   ");
+ 		Test("SQL_VARIANT", "CAST('321' AS VARBINARY(10))", SQL_C_CHAR, "6 333231");
+-		Test("SQL_VARIANT", "CAST('-123.4' AS FLOAT)", SQL_C_CHAR, "6 -123.4");
++		/* for some reasons MS ODBC seems to convert -123.4 to -123.40000000000001 */
++		Test("SQL_VARIANT", "CAST('-123.5' AS FLOAT)", SQL_C_CHAR, "6 -123.5");
+ 		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "7 -123.40");
+ 	}
+ 
+
+commit 9b9528939a593b893c49568c13df1d59f89adf4b
+Author: freddy77 <freddy77>
+Date:   Sun Nov 29 20:16:36 2009 +0000
+
+    Check error if conversion truncate data
+
+diff --git a/ChangeLog b/ChangeLog
+index 7a384df..6ecdf8d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Nov 29 21:16:19 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/getdata.c:
++	- Check error if conversion truncate data
++
+ Sun Nov 29 21:06:18 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: Fix MS ODBC problem during test
+ 
+@@ -1935,4 +1939,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2894 2009/11/29 20:06:28 freddy77 Exp $
++$Id: ChangeLog,v 1.2895 2009/11/29 20:16:36 freddy77 Exp $
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index f67701c..8a02da3 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.11 2009/11/27 16:16:39 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.12 2009/11/29 20:16:36 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -67,6 +67,7 @@ main(int argc, char *argv[])
+ 	char buf[32];
+ 	SQLINTEGER int_buf;
+ 	SQLLEN len;
++	SQLRETURN rc;
+ 
+ 	Connect();
+ 
+@@ -165,6 +166,40 @@ main(int argc, char *argv[])
+ 
+ 	ResetStatement();
+ 
++
++	/* test int to truncated string */
++	Command("SELECT CONVERT(INTEGER, 12345)");
++	CHKFetch("S");
++
++	/* error 22003 */
++	CHKGetData(1, SQL_C_CHAR, buf, 4, NULL, "E");
++	ReadError();
++	if (strcmp(odbc_sqlstate, "22003") != 0) {
++		fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
++		Disconnect();
++		exit(1);
++	}
++	CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
++	ResetStatement();
++
++	/* test unique identifier to truncated string */
++	rc = Command2("SELECT CONVERT(UNIQUEIDENTIFIER, 'AA7DF450-F119-11CD-8465-00AA00425D90')", "SENo");
++	if (rc != SQL_ERROR) {
++		CHKFetch("S");
++
++		/* error 22003 */
++		CHKGetData(1, SQL_C_CHAR, buf, 17, NULL, "E");
++		ReadError();
++		if (strcmp(odbc_sqlstate, "22003") != 0) {
++			fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
++			Disconnect();
++			exit(1);
++		}
++		CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
++	}
++	ResetStatement();
++
++
+ 	Disconnect();
+ 
+ 	use_odbc_version3 = 1;
+
+commit f47d2c8eb9db7a90dff172ba24cf746deaf32f7f
+Author: jklowden <jklowden>
+Date:   Wed Dec 2 22:35:16 2009 +0000
+
+    add Microsoft db-lib error symbols
+
+diff --git a/ChangeLog b/ChangeLog
+index 6ecdf8d..a1e43d4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Wed Dec  2 17:30:10 EST 2009	JK Lowden <jklowden@freetds.org>
++	* include/sqldb.h add Microsoft db-lib error symbols
++	* src/dblib/dblib.c 
++	- dbsqlok returns FAIL if error encountered in any DONEINPROC
++	- packet prior to returning.  Should return FAIL for
++	- RAISERROR('msg', 16,1).
++
+ Sun Nov 29 21:16:19 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/getdata.c:
+ 	- Check error if conversion truncate data
+@@ -1939,4 +1946,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2895 2009/11/29 20:16:36 freddy77 Exp $
++$Id: ChangeLog,v 1.2896 2009/12/02 22:35:16 jklowden Exp $
+diff --git a/include/sqldb.h b/include/sqldb.h
+index 3b64b71..f685642 100644
+--- a/include/sqldb.h
++++ b/include/sqldb.h
+@@ -52,6 +52,120 @@
+ #define DBERRHANDLE_PROC EHANDLEFUNC 
+ #define DBMSGHANDLE_PROC MHANDLEFUNC 
+ 
++/* DB-Library errors as defined by Microsoft */
++#define SQLEMEM		SYBEMEM
++#define SQLENULL	SYBENULL
++#define SQLENLOG	SYBENLOG
++#define SQLEPWD		SYBEPWD
++#define SQLECONN	SYBECONN
++#define SQLEDDNE	SYBEDDNE
++#define SQLENULLO	SYBENULLO
++#define SQLESMSG	SYBESMSG
++#define SQLEBTOK	SYBEBTOK
++#define SQLENSPE	SYBENSPE
++#define SQLEREAD	SYBEREAD
++#define SQLECNOR	SYBECNOR
++#define SQLETSIT	SYBETSIT
++#define SQLEPARM	SYBEPARM
++#define SQLEAUTN	SYBEAUTN
++#define SQLECOFL	SYBECOFL
++#define SQLERDCN	SYBERDCN
++#define SQLEICN		SYBEICN
++#define SQLECLOS	SYBECLOS
++#define SQLENTXT	SYBENTXT
++#define SQLEDNTI	SYBEDNTI
++#define SQLETMTD	SYBETMTD
++#define SQLEASEC	SYBEASEC
++#define SQLENTLL	SYBENTLL
++#define SQLETIME	SYBETIME
++#define SQLEWRIT	SYBEWRIT
++#define SQLEMODE	SYBEMODE
++#define SQLEOOB		SYBEOOB
++#define SQLEITIM	SYBEITIM
++#define SQLEDBPS	SYBEDBPS
++#define SQLEIOPT	SYBEIOPT
++#define SQLEASNL	SYBEASNL
++#define SQLEASUL	SYBEASUL
++#define SQLENPRM	SYBENPRM
++#define SQLEDBOP	SYBEDBOP
++#define SQLENSIP	SYBENSIP
++#define SQLECNULL	SYBECNULL
++#define SQLESEOF	SYBESEOF
++#define SQLERPND	SYBERPND
++#define SQLECSYN	SYBECSYN
++#define SQLENONET	SYBENONET
++#define SQLEBTYP	SYBEBTYP
++#define SQLEABNC	SYBEABNC
++#define SQLEABMT	SYBEABMT
++#define SQLEABNP	SYBEABNP
++#define SQLEBNCR	SYBEBNCR
++#define SQLEAAMT	SYBEAAMT
++#define SQLENXID	SYBENXID
++#define SQLEIFNB	SYBEIFNB
++#define SQLEKBCO	SYBEKBCO
++#define SQLEBBCI	SYBEBBCI
++#define SQLEKBCI	SYBEKBCI
++#define SQLEBCWE	SYBEBCWE
++#define SQLEBCNN	SYBEBCNN
++#define SQLEBCOR	SYBEBCOR
++#define SQLEBCPI	SYBEBCPI
++#define SQLEBCPN	SYBEBCPN
++#define SQLEBCPB	SYBEBCPB
++#define SQLEVDPT	SYBEVDPT
++#define SQLEBIVI	SYBEBIVI
++#define SQLEBCBC	SYBEBCBC
++#define SQLEBCFO	SYBEBCFO
++#define SQLEBCVH	SYBEBCVH
++#define SQLEBCUO	SYBEBCUO
++#define SQLEBUOE	SYBEBUOE
++#define SQLEBWEF	SYBEBWEF
++#define SQLEBTMT	SYBEBTMT
++#define SQLEBEOF	SYBEBEOF
++#define SQLEBCSI	SYBEBCSI
++#define SQLEPNUL	SYBEPNUL
++#define SQLEBSKERR	SYBEBSKERR
++#define SQLEBDIO	SYBEBDIO
++#define SQLEBCNT	SYBEBCNT
++#define SQLEMDBP	SYBEMDBP
++#define SQLINIT		SYBINIT
++#define SQLCRSINV	SYBCRSINV
++#define SQLCRSCMD	SYBCRSCMD
++#define SQLCRSNOIND	SYBCRSNOIND
++#define SQLCRSDIS	SYBCRSDIS
++#define SQLCRSAGR	SYBCRSAGR
++#define SQLCRSORD	SYBCRSORD
++#define SQLCRSMEM	SYBCRSMEM
++#define SQLCRSBSKEY	SYBCRSBSKEY
++#define SQLCRSNORES	SYBCRSNORES
++#define SQLCRSVIEW	SYBCRSVIEW
++#define SQLCRSBUFR	SYBCRSBUFR
++#define SQLCRSFROWN	SYBCRSFROWN
++#define SQLCRSBROL	SYBCRSBROL
++#define SQLCRSFRAND	SYBCRSFRAND
++#define SQLCRSFLAST	SYBCRSFLAST
++#define SQLCRSRO	SYBCRSRO
++#define SQLCRSTAB	SYBCRSTAB
++#define SQLCRSUPDTAB	SYBCRSUPDTAB
++#define SQLCRSUPDNB	SYBCRSUPDNB
++#define SQLCRSVIIND	SYBCRSVIIND
++#define SQLCRSNOUPD	SYBCRSNOUPD
++#define SQLCRSOS	SYBCRSOS
++#define SQLEBCSA	SYBEBCSA
++#define SQLEBCRO	SYBEBCRO
++#define SQLEBCNE	SYBEBCNE
++#define SQLEBCSK	SYBEBCSK
++#define SQLEUVBF	SYBEUVBF
++#define SQLEBIHC	SYBEBIHC
++#define SQLEBWFF	SYBEBWFF
++#define SQLNUMVAL	SYBNUMVAL
++#define SQLEOLDVR	SYBEOLDVR
++#define SQLEBCPS	SYBEBCPS
++#define SQLEDTC		SYBEDTC
++#define SQLENOTIMPL	SYBENOTIMPL
++#define SQLENONFLOAT	SYBENONFLOAT
++#define SQLECONNFB	SYBECONNFB
++
++
+ #define dbfreelogin(x) dbloginfree((x))
+ 
+ #define dbprocerrhandle(p, h) dberrhandle((h))
+@@ -59,7 +173,7 @@
+ 
+ #define dbwinexit()
+ 
+-static const char rcsid_sqldb_h[] = "$Id: sqldb.h,v 1.5 2009/01/16 20:27:56 jklowden Exp $";
++static const char rcsid_sqldb_h[] = "$Id: sqldb.h,v 1.6 2009/12/02 22:35:18 jklowden Exp $";
+ static const void *const no_unused_sqldb_h_warn[] = { rcsid_sqldb_h, no_unused_sqldb_h_warn };
+ 
+ 
+
+commit 41388b7daf3a2e519103abdd9f805aa629153bf1
+Author: jklowden <jklowden>
+Date:   Wed Dec 2 22:35:25 2009 +0000
+
+    dbsqlok returns FAIL if error encountered in any DONEINPROC packet prior to returning.  Should return FAIL for RAISERROR('msg', 16,1).
+
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index efbc23e..20142fd 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.355 2009/10/23 19:21:45 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.356 2009/12/02 22:35:25 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4544,6 +4544,7 @@ dbsqlok(DBPROCESS * dbproc)
+ 	TDSSOCKET *tds;
+ 	int done_flags;
+ 	TDS_INT result_type;
++	RETCODE return_code = SUCCEED;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsqlok(%p)\n", dbproc);
+ 	CHECK_DBPROC();
+@@ -4567,13 +4568,25 @@ dbsqlok(DBPROCESS * dbproc)
+ 	 * We're looking for a result token or a done token.
+          */
+ 	for (;;) {
++		int tds_code;
+ 		/* 
+ 		 * If we hit an end token -- e.g. if the command
+ 		 * submitted returned no data (like an insert) -- then
+ 		 * we process the end token to extract the status code. 
+ 		 */
+ 		tdsdump_log(TDS_DBG_FUNC, "dbsqlok() not done, calling tds_process_tokens()\n");
+-		switch (tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS)) {
++
++		tds_code = tds_process_tokens(tds, &result_type, &done_flags, TDS_TOKEN_RESULTS);
++
++		/* 
++		 * The error flag may be set for any intervening DONEINPROC packet, in particular
++		 * by a RAISERROR statement.  Microsoft db-lib returns FAIL in that case. 
++		 */
++		if (done_flags & TDS_DONE_ERROR) {
++			return_code = FAIL;
++		}
++		
++		switch (tds_code) {
+ 		case TDS_NO_MORE_RESULTS:
+ 			return SUCCEED;
+ 			break;
+@@ -4595,26 +4608,27 @@ dbsqlok(DBPROCESS * dbproc)
+ 				tdsdump_log(TDS_DBG_FUNC, "dbsqlok() found result token\n");
+ 				return SUCCEED;
+ 				break;
++			case TDS_DONEINPROC_RESULT:
++				break;
+ 			case TDS_DONE_RESULT:
+ 			case TDS_DONEPROC_RESULT:
++				tdsdump_log(TDS_DBG_FUNC, "dbsqlok() end status is %s\n", prdbretcode(return_code));
+ #if 1
+ 				if (done_flags & TDS_DONE_ERROR) {
+-					tdsdump_log(TDS_DBG_FUNC, "dbsqlok() end status was error\n");
+ 
+ 					if (done_flags & TDS_DONE_MORE_RESULTS) {
+ 						dbproc->dbresults_state = _DB_RES_NEXT_RESULT;
+-						return SUCCEED;
+ 					} else {
+ 						dbproc->dbresults_state = _DB_RES_NO_MORE_RESULTS;
+ 					}
+ 
+-					return FAIL;
+ 				} else {
+ 					tdsdump_log(TDS_DBG_FUNC, "dbsqlok() end status was success\n");
+ 
+ 					dbproc->dbresults_state = _DB_RES_SUCCEED;
+-					return SUCCEED;
+ 				}
++
++				return return_code;
+ 				break;
+ #else
+ 				int retcode = (done_flags & TDS_DONE_ERROR)? FAIL : SUCCEED;
+@@ -4630,6 +4644,8 @@ dbsqlok(DBPROCESS * dbproc)
+ 				return retcode;
+ #endif
+ 			default:
++				tdsdump_log(TDS_DBG_FUNC, "%s %d: logic error: tds_process_tokens result_type %d\n", 
++						__FILE__, __LINE__, result_type);
+ 				break;
+ 			}
+ 			break;
+
+commit fa1320d3f53240ba77a4827b1c450509ae46db84
+Author: jklowden <jklowden>
+Date:   Wed Dec 2 22:58:21 2009 +0000
+
+    warning & uninitialized variable cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index a1e43d4..3290f74 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Dec  2 17:56:52 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c src/odbc/prepare_query.c src/tds/login.c
++	- warning & uninitialized variable cleanup
++
+ Wed Dec  2 17:30:10 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* include/sqldb.h add Microsoft db-lib error symbols
+ 	* src/dblib/dblib.c 
+@@ -1946,4 +1950,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2896 2009/12/02 22:35:16 jklowden Exp $
++$Id: ChangeLog,v 1.2897 2009/12/02 22:58:21 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 20142fd..d8f3e6b 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.356 2009/12/02 22:35:25 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.357 2009/12/02 22:58:21 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -2193,8 +2193,8 @@ dbconvert(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT srclen, int d
+ 	/* FIXME what happen if client do not reset values ??? */
+ 	/* FIXME act differently for ms and sybase */
+ 	if (is_numeric_type(desttype)) {
+-		num = (DBNUMERIC *) dest;
+-		if (num->precision <= 0 || num->precision > MAXPRECISION || num->scale < 0 || num->scale > num->precision) {
++		num = (DBNUMERIC *) dest;	                         /* num->scale is unsigned */
++		if (num->precision <= 0 || num->precision > MAXPRECISION || num->scale > num->precision) { 
+ 			dres.n.precision = 18;
+ 			dres.n.scale = 0;
+ 		} else {
+@@ -7122,7 +7122,6 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
+ 	CONV_RESULT dres;
+ 	DBINT ret;
+ 	int i, len;
+-	DBNUMERIC *num;
+ 	DBSMALLINT indicator_value = 0;
+ 
+ 	int limited_dest_space = 0;
+@@ -7142,8 +7141,8 @@ copy_data_to_host_var(DBPROCESS * dbproc, int srctype, const BYTE * src, DBINT s
+ 	/* oft times we are asked to convert a data type to itself */
+ 
+ 	if (is_numeric_type(desttype)) {
+-		num = (DBNUMERIC *) dest;
+-		if (num->precision <= 0 || num->precision > MAXPRECISION || num->scale < 0 || num->scale > num->precision) {
++		DBNUMERIC *num = (DBNUMERIC *) dest;	                         /* num->scale is unsigned */
++		if (num->precision <= 0 || num->precision > MAXPRECISION || num->scale > num->precision) { 
+ 			dres.n.precision = 18;
+ 			dres.n.scale = 0;
+ 		} else {
+diff --git a/src/odbc/prepare_query.c b/src/odbc/prepare_query.c
+index a3be5f4..d40131c 100644
+--- a/src/odbc/prepare_query.c
++++ b/src/odbc/prepare_query.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: prepare_query.c,v 1.78 2009/05/28 16:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: prepare_query.c,v 1.79 2009/12/02 22:58:21 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -367,7 +367,7 @@ continue_parse_prepared_query(struct _hstmt *stmt, SQLPOINTER DataPtr, SQLLEN St
+ 	if (blob) {
+ 		TDS_CHAR *p;
+ 		int binary_convert = 0;
+-		SQLLEN orig_len;
++		SQLLEN orig_len = len;
+ 
+ 		if (sql_src_type == SQL_C_CHAR || sql_src_type == SQL_C_WCHAR) {
+ 			switch (tds_get_conversion_type(curcol->column_type, curcol->column_size)) {
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 223d3d9..0ff62f4 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.190 2009/11/26 09:47:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.191 2009/12/02 22:58:21 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -316,7 +316,7 @@ free_save_context(TDSSAVECONTEXT *ctx)
+ int
+ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ {
+-	int erc;
++	int erc = TDSEFCON;
+ 	int connect_timeout = 0;
+ 	int db_selected = 0;
+ 
+@@ -351,7 +351,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		tds->env_chg_func = tds_save_env;
+ 		mod_ctx->err_handler = NULL;
+ 
+-		for (i=tds->use_iconv ? 1: 0; i < TDS_VECTOR_SIZE(versions); ++i) {
++		for (i = tds->use_iconv? 1 : 0; i < TDS_VECTOR_SIZE(versions); ++i) {
+ 			connection->tds_version = versions[i];
+ 			reset_save_context(&save_ctx);
+ 
+
+commit bbccd7ec71e131379e24bf1e95f936f79dbad54f
+Author: freddy77 <freddy77>
+Date:   Fri Dec 4 10:35:06 2009 +0000
+
+    check buffer unchanged if overflow detected
+
+diff --git a/ChangeLog b/ChangeLog
+index 3290f74..42e3985 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Dec  4 11:34:10 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/getdata.c:
++	- check buffer unchanged if overflow detected
++
+ Wed Dec  2 17:56:52 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c src/odbc/prepare_query.c src/tds/login.c
+ 	- warning & uninitialized variable cleanup
+@@ -1950,4 +1954,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2897 2009/12/02 22:58:21 jklowden Exp $
++$Id: ChangeLog,v 1.2898 2009/12/04 10:35:06 freddy77 Exp $
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 8a02da3..0617b13 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.12 2009/11/29 20:16:36 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.13 2009/12/04 10:35:06 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -172,7 +172,13 @@ main(int argc, char *argv[])
+ 	CHKFetch("S");
+ 
+ 	/* error 22003 */
++	memset(buf, 'x', sizeof(buf));
+ 	CHKGetData(1, SQL_C_CHAR, buf, 4, NULL, "E");
++	buf[4] = 0;
++	if (strcmp(buf, "xxxx") != 0) {
++		fprintf(stderr, "Wrong buffer result buf = %s\n", buf);
++		exit(1);
++	}
+ 	ReadError();
+ 	if (strcmp(odbc_sqlstate, "22003") != 0) {
+ 		fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
+
+commit 8ee4385a7645881cbef0240e653f28db0517ed3d
+Author: jklowden <jklowden>
+Date:   Sat Dec 5 20:25:31 2009 +0000
+
+    applied small optind patch from ML
+
+diff --git a/ChangeLog b/ChangeLog
+index 42e3985..7b57db4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Dec  5 14:43:00 EST 2009	JK Lowden <jklowden@freetds.org>
++	* src/apps/tsql.c applied small optind patch from ML
++
+ Fri Dec  4 11:34:10 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/getdata.c:
+ 	- check buffer unchanged if overflow detected
+@@ -15,7 +18,7 @@ Wed Dec  2 17:30:10 EST 2009	JK Lowden <jklowden@freetds.org>
+ 
+ Sun Nov 29 21:16:19 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/getdata.c:
+-	- Check error if conversion truncate data
++	- Check error if conversion truncates data
+ 
+ Sun Nov 29 21:06:18 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/data.c: Fix MS ODBC problem during test
+@@ -1954,4 +1957,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2898 2009/12/04 10:35:06 freddy77 Exp $
++$Id: ChangeLog,v 1.2899 2009/12/05 20:25:31 jklowden Exp $
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index c751969..e337b62 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.129 2009/10/23 19:21:38 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.130 2009/12/05 20:25:31 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -313,8 +313,10 @@ reset_getopt(void)
+ {
+ #ifdef HAVE_GETOPT_OPTRESET
+ 	optreset = 1;
+-#endif
+ 	optind = 1;
++#else
++	optind = 0;
++#endif
+ }
+ 
+ /*
+
+commit de41e8413182a93fa67eeea98bed9c30380ed4ca
+Author: freddy77 <freddy77>
+Date:   Mon Dec 7 16:22:12 2009 +0000
+
+    Ported test for conversion from '' text to SQL_C_BINARY, remove possible core
+
+diff --git a/ChangeLog b/ChangeLog
+index 7b57db4..6699551 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Dec  7 17:22:05 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/getdata.c src/tds/convert.c:
++	- Ported test for conversion from '' text to SQL_C_BINARY, remove
++	  possible core
++
+ Sat Dec  5 14:43:00 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/tsql.c applied small optind patch from ML
+ 
+@@ -1957,4 +1962,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2899 2009/12/05 20:25:31 jklowden Exp $
++$Id: ChangeLog,v 1.2900 2009/12/07 16:22:12 freddy77 Exp $
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 0617b13..36c6019 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.13 2009/12/04 10:35:06 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.14 2009/12/07 16:22:12 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -249,6 +249,20 @@ main(int argc, char *argv[])
+ 			lc = sizeof(SQLWCHAR);
+ 			type = SQL_C_WCHAR;
+ 		}	
++
++		Command("SELECT CONVERT(TEXT,'')");
++
++		CHKFetch("S");
++
++		len = 1234;
++		CHKGetData(1, SQL_C_BINARY, buf, 1, &len, "S");
++
++		if (len != 0) {
++			fprintf(stderr, "Wrong len returned, returned %ld\n", (long) len);
++			return 1;
++		}
++
++		CHKGetData(1, SQL_C_BINARY, buf, 1, NULL, "No");
+ 	}
+ 
+ 	Disconnect();
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index 0d1d44b..adc9967 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.193 2009/09/29 09:16:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.194 2009/12/07 16:22:12 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -351,7 +351,7 @@ tds_convert_char(int srctype, const TDS_CHAR * src, TDS_UINT srclen, int desttyp
+ 
+ 		/* skip leading "0x" or "0X" */
+ 
+-		if (src[0] == '0' && (src[1] == 'x' || src[1] == 'X')) {
++		if (srclen >= 2 && src[0] == '0' && (src[1] == 'x' || src[1] == 'X')) {
+ 			src += 2;
+ 			srclen -= 2;
+ 		}
+
+commit 364f12529ddd846e9aaf8e26709680c028f30d43
+Author: freddy77 <freddy77>
+Date:   Sun Dec 13 09:48:55 2009 +0000
+
+    Fix problem with long binary managed as char type (patch from Christian Hoffmann)
+
+diff --git a/ChangeLog b/ChangeLog
+index 6699551..c063433 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sun Dec 13 10:48:42 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c:
++	- Fix problem with long binary managed as char type (patch from
++	  Christian Hoffmann)
++
+ Mon Dec  7 17:22:05 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/getdata.c src/tds/convert.c:
+ 	- Ported test for conversion from '' text to SQL_C_BINARY, remove
+@@ -1962,4 +1967,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2900 2009/12/07 16:22:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2901 2009/12/13 09:48:55 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 71b511f..ec2406b 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.201 2009/11/26 09:47:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.202 2009/12/13 09:48:55 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2014,7 +2014,7 @@ _ct_get_client_type(TDSCOLUMN *col)
+ 	case SYBLONGBINARY:
+ 		if (col->column_usertype == USER_UNICHAR_TYPE || col->column_usertype == USER_UNIVARCHAR_TYPE)
+ 			return CS_UNICHAR_TYPE;
+-		return CS_CHAR_TYPE;
++		return CS_LONGBINARY_TYPE;
+ 		break;
+ 	}
+ 
+
+commit cc9dca6eda9778acb49bc0357baff33742904eb9
+Author: freddy77 <freddy77>
+Date:   Sun Dec 13 10:36:54 2009 +0000
+
+    Style and comments
+
+diff --git a/ChangeLog b/ChangeLog
+index c063433..2dd1e37 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Dec 13 11:36:48 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/t0006.c: Style and comments
++
+ Sun Dec 13 10:48:42 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c:
+ 	- Fix problem with long binary managed as char type (patch from
+@@ -1967,4 +1970,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2901 2009/12/13 09:48:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2902 2009/12/13 10:36:54 freddy77 Exp $
+diff --git a/src/ctlib/unittests/t0006.c b/src/ctlib/unittests/t0006.c
+index 5725ca2..0d98faa 100644
+--- a/src/ctlib/unittests/t0006.c
++++ b/src/ctlib/unittests/t0006.c
+@@ -9,21 +9,15 @@
+ #include <stdio.h>
+ #include <ctpublic.h>
+ 
+-static char software_version[] = "$Id: t0006.c,v 1.11 2005/06/29 07:21:08 freddy77 Exp $";
++static char software_version[] = "$Id: t0006.c,v 1.12 2009/12/13 10:36:54 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ CS_CONTEXT *ctx;
+-int allSuccess = 1;
++static int allSuccess = 1;
+ 
+ typedef const char *STR;
+ 
+-int DoTest(CS_INT fromtype, void *fromdata, CS_INT fromlen,
+-	   CS_INT totype, CS_INT tomaxlen,
+-	   CS_RETCODE tores, void *todata, CS_INT tolen,
+-	   STR sdecl,
+-	   STR sfromtype, STR sfromdata, STR sfromlen, STR stotype, STR stomaxlen, STR stores, STR stodata, STR stolen, int line);
+-
+-int
++static int
+ DoTest(
+ 	      /* source information */
+ 	      CS_INT fromtype, void *fromdata, CS_INT fromlen,
+@@ -31,8 +25,11 @@ DoTest(
+ 	      CS_INT totype, CS_INT tomaxlen,
+ 	      /* expected result */
+ 	      CS_RETCODE tores, void *todata, CS_INT tolen,
++	      /* fields in string format */
+ 	      STR sdecl,
+-	      STR sfromtype, STR sfromdata, STR sfromlen, STR stotype, STR stomaxlen, STR stores, STR stodata, STR stolen, int line)
++	      STR sfromtype, STR sfromdata, STR sfromlen, STR stotype, STR stomaxlen, STR stores, STR stodata, STR stolen,
++	      /* source line number for error reporting */
++	      int line)
+ {
+ 	CS_DATAFMT destfmt, srcfmt;
+ 	CS_INT reslen;
+
+commit fae7704ff6c3d375161166ffde137a0a8477507b
+Author: freddy77 <freddy77>
+Date:   Sun Dec 13 10:37:37 2009 +0000
+
+    Fix posting longbinary on Sybase server
+
+diff --git a/ChangeLog b/ChangeLog
+index 2dd1e37..c102b13 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Dec 13 11:37:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/rpc_ct_setparam.c src/tds/query.c:
++	- Fix posting longbinary on Sybase server
++
+ Sun Dec 13 11:36:48 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/t0006.c: Style and comments
+ 
+@@ -1970,4 +1974,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2902 2009/12/13 10:36:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2903 2009/12/13 10:37:37 freddy77 Exp $
+diff --git a/src/ctlib/unittests/rpc_ct_setparam.c b/src/ctlib/unittests/rpc_ct_setparam.c
+index b081b02..3d8f2d4 100644
+--- a/src/ctlib/unittests/rpc_ct_setparam.c
++++ b/src/ctlib/unittests/rpc_ct_setparam.c
+@@ -18,7 +18,7 @@
+ #define MAX(X,Y)      (((X) > (Y)) ? (X) : (Y))
+ #define MIN(X,Y)      (((X) < (Y)) ? (X) : (Y))
+ 
+-static char software_version[] = "$Id: rpc_ct_setparam.c,v 1.9 2006/12/29 19:00:33 freddy77 Exp $";
++static char software_version[] = "$Id: rpc_ct_setparam.c,v 1.10 2009/12/13 10:37:37 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ CS_RETCODE ex_clientmsg_cb(CS_CONTEXT * context, CS_CONNECTION * connection, CS_CLIENTMSG * errmsg);
+@@ -87,7 +87,7 @@ main(int argc, char *argv[])
+         @sintparam smallint output, @floatparam float output, \
+         @moneyparam money output,  \
+         @dateparam datetime output, @charparam char(20) output, \
+-        @binaryparam    binary(20) output) \
++        @binaryparam    varbinary(2000) output) \
+         as ");
+ 
+ 	strcat(cmdbuf, "select @intparam, @sintparam, @floatparam, @moneyparam, \
+@@ -266,8 +266,8 @@ main(int argc, char *argv[])
+ 
+ 	strcpy(datafmt.name, "@binaryparam");
+ 	datafmt.namelen = CS_NULLTERM;
+-	datafmt.datatype = CS_BINARY_TYPE;
+-	datafmt.maxlength = 255;
++	datafmt.datatype = CS_LONGBINARY_TYPE;
++	datafmt.maxlength = 2000;
+ 	datafmt.status = CS_RETURN;
+ 	datafmt.locale = NULL;
+ 
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 7200afb..4dd1d18 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.242 2009/10/02 09:24:08 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.243 2009/12/13 10:37:37 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1390,6 +1390,7 @@ tds_put_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 		case 2:
+ 			tds_put_smallint(tds, size);
+ 			break;
++		case 5:
+ 		case 4:
+ 			tds_put_int(tds, size);
+ 			break;
+@@ -1437,6 +1438,8 @@ tds_put_data_info_length(TDSSOCKET * tds, TDSCOLUMN * curcol, int flags)
+ 		len += curcol->column_namelen;
+ 	if (is_numeric_type(curcol->on_server.column_type))
+ 		len += 2;
++	if (curcol->column_varint_size == 5)
++		return len + 4;
+ 	return len + curcol->column_varint_size;
+ }
+ 
+@@ -1464,6 +1467,9 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	if (curcol->column_cur_size < 0) {
+ 		tdsdump_log(TDS_DBG_INFO1, "tds_put_data: null param\n");
+ 		switch (curcol->column_varint_size) {
++		case 5:
++			tds_put_int(tds, 0);
++			break;
+ 		case 4:
+ 			tds_put_int(tds, -1);
+ 			break;
+@@ -1588,6 +1594,10 @@ tds_put_data(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		/* TODO ICONV handle charset conversions for data */
+ 		/* put size of data */
+ 		switch (curcol->column_varint_size) {
++		case 5:	/* It's a LONGBINARY */
++			colsize = MIN(colsize, 0x7fffffff);
++			tds_put_int(tds, colsize);
++			break;
+ 		case 4:	/* It's a BLOB... */
+ 			tds_put_byte(tds, 16);
+ 			tds_put_n(tds, blob->textptr, 16);
+
+commit 56b1c529d52f1a3ab7f811869da1c54bf4aeb7db
+Author: jklowden <jklowden>
+Date:   Mon Dec 14 01:02:26 2009 +0000
+
+    updated documentation in preparation for upcoming release.
+
+diff --git a/ChangeLog b/ChangeLog
+index c102b13..be0bf2b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Dec 13 20:01:01 EST 2009	JK Lowden <jklowden@freetds.org>
++	* doc/freetds.conf.5 doc/userguide.sgml
++	- updated documentation in preparation for upcoming release. 
++
+ Sun Dec 13 11:37:31 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/rpc_ct_setparam.c src/tds/query.c:
+ 	- Fix posting longbinary on Sybase server
+@@ -1974,4 +1978,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2903 2009/12/13 10:37:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2904 2009/12/14 01:02:26 jklowden Exp $
+diff --git a/doc/freetds.conf.5 b/doc/freetds.conf.5
+index 524bbb9..5b5da16 100644
+--- a/doc/freetds.conf.5
++++ b/doc/freetds.conf.5
+@@ -1,4 +1,4 @@
+-.\" $Id: freetds.conf.5,v 1.3 2009/08/25 14:25:35 freddy77 Exp $
++.\" $Id: freetds.conf.5,v 1.4 2009/12/14 01:02:27 jklowden Exp $
+ .Dd December 23, 2007
+ .Os [FreeTDS] [@version@]
+ .Dt FREETDS.CONF 5
+@@ -10,7 +10,7 @@
+ .Sh SYNOPSIS
+ The 
+ .Pa freetds.conf
+-file describes Sybase and Microsoft dataservers to the
++file describes Sybase and Microsoft database servers to the
+ FreeTDS library.  It comprises sections headed by a servername, followed by a
+ list of connection properties denoted as name-value pairs.  Defaults are
+ defined via a 
+@@ -106,7 +106,7 @@ allow encrypted connections only
+ .El
+ .
+ .It host
+-Name of the host the dataserver is running on.
++Name of the host the server is running on.
+ .Bl -tag -width "default:" -compact
+ .It Domain:
+ host name or IP address
+@@ -134,7 +134,7 @@ none
+ .El
+ .
+ .It port
+-port number that the dataserver is listening to
++port number that the server is listening to
+ .Bl -tag -width "default:" -compact
+ .It Domain:
+ any valid port
+@@ -172,6 +172,14 @@ none (wait forever)
+ .
+ .El
+ .Pp
++Do not define both 
++.Fa port
++and
++.Fa instance Ns
++\&.  One implies the other.  
++
++
++.Pp
+ Boolean property values may be denoted as on/off, true/false, or 1/0.
+ .
+ .Ss DEBUG FLAGS 
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 2c34cab..4f07c80 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -1,14 +1,18 @@
+ <!doctype book PUBLIC "-//OASIS//DTD DocBook V4.1//EN" [
+-<!ENTITY dblibapisgml SYSTEM "../../../dblib.api.sgml">
+-<!ENTITY ctlibapisgml SYSTEM "../../../ctlib.api.sgml">
+-<!ENTITY  odbcapisgml SYSTEM "../../../odbc.api.sgml">
++	<!ENTITY dblibapisgml SYSTEM "../../../dblib.api.sgml">
++	<!ENTITY ctlibapisgml SYSTEM "../../../ctlib.api.sgml">
++	<!ENTITY  odbcapisgml SYSTEM "../../../odbc.api.sgml">
++	<!ENTITY ora "O'Reilly &amp; Associates">
++	<!ENTITY freetds "<productname>FreeTDS</productname>">
++	<!ENTITY version "0.92"> <!--  echo '0.84 + 0.5 * (1.0 - 0.84)' -->
++	<!ENTITY freetdsconf "<filename>freetds.conf</filename>">
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2009/08/25 14:25:35 $</date>
+-		<releaseinfo>$Revision: 1.125 $</releaseinfo>
+-		<title><productname>FreeTDS</productname> User Guide</title>
+-		<subtitle>A Guide to Installing, Configuring, and Running <productname>FreeTDS</productname></subtitle>
++		<date>$Date: 2009/12/14 01:02:27 $</date>
++		<releaseinfo>$Revision: 1.126 $</releaseinfo>
++		<title>&freetds; User Guide</title>
++		<subtitle>A Guide to Installing, Configuring, and Running &freetds;</subtitle>
+ 		<author>
+ 			<firstname>Brian</firstname>
+ 			<surname>Bruns</surname>
+@@ -46,7 +50,7 @@
+ 				<!-- ////////////////// CHAPTER /////////////////////// -->
+ 	<preface id="about"><title>About this User Guide</title>
+ 			<para>
+-This User Guide describes <productname>FreeTDS</productname> 0.82.  It is the product of (lots of) happy collaborative effort.  Although Brian's name and mine are at the top of it, behind it are many others, who contributed thoughtful suggestions, bamboozled questions, stellar prose, and terse instructions.  I don't mention this for the usual reasons (the enumeration of which I leave to you) but rather to emphasize that the purpose of our effort is to help you and those who come after you to have the easiest and most enjoyable time with <productname>FreeTDS</productname>.  
++This User Guide describes &freetds; &version;.  It is the product of (lots of) happy collaborative effort.  Although Brian's name and mine are at the top of it, behind it are many others, who contributed thoughtful suggestions, bamboozled questions, stellar prose, and terse instructions.  I don't mention this for the usual reasons (the enumeration of which I leave to you) but rather to emphasize that the purpose of our effort is to help you and those who come after you to have the easiest and most enjoyable time with &freetds;.  
+ 			</para>
+ 			<para>
+ It is surprisingly hard, after a while, to remember how it can be for someone newly approaching a project to use it.  What seems as obvious as a fog horn to an old hand may be much more like the fog itself to the newcomer.  That can make installing and setting up new software a puzzling or frustrating experience.  You may have heard, <quote>It's easy if you know how.</quote>  Indeed it is, and that's our purpose here: to make it easy, by letting you know how.  
+@@ -57,12 +61,12 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.125 $</>
+-<member>$Date: 2009/08/25 14:25:35 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.125 2009/08/25 14:25:35 freddy77 Exp $.</>
++<member>$Revision: 1.126 $</>
++<member>$Date: 2009/12/14 01:02:27 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.126 2009/12/14 01:02:27 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+-can be found on the <productname>FreeTDS</productname> 
++can be found on the &freetds; 
+ <ulink url="http://www.freetds.org/userguide/">web site</ulink>, where you will also find the most up to date <ulink url="http://www.freetds.org/faq.html">FAQ</ulink>, as well as links to the anonymous and browseable CVS tree.  If you find something wrong, unclear, badly put, misleading, or incorrigible, I hope you will let us know.  Post your musings or rants to the mailing list (see <link linkend="contrib">Helping</link>).  Patches to <filename>doc/userguide.sgml</> are especially welcome, of course.  By taking the time let us know what you think, perhaps the path to enlightenment will be made a little smoother for the fellow behind you.  
+ 			</para>
+ 			<para>
+@@ -78,13 +82,13 @@ Enough.  Let's begin.
+ 	</preface>
+ 
+ 	<chapter id="what">
+-		<title>What is <productname>FreeTDS</productname>?</title>
++		<title>What is &freetds;?</title>
+ 
+ 		<para>
+-<productname>FreeTDS</productname> is an open source (or free software if you prefer) programming library, a re-implementation of the Tabular Data Stream protocol.  It can be used in place of Sybase's <systemitem class="library">db-lib</systemitem> or <systemitem class="library">ct-lib</systemitem> libraries.  It also includes an <systemitem class="library">ODBC library</systemitem>.  It allows many open source applications such as <productname>Perl</productname> and <productname>PHP</productname> (or your own C or C++ program) to connect to Sybase or Microsoft <productname>SQL Server</productname>.   
++&freetds; is an open source (or free software if you prefer) programming library, a re-implementation of the Tabular Data Stream protocol.  It can be used in place of Sybase's <systemitem class="library">db-lib</systemitem> or <systemitem class="library">ct-lib</systemitem> libraries.  It also includes an <systemitem class="library">ODBC library</systemitem>.  It allows many open source applications such as <productname>Perl</productname> and <productname>PHP</productname> (or your own C or C++ program) to connect to Sybase or Microsoft <productname>SQL Server</productname>.   
+ 		</para>
+ 		<para>
+-<productname>FreeTDS</productname> is distributed in source code form, and is expected to compile on just about any operating system.  That means every form of Unix&reg; and Unix-like&trade; system (including notable variants such as Interix&reg; and QNX&reg;), as well as Win32&reg;, VMS&reg;, and OS X&reg;.  If it doesn't compile on your system &mdash; and you're not using MS-DOS&reg; &mdash; it's probably considered a bug.  
++&freetds; is distributed in source code form, and is expected to compile on just about any operating system.  That means every form of Unix&reg; and Unix-like&trade; system (including notable variants such as Interix&reg; and QNX&reg;), as well as Win32&reg;, VMS&reg;, and OS X&reg;.  If it doesn't compile on your system &mdash; and you're not using MS-DOS&reg; &mdash; it's probably considered a bug.  
+ 		</para>
+ 		<sect1 id="tdsprotocolhist">
+ 			<title>Background: The <acronym>TDS</> Protocol
+@@ -172,15 +176,15 @@ Introduced for <productname>SQL Server 2005</productname>.  Includes support for
+ 			</variablelist>
+ 		  </sect1>
+ 
+-		  <sect1 id="FreeTDShistory"> <title>History of <productname>FreeTDS</productname></title>
++		  <sect1 id="FreeTDShistory"> <title>History of &freetds;</title>
+ 			<para>
+-<productname>FreeTDS</productname> was and is developed by observation and experimentation, which is to say, by trial and error.  
++&freetds; was and is developed by observation and experimentation, which is to say, by trial and error.  
+ 			</para>
+ 			<para>
+ In early 1997, the only option for connecting to a Sybase server from Linux or other free systems was an aging Sybase-released version of <productname>OpenClient</productname>.  Unfortunately it had a few problems.  The original release was <symbol>a.out</>-based, although Greg Thain did a great service in converting the library to ELF.  Secondly, it included only the newer <systemitem class="library">ct-lib</systemitem> <acronym>API</>.  The older <systemitem class="library">db-lib</systemitem> <acronym>API</> was missing.
+ 			</para>
+ 			<para>
+-Brian Bruns, a Sybase DBA and originator of the <productname>FreeTDS</productname> project, had some <systemitem class="library">db-lib</systemitem> programs he wanted to run under Linux, and thus began the <productname>FreeTDS</productname> project. The original work focused on <systemitem class="library">db-lib</systemitem> and version 5.0 of the protocol, but quickly expanded to include a <systemitem class="library">ct-lib</systemitem> compatible layer and <acronym>TDS</> version 4.2.  Later support for <systemitem class="library">ODBC</systemitem> and <acronym>TDS 7.0 and 7.1</> was added. Craig Spannring wrote a Java  <acronym>JDBC</> driver which became <productname>FreeTDS/JDBC</productname>.
++Brian Bruns, a Sybase DBA and originator of the &freetds; project, had some <systemitem class="library">db-lib</systemitem> programs he wanted to run under Linux, and thus began the &freetds; project. The original work focused on <systemitem class="library">db-lib</systemitem> and version 5.0 of the protocol, but quickly expanded to include a <systemitem class="library">ct-lib</systemitem> compatible layer and <acronym>TDS</> version 4.2.  Later support for <systemitem class="library">ODBC</systemitem> and <acronym>TDS 7.0 and 7.1</> was added. Craig Spannring wrote a Java  <acronym>JDBC</> driver which became <productname>FreeTDS/JDBC</productname>.
+ 			</para>
+ 			<para>
+ As the project matured, it gained new participants.  Frediano Ziglio greatly expanded the <systemitem class="library">ODBC</systemitem> driver, and continues to improve both it and the underlying TDS library.  Bill Thompson wrote most of the present BCP system and added cursors to our <systemitem class="library">ct-lib</systemitem>.  Your humble author joined the project to add documentation, and wound up as the project's maintainer.  Such are the rewards for doing a good deed.  
+@@ -194,11 +198,11 @@ There have been many other contributions.  Please see the <filename>AUTHORS</> i
+ 		  <sect2 id="Current">
+ 			<title>Current Projects</title>
+ 			<para>
+-<productname>FreeTDS</productname> consists of two projects.  The <productname>FreeTDS</productname> C libraries and <productname>FreeTDS</productname>/ <acronym>JDBC</>.
++&freetds; consists of two projects.  The &freetds; C libraries and &freetds;/ <acronym>JDBC</>.
+ 			</para>
+ 			<itemizedlist mark=opencircle>
+ 			<listitem><para>
+-The <productname>FreeTDS</productname> C libraries support three separate <acronym>API</>s: <systemitem class="library">db-lib</systemitem>, <systemitem class="library">ct-lib</systemitem>, and <systemitem class="library">ODBC</systemitem>.  Underlying these three is libtds, which handles the low-level details of the <acronym>TDS</> protocol, such as sending, receiving, and datatype conversion.  This document and the <ulink url="http://www.freetds.org/">FreeTDS</ulink> website are dedicated to these libraries.  
++The &freetds; C libraries support three separate <acronym>API</>s: <systemitem class="library">db-lib</systemitem>, <systemitem class="library">ct-lib</systemitem>, and <systemitem class="library">ODBC</systemitem>.  Underlying these three is libtds, which handles the low-level details of the <acronym>TDS</> protocol, such as sending, receiving, and datatype conversion.  This document and the <ulink url="http://www.freetds.org/">FreeTDS</ulink> website are dedicated to these libraries.  
+ 			</para></listitem>
+ 			<listitem><para>
+ If Java is your game, we refer you to the 
+@@ -214,7 +218,7 @@ project on SourceForge.  It is a fork of the
+ The <systemitem class="library">db-lib</systemitem> and <systemitem class="library">ct-lib</systemitem> <acronym>API</>s have been usable for several years.  They have been successfully  substituted for Sybase's own libraries in a variety of venues, including <productname>Perl</productname> and <productname>PHP</productname>.  That is not to say that these drivers are complete; they're not.  But they faithfully implement a useful &mdash; and widely used &mdash; subset of their <acronym>API</>s.  
+ 			</para>
+ 			<para>
+-In addition to the core <systemitem class="library">db-lib</systemitem> <acronym>API</>, <productname>FreeTDS</productname>  includes a full implementation of <systemitem class="library">db-lib</systemitem>'s <acronym>bcp</> functions, as well as <command>freebcp</>, a replacement for Sybase's <application>bcp</application> utility.  
++In addition to the core <systemitem class="library">db-lib</systemitem> <acronym>API</>, &freetds;  includes a full implementation of <systemitem class="library">db-lib</systemitem>'s <acronym>bcp</> functions, as well as <command>freebcp</>, a replacement for Sybase's <application>bcp</application> utility.  
+ 			</para>
+ 			<para>
+ The <systemitem class="library">ODBC</> driver should be fully ODBC 3.0 compliant.  Any problems found in the currently implemented <acronym>API</> subset are cheerfully  addressed.  
+@@ -222,15 +226,15 @@ The <systemitem class="library">ODBC</> driver should be fully ODBC 3.0 complian
+ 			<para>
+ Basic <link linkend="apireference">API coverage</link> information for all libraries may be found in this manual.  It is maintained in <filename>doc/api_status.txt</>, included in the source distribution.   			
+ 			</para> 
+-			<para>How big is it?  <productname>FreeTDS</productname> has over 90,000 lines of C code, maintained by a handful of developers.  Patches arrive irregularly, varying in size from one-liners to thousand-line monsters.  Almost all are applied or used in some way.  The mailing list has some 700 or so subscribers at this writing.  Safe to say, <productname>FreeTDS</productname>'s success so far lies somewhere between the Beetle and the Edsel.  
++			<para>How big is it?  &freetds; has over 90,000 lines of C code, maintained by a handful of developers.  Patches arrive irregularly, varying in size from one-liners to thousand-line monsters.  Almost all are applied or used in some way.  The mailing list has some 700 or so subscribers at this writing.  Safe to say, &freetds;'s success so far lies somewhere between the Beetle and the Edsel.  
+ 			</para>
+-			<para>Who uses it?  Oh, pretty much everyone.  <productname>FreeTDS</productname> users almost certainly number in the tens of thousands.  It's used by large corporations, by the U.S. federal government (e.g. <ulink url="http://www.ncbi.nlm.nih.gov/books/bv.fcgi?rid=toolkit.chapter.ch_dbapi">Database Access Library</ulink> at the National Center for Biotechnology Information) and, judging by the mailing list, by many webservers running Apache and PHP.  Microsoft recommends <productname>FreeTDS</productname> to their customers who want access to Microsoft SQL Server from non-Win32 clients. So do we.  
++			<para>Who uses it?  Oh, pretty much everyone.  &freetds; users almost certainly number in the tens of thousands.  It's used by large corporations, by the U.S. federal government (e.g. <ulink url="http://www.ncbi.nlm.nih.gov/books/bv.fcgi?rid=toolkit.chapter.ch_dbapi">Database Access Library</ulink> at the National Center for Biotechnology Information) and, judging by the mailing list, by many webservers running Apache and PHP.  Microsoft recommends &freetds; to their customers who want access to Microsoft SQL Server from non-Win32 clients. So do we.  
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="Languages">
+ 			<title>Languages besides C and Java</title>
+ 			<para>
+-You may be wondering how these libraries fit with Perl, PHP, TCL, Python, or other popular scripting languages.  Most of these languages have bindings to Sybase that use either the <systemitem class="library">db-lib</systemitem> or <systemitem class="library">ct-lib</systemitem> <acronym>API</>, for which <productname>FreeTDS</productname> is intended as a drop-in replacement.  For instance, Michael Peppler's <systemitem class="library">DBD::Sybase</systemitem> works very well using <productname>FreeTDS</productname> to access Sybase or Microsoft <productname>SQL Server</productname>s.  <productname>PHP</productname> has options for <filename>sybase</filename> (<systemitem class="library">db-lib</systemitem>) and <filename>sybase-ct</filename> (<systemitem class="library">ct-lib</systemitem>) <acronym>API</>s.
++You may be wondering how these libraries fit with Perl, PHP, TCL, Python, or other popular scripting languages.  Most of these languages have bindings to Sybase that use either the <systemitem class="library">db-lib</systemitem> or <systemitem class="library">ct-lib</systemitem> <acronym>API</>, for which &freetds; is intended as a drop-in replacement.  For instance, Michael Peppler's <systemitem class="library">DBD::Sybase</systemitem> works very well using &freetds; to access Sybase or Microsoft <productname>SQL Server</productname>s.  <productname>PHP</productname> has options for <filename>sybase</filename> (<systemitem class="library">db-lib</systemitem>) and <filename>sybase-ct</filename> (<systemitem class="library">ct-lib</systemitem>) <acronym>API</>s.
+ 			</para>
+ 			<para>
+ Not to be outdone, the folks at the <firstterm>O'Caml</> project have a binding for that language.  You can read more about it on <ulink url="http://kenn.frap.net/ocaml-freetds/">
+@@ -240,11 +244,11 @@ Kenn Knowles's</ulink> site; see also his <ulink url="http://www.merjis.com/deve
+ 		<sect2 id="alternatives">
+ 			<title>Alternatives</title>
+ 			<variablelist id="tab.alternatives">
+-				<title>Should <productname>FreeTDS</productname> not suit your needs, some alternatives</title>
++				<title>Should &freetds; not suit your needs, some alternatives</title>
+ 				<varlistentry>
+ 					<term>Sybase OpenClient</term>
+ 					<listitem>
+-					<para>In the time since <productname>FreeTDS</productname> was started, Sybase (as well as most major <acronym>DBMS</> vendors) has released its database for the Intel <productname><acronym>GNU</>/Linux</productname> platform.  The good: it is a solid product and supports <acronym>TDS</> 4.2 and <acronym>TDS</> 5.0.  The bad: it doesn't support <acronym>TDS 7.0</> or Linux/*BSD on non-Intel platforms.  The ugly: Microsoft broke date handling for big endian Sybase clients.</para>
++					<para>In the time since &freetds; was started, Sybase (as well as most major <acronym>DBMS</> vendors) has released its database for the Intel <productname><acronym>GNU</>/Linux</productname> platform.  The good: it is a solid product and supports <acronym>TDS</> 4.2 and <acronym>TDS</> 5.0.  The bad: it doesn't support <acronym>TDS 7.0</> or Linux/*BSD on non-Intel platforms.  The ugly: Microsoft broke date handling for big endian Sybase clients.</para>
+ 						<para>Depending on platform, it may cost something.</para>
+ 					</listitem>
+ 				</varlistentry>
+@@ -272,7 +276,7 @@ Kenn Knowles's</ulink> site; see also his <ulink url="http://www.merjis.com/deve
+ 				<!-- ////////////////// CHAPTER /////////////////////// -->
+ 	
+ 	<chapter id="build">
+-		<title>Build <productname>FreeTDS</productname></title>
++		<title>Build &freetds;</title>
+ <epigraph>
+ <para>
+ If you build it they will come.
+@@ -281,7 +285,7 @@ If you build it they will come.
+ 		<sect1 id="gnu">
+ 			<title>The <acronym>GNU</> World</title>
+ 			<para>
+-<productname>FreeTDS</productname> uses <acronym>GNU</> <application>Automake</application>, <application>Autoconf</application>, and <application>libtool</application> to increase portability.
++&freetds; uses <acronym>GNU</> <application>Automake</application>, <application>Autoconf</application>, and <application>libtool</application> to increase portability.
+ 			</para>
+ 			<para>
+ For many people, the preceding sentence says it all (good or bad).  If you're familiar with the <acronym>GNU</> system, you can probably just download the tarball and get away with scanning the <filename>README</filename> impatiently and then following your instincts.  Because everyone is a beginner once and no one is an expert at everything, we'll try to explain things in plain English where possible, and to define our terms as we go along.
+@@ -293,7 +297,7 @@ If the following nevertheless reads like gibberish, you might very well want to
+ 		<sect1 id="packages">
+     			<title>What to build: Packages, Tarballs, and the <productname>CVS</productname> repository</title>
+ 			<para>
+-The latest <productname>FreeTDS</productname> package is always available from 
++The latest &freetds; package is always available from 
+ 	<ulink url="ftp://ibiblio.unc.edu/pub/Linux/ALPHA/freetds/freetds-release.tgz">
+ 		<citetitle>iBiblio</citetitle></ulink> 
+ and its mirrors.
+@@ -315,19 +319,19 @@ For those behind firewalls or otherwise unable to access <productname>CVS</produ
+ 	<ulink url="ftp://ftp.ibiblio.org/pub/Linux/ALPHA/freetds/freetds-current.tgz">ibiblio.org</ulink>.  Tarballs are generated around 3am EST (GMT-5).
+ 			</para>
+ 			<para>
+-In general, the <productname>CVS</productname> version works better and has more functionality than the release version.  Bugs sometimes persist in the release version but are usually fixed in short order (once identified) in <productname>CVS</productname>.  
++In general, the <productname>CVS</productname> HEAD revision (the basis of the current nightly snapshot) works better and has more functionality than the release version.  Bugs sometimes persist in the release version but are usually fixed in short order (once identified) in <productname>CVS</productname> HEAD.  
+   			</para>
+ 			<tip><para>
+-As with any project of this sort, if you want to use the <productname>CVS</productname> version, it's a good idea to join the mailing list.  
++As with any project of this sort, if you want to use the <productname>CVS</productname> HEAD revision, it's a good idea to join the mailing list.  
+ 			</para></tip>
+ 		</sect1>
+ 		<sect1 id="config">
+     			<title>How to build: Configure and make</title>
+ 			<para>
+-If you've built other <acronym>GNU</> projects, building <productname>FreeTDS</productname> is a fairly straightforward process. We have a terse and verbose description.
++If you've built other <acronym>GNU</> projects, building &freetds; is a fairly straightforward process. We have a terse and verbose description.
+ 			</para>
+ 			<Note><para>
+-<productname>FreeTDS</productname>  is known to build with <acronym>GNU</> and <acronym>BSD</> <application>make</application>.  If you encounter a large number of build errors, and your operating system's <application>make</application> is not <acronym>GNU</> <application>make</application> (as is the case on most non-<acronym>GNU</>/Linux systems), you may wish to install <acronym>GNU</> <application>make</application> from <ulink url="ftp://ftp.gnu.org/gnu/make/">ftp.gnu.org</ulink>.
++&freetds;  is known to build with <acronym>GNU</> and <acronym>BSD</> <application>make</application>.  If you encounter a large number of build errors, and your operating system's <application>make</application> is not <acronym>GNU</> <application>make</application> (as is the case on most non-<acronym>GNU</>/Linux systems), you may wish to install <acronym>GNU</> <application>make</application> from <ulink url="ftp://ftp.gnu.org/gnu/make/">ftp.gnu.org</ulink>.
+ 			</para></note>
+ 			<sect2 id="Experts"><title>For Experts</title>
+ <screen>
+@@ -344,7 +348,7 @@ Building from CVS is described in the file INSTALL.CVS.
+ 
+ 			</sect2>
+ 			<sect2 id="Everyone"><title>For Everyone Else </title>
+-				<TITLEABBREV>(<productname>FreeTDS</productname> for Dummies?)</TITLEABBREV>
++				<TITLEABBREV>(&freetds; for Dummies?)</TITLEABBREV>
+ 				
+ 			<para>			
+ The <acronym>GNU</> development system can generate code for a wide variety of hardware architectures and operating systems, virtually all of which can run <productname>FreeTDS</> in consequence.  The work of building and installing the <productname>FreeTDS</> libraries begins with the command <Command>configure</Command>, which generates the <filename>Makefile</filename> that governs how the code is compiled, linked, and installed.  Once you've <quote>configured</quote> the project, <command>make</> will manage the rest of the build.
+@@ -429,12 +433,12 @@ There are a few optional arguments to <Command>configure</> that may be importan
+ 				</varlistentry>
+ 			<varlistentry>
+ 				<term><Option>--disable-libiconv</Option></term>
+-				<listitem><para>By default, <command>configure</> will search your system for an <systemitem class="library">iconv</systemitem> library for use with Microsoft servers (because TDS 7.0 employs Unicode).  This switch prevents that search.  If no <systemitem class="library">iconv</systemitem> library is used, <productname>FreeTDS</productname> relies on its built-in iconv emulation, which is capable of converting ISO-8859-1 to UCS-2, sufficient for many applications.  </para>
++				<listitem><para>By default, <command>configure</> will search your system for an <systemitem class="library">iconv</systemitem> library for use with Microsoft servers (because TDS 7.0 employs Unicode).  This switch prevents that search.  If no <systemitem class="library">iconv</systemitem> library is used, &freetds; relies on its built-in iconv emulation, which is capable of converting ISO-8859-1 to UCS-2, sufficient for many applications.  </para>
+ 					</listitem>
+ 				</varlistentry>
+ 			<varlistentry>
+ 				<term><Option>--disable-threadsafe</Option></term>
+-				<listitem><para>Force <productname>FreeTDS</productname> not to use threadsafe versions of functions such as <function>gethostbyname_r()</> where available.  Rely instead on the older and non-threadsafe ones such as <function>gethostbyname()</>. <command>configure</> tests some of these functions.  If the tests are successful, <productname>FreeTDS</productname> will use threadsafe functions throughout. </para>
++				<listitem><para>Force &freetds; not to use threadsafe versions of functions such as <function>gethostbyname_r()</> where available.  Rely instead on the older and non-threadsafe ones such as <function>gethostbyname()</>. <command>configure</> tests some of these functions.  If the tests are successful, &freetds; will use threadsafe functions throughout. </para>
+ 				<para>Threadsafe operation has been tested on Linux, FreeBSD, and HP-UX.  It should work on Solaris, Tru64, and (reportedly) IRIX.  Not expected to work on non-unixy systems.  It is a good idea to enable threadsafe operation if you configure Apache with multi-threading support.</para>
+ 				</listitem>
+ 				</varlistentry>
+@@ -481,7 +485,7 @@ There are a few optional arguments to <Command>configure</> that may be importan
+ 
+ 			<varlistentry>
+ 				<term><Option>--with-openssl=<replaceable>DIR</></Option></term>
+-				<listitem><para>Enable SSL using OpenSSL. Unlike <productname>FreeTDS</productname>, OpenSSL does not use the LGPL.  Please read the <ulink url="http://www.openssl.org/source/license.html">OpenSSL license</ulink> before distributing binaries compiled with this option.  </para>
++				<listitem><para>Enable SSL using OpenSSL. Unlike &freetds;, OpenSSL does not use the LGPL.  Please read the <ulink url="http://www.openssl.org/source/license.html">OpenSSL license</ulink> before distributing binaries compiled with this option.  </para>
+ 					</listitem>
+ 			</varlistentry>
+ 
+@@ -512,7 +516,7 @@ Now you're ready to build.  Follow these easy steps.
+ You normally need to be root to <command>make install</command>, unless you used the <option>--prefix</> option during configuration to install into your own directory.
+ 			</para>
+ 			<para>
+-With any luck, you've built and installed the <productname>FreeTDS</productname> libraries.  
++With any luck, you've built and installed the &freetds; libraries.  
+ 			</para>
+ 			</sect3>
+ 		</sect2>
+@@ -520,16 +524,16 @@ With any luck, you've built and installed the <productname>FreeTDS</productname>
+ 		<sect1 id="osissues">
+     			<title>OS-specific Issues</title>
+ 			<sidebar>
+-			<para>If you've recently built and installed <productname>FreeTDS</productname> and noticed steps peculiar to your OS, we'll happily include your comments here. </para>
++			<para>If you've recently built and installed &freetds; and noticed steps peculiar to your OS, we'll happily include your comments here. </para>
+ 			
+-			<para>One thing that can be said, if it's not too obvious:  check with your vendor or favorite download site.  <productname>FreeTDS</productname> is routinely rolled up into OS install packages.  We know of packages for <productname>Debian</productname>, <productname>Red Hat</productname>, <productname>FreeBSD</productname>, and <productname>NetBSD</productname>.  The installation through the package management systems in these environments may well reduce your work to simply <command>make install</command>.  </para>
++			<para>One thing that can be said, if it's not too obvious:  check with your vendor or favorite download site.  &freetds; is routinely rolled up into OS install packages.  We know of packages for <productname>Debian</productname>, <productname>Red Hat</productname>, <productname>FreeBSD</productname>, and <productname>NetBSD</productname>.  The installation through the package management systems in these environments may well reduce your work to simply <command>make install</command>.  </para>
+ 			</sidebar>
+ 		<sect2 id="Windows"><title></title>
+-			<para>The <productname>FreeTDS</productname> ODBC driver compiles under
++			<para>The &freetds; ODBC driver compiles under
+ 			
+ 			<itemizedlist>
+ 
+-				<listitem><para>VC++; <filename>.dsw</> and <filename>.dsp</> files are included in the <filename>win32</> directory.  </para></listitem>
++				<listitem><para>VC++.  Project files are included in the <filename>win32</> directory.   See also <filename>Makefile.win32</>. </para></listitem>
+ 
+ 				<listitem><para>Dev-C++</para></listitem>
+ 				<listitem><para>MingW</para></listitem>
+@@ -541,10 +545,10 @@ With any luck, you've built and installed the <productname>FreeTDS</productname>
+ 			</itemizedlist>	
+ 
+ Threadsafe operation will not be enabled.  </para>
+-			<para>From the Department of Double Emulation: <productname>FreeTDS</productname> builds as a <filename>.dll</> under <productname>WINE</> and as a <filename>.a</> under <productname>Interix</>.  See the mailing list archives (second half of 2003) for details.  </para>
++			<para>From the Department of Double Emulation: &freetds; builds as a <filename>.dll</> under <productname>WINE</> and as a <filename>.a</> under <productname>Interix</>.  See the mailing list archives (second half of 2003) for details.  </para>
+ 		</sect2>
+ 		<sect2 id="VMS"><title>VMS&reg;</title>
+-			<para><productname>FreeTDS</productname> will probably build and run on most versions of OpenVMS Alpha 7.0 and later with DEC/Compaq C 6.0 or later.  Other prerequisites:
++			<para>&freetds; will probably build and run on most versions of OpenVMS Alpha 7.0 and later with DEC/Compaq C 6.0 or later.  Other prerequisites:
+ 
+ 			<simplelist>
+ 				<member><application>gunzip</></member>
+@@ -577,7 +581,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2009/08/25 14:25:35 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2009/12/14 01:02:27 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -587,7 +591,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 	<title>Installing with libtool 1.5.2</title>
+ 	<step><para>Install the latest <command>libtool</> from GNU into <filename>/usr/local</>, so as not to interfere with the Apple-original.  </para></step>
+ 	<step><para>Make sure <filename>/usr/local/bin</> is in your <envar>PATH</envar> and <filename>/usr/local/lib</> is in your <envar>LIBRARY_PATH</envar>.  </para></step>
+-	<step><para>Go to the <productname>FreeTDS</productname> source directory and generate the <filename>Makefile</>s
++	<step><para>Go to the &freetds; source directory and generate the <filename>Makefile</>s
+ 		<screen>
+ 		<prompt>$ </prompt><userinput>./configure --disable-libiconv --disable-odbc</userinput>
+ 		</screen>
+@@ -646,7 +650,7 @@ know it is easily done:
+ <!-- ////////////////// CHAPTER /////////////////////// -->
+ 	
+ 	<chapter id="install">
+-		<title>Install <productname>FreeTDS</productname></title>
++		<title>Install &freetds;</title>
+ <epigraph>
+ <para>
+ If you install it they will stay?
+@@ -660,16 +664,16 @@ If you install it they will stay?
+ don't have absolute, context-free definitions.  In some circles, we install a product and then configure it.  In the <acronym>GNU</> world, we <command>configure</command> the package (generate the <filename>Makefile</>s), then we <command>make install</command> the package.  To  <emphasis>install the package</emphasis> is to copy the binaries to their appropriate run-time directories, copy the documentation to the <filename>doc</filename> directory, and maybe let the package manager know what's happened.  That's generally considered part of the <phrase>build process</phrase>, covered in the last chapter.  
+ 			</para>
+ 			<para>
+-For lack of a better term, this chapter describes installing the <emphasis>product</emphasis>.  Put more specifically, once we're done with the package manager, we still have to tell <productname>FreeTDS</productname> about your database servers, and we still have to tell your client programs about <productname>FreeTDS</productname>.  
++For lack of a better term, this chapter describes installing the <emphasis>product</emphasis>.  Put more specifically, once we're done with the package manager, we still have to tell &freetds; about your database servers, and we still have to tell your client programs about &freetds;.  
+ 			</para>
+ </Note>
+ 		<sect1 id="LocalEnvironment">
+ 		<title>The local environment</title>
+ 			<para>
+-After <productname>FreeTDS</productname> has been built and installed, it still doesn't know where your servers are or what particular version of Sybase or Microsoft software each one is using.  
++After &freetds; has been built and installed, it still doesn't know where your servers are or what particular version of Sybase or Microsoft software each one is using.  
+ 			</para>
+ 			<para>
+-The purpose of this section is to explain how to describe your dataservers to <productname>FreeTDS</productname>.  <productname>FreeTDS</productname> looks up your server's attributes in <filename>freetds.conf</filename>.  Some of the attributes can be overridden by environment variables.  
++The purpose of this section is to explain how to describe your servernames to &freetds;.  &freetds; looks up your server's attributes in &freetdsconf;.  Some of the attributes can be overridden by environment variables.  
+ 			</para>
+ 			<para>
+ One of the more important (and arcane) settings is the <acronym>TDS</> protocol version, described next.  
+@@ -744,26 +748,57 @@ and 7.0.  Version 7.0 is recommended for compatibility with SQL Server tools.
+ 			
+ 			
+ 		</sect1>
++		<sect1 id="name.lookup"> <title><replaceable>servername</> Lookup</title>
++		<!--
++			<para>When an application names a server to connect to, &freetds;:
++			<simplelist type="vert" columns="1">
++				<member>resolves the name to an IP address</member>
++				<member>chooses a port</member>
++				<member>connects to the port</member>
++				<member>chooses a version of the TDS protocol</member>
++				<member>sends a login packet</member>
++				<member>listens for an answer from the server</member>
++			</simplelist>
++		-->	
++			<para>&freetds; tries the following steps, in order, to convert the servername to an IP address, stopping when it succeeds. 
++			<orderedlist><title>Name lookup sequence
++				<footnote><para>This description applies to db-lib and ct-lib.  ODBC lookup is different.  </para></footnote>
++				</title>
++				<listitem><para>Find <replaceable>servername</> in &freetdsconf;.  If a section with that name exists, use the hostname, port, and TDS version specified therein.  </para></listitem>
++				<listitem><para>Attempt to convert <replaceable>servername</> to an IP address with <function>inet_addr(3)</>.  If successful, use the compiled-in default port and TDS version.  </para></listitem>
++				<listitem><para>Request name-lookup from the operating system via <function>gethostbyname(3)</> or similar.  If successful, use the compiled-in default port and TDS version.  </para></listitem>
++			</orderedlist>
++
++			As you can see, if most of your servers use the same TDS version and answer to the default port, then you don't need to list them all in &freetdsconf;.  You can simply compile in the right defaults &mdash; or set the <envar>TDSPORT</envar> and <envar>TDSVER</envar> environment variables &mdash; and rely on DNS for name resolution.  
++			
++			
++			</para>
++		</sect1>
++
+ 		<sect1 id="freetdsconf">
+-    			<title>The <filename>freetds.conf</filename> file</title>
++    			<title>The &freetdsconf; file</title>
+ 		<sect2 id="freetdsconfpurpose">
+ 			<title>What it does</title>
+ 			<para>
+-<productname>FreeTDS</productname> uses a configuration file 
+-<filename>freetds.conf</filename>  (the name can be controlled by an environment variable).  Its format is similar to Samba's modified <quote><filename>win.ini</filename></quote> format.  Its foremost job is to relate  <emphasis>dataserver</emphasis> names, as known to your programs
+-	<footnote>
+-	<para>In general, the dataserver name is arbitrary and local; it's used only by your client programs to tell <productname>FreeTDS</productname> which server to connect to.  You can choose any name you like.  </para>
+-	<para><productname>Sybase SQL Anywhere</productname> (a/k/a Sybase ASA), however, is fussy.  You must use the database's name as your dataserver name.  Otherwise, the server will refuse your connection.  </para>
+-	</footnote>
+-, to  <emphasis>machine</emphasis> names, as known your
+-network.  That is, while your machines have names known to the
+-network, the dataservers on your machines have names known only to
+-your  <productname>FreeTDS</productname> client programs.  The
+-configuration file can then further describe that dataserver in
+-greater detail, as need be.  
++Just as DNS defines hostnames for  network addresses, &freetdsconf; uses a <firstterm>servername</> to define the properties of your server.  <footnote>
++	<para>In general, the servername is arbitrary and local; it's used only by your client programs to tell &freetds; which server to connect to.  You can choose any name you like.  </para>
++	<para><productname>Sybase SQL Anywhere</productname> (a/k/a Sybase ASA), however, is fussy.  You must use the database's name as your servername.  Otherwise, the server will refuse your connection.  </para>
++	</footnote> 
++In particular, &freetds; needs to know:
++			<ItemizedList><title>Primary Server Properties</title>
++				<listitem><para>Hostname or IP address of the server
++					</para></listitem>
++				<listitem><para>Port number or Instance name (not both)
++					</para></listitem>
++				<listitem><para><acronym>TDS</> protocol version
++					</para></listitem>
++			</ItemizedList>
++
++			</para>
++			<para>
+ 			</para>
+ 			<para>
+-<note><para>	<productname>FreeTDS</productname> also supports an older configuration file format, known as the <filename>interfaces</filename> file.  Use <filename>freetds.conf</filename> unless <filename>interfaces</filename> is needed for your situation.  It is easier to read, and it is where all the new options are being added.  <productname>FreeTDS</productname> looks for <filename>freetds.conf</filename> first, falling back on <filename>interfaces</filename> only if <filename>freetds.conf</filename> is not found.  
++<note><para>	&freetds; also supports an older configuration file format, known as the <filename>interfaces</filename> file.  Use &freetdsconf; unless <filename>interfaces</filename> is needed for your situation.  It is easier to read, and it is where all the new options are being added.  &freetds; looks for &freetdsconf; first, falling back on <filename>interfaces</filename> only if &freetdsconf; is not found.  
+ 			</para>
+ 			<para>
+ Should you need it, more information about <filename>interfaces</filename> can be found in the <link linkend="interfacesfile">Appendix</link>.	</para></note>
+@@ -773,26 +808,27 @@ Should you need it, more information about <filename>interfaces</filename> can b
+ 		<sect2 id="freetdsconflocation">
+ 			<title>Where it goes</title>
+ 			<para>
+-The default location of <filename>freetds.conf</filename> is determined by the  <literal>--sysconfdir</literal> option of <command>configure</>.  If you don't specify anything, <command>configure</>'s default <literal>sysconfdir</literal> is <filename>/usr/local/etc</filename>.
++The default location of &freetdsconf; is determined by the  <literal>--sysconfdir</literal> option of <command>configure</>.  If you don't specify anything, <command>configure</>'s default <literal>sysconfdir</literal> is <filename>/usr/local/etc</filename>.  <command>tsql -C</command> reports the <literal>sysconfdir</literal> to let you confirm it.  
+ 			</para>
+ 			<para>
+-In addition, <productname>FreeTDS</productname> will look for a file <filename>.freetds.conf</filename> in the user's home directory (<filename>~/.freetds.conf</filename>).  
++In addition, &freetds; will look for a file <filename>.freetds.conf</filename> in the user's home directory (<envar>${HOME}</><filename>/.freetds.conf</filename>).  
+ 			</para>
+ 			<para>
+-The actual name and location of <filename>freetds.conf</filename> may be specified by the environment variable <envar>FREETDS</envar> (or <envar>FREETDSCONF</envar>, same effect).  See <link linkend="envvar">Environment Variables</link>, below.  
++The actual name and location of &freetdsconf; may be specified by the environment variable <envar>FREETDS</envar> (or <envar>FREETDSCONF</envar>, same effect).  See <link linkend="envvar">Environment Variables</link>, below.  
+ 			</para>
+ 			<para>
+-<productname>FreeTDS</productname> reads the user's <replaceable>${HOME}/</replaceable><filename>.freetds.conf</filename> before resorting to the system-wide <replaceable>sysconfdir/</replaceable><filename>freetds.conf</filename>.  The first properly configured (i.e., a readable file with a section for the server) <filename>freetds.conf</filename> file will be the one used.
++&freetds; reads the user's <replaceable>${HOME}/</replaceable><filename>.freetds.conf</filename> before resorting to the system-wide <replaceable>sysconfdir/</replaceable>&freetdsconf;.  The file used is the first one that is readable and contains a section for the server.
+            		</para>
+ 		</sect2>
+ 		<sect2 id="freetdsconfformat">
+ 			<title>What it looks like</title>
++			<para><tip><para> The following information is also provided in the &freetdsconf; manual page, cf. <command>man freetds.conf</>. </para></tip></para>
+ 			<para>
+-The <filename>freetds.conf</filename> file is composed of two types of sections: one
+-<literal>[global]</literal> section,  and a <literal>[<replaceable>dataserver</replaceable>]</literal> section for each dataserver.  Settings in the <literal>[global]</literal> section affect all dataservers, but can be overridden in a <literal>[<replaceable>dataserver</replaceable>]</literal> section.  For example
++The &freetdsconf; file format is similar to that of Samba's modified <quote><filename>win.ini</filename></quote>.  It 
++is composed of two types of sections: one <literal>[global]</literal> section,  and a <literal>[<replaceable>servername</replaceable>]</literal> section for each servername.  Settings in the <literal>[global]</literal> section affect all servernames, but can be overridden in a <literal>[<replaceable>servername</replaceable>]</literal> section.  For example
+ 			</para>
+ <example id="e.g.freetdsconf">
+-<title>A <filename>freetds.conf</filename> file example</title>
++<title>A &freetdsconf; file example</title>
+ <programlisting>
+ [global]
+ 	tds version = 4.2
+@@ -813,17 +849,17 @@ The <filename>freetds.conf</filename> file is composed of two types of sections:
+ </programlisting>
+ </example>
+ 	<para>
+-In this example, the default  <acronym>TDS</> version for all dataservers is set to <literal>4.2</>.  It is then overridden for <literal>myserver2</literal> (a Sybase server) which uses <literal>5.0</literal>, and <literal>myserver3</literal> (a MSSQL 2000 server) which uses <literal>7.1</literal>.
++In this example, the default  <acronym>TDS</> version for all servernames is set to <literal>4.2</>.  It is then overridden for <literal>myserver2</literal> (a Sybase server) which uses <literal>5.0</literal>, and <literal>myserver3</literal> (a MSSQL 2000 server) which uses <literal>7.1</literal>.
+ 	</para>
+ 	<para>
+ Usually, it is sufficient to state just the server's hostname and TDS protocol version.  Everything else can be inferred, unless your setup (or your server's) strays from the defaults.  
+ 	<tip><para>Some people seem to feel safer using the IP address for the server, rather than its name.  We don't recommend you do that.  Use the name, and benefit from the inherent advantages.  That's why DNS was invented in the first place, you know.  </para></tip>
+ 	</para>
+ 	<para>
+-It bears mentioning here that prior versions of <productname>FreeTDS</productname> were quite fussy about domain logins, forcing users to make explicit per-server entries in <filename>freetds.conf</>.  That is no longer the case.  If the username has the form <parameter>DOMAIN\username</>, <productname>FreeTDS</productname> will automatically use a domain login.  
++It bears mentioning here that prior versions of &freetds; were quite fussy about domain logins, forcing users to make explicit per-server entries in &freetdsconf;.  That is no longer the case.  If the username has the form <parameter>DOMAIN\username</>, &freetds; will automatically use a domain login.  
+ 	</para>
+ <table id="tab.freetds.conf">
+-<title><filename>freetds.conf</filename> settings</title>
++<title>&freetdsconf; settings</title>
+ <tgroup cols="4">
+ <thead>
+ 	<row>
+@@ -846,7 +882,7 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	<entry>host</entry>
+ 	<entry>host name or IP address</entry>
+ 	<entry>none</entry>
+-	<entry>The host that the dataserver is running on.</entry>
++	<entry>The host that the servername is running on.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>port</entry>
+@@ -886,9 +922,9 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 		</row>
+ 		</tbody>
+ 	</entrytbl>
+-	<entry>	The port number that the dataserver is listening to.  
++	<entry>	The port number that the servername is listening to.  
+ 		<emphasis>Please note:</emphasis>
+-			The "defaults" to the left are the server's default settings.   <productname>FreeTDS</productname> chooses its default port based on the TDS protocol version: <literal>5000</> for <acronym>TDS</> <literal>5.0</>, and <literal>1433</> for everything else.  
++			The "defaults" to the left are the server's default settings.   &freetds; chooses its default port based on the TDS protocol version: <literal>5000</> for <acronym>TDS</> <literal>5.0</>, and <literal>1433</> for everything else.  
+ 		Overridden by <link  linkend="TDSPORT">TDSPORT</link>.
+ 	</entry>
+ 	</row>
+@@ -896,7 +932,7 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	<row>
+ 	<entry>ASA database</entry>
+ 	<entry>valid database name</entry>
+-	<entry>dataserver [<replaceable>section</>] name</entry>
++	<entry>servername [<replaceable>section</>] name</entry>
+ 	<entry>Specifies the name of the default database when connecting to an ASA server.  A TDS 5.0 login packet has a field called <literal>lservname</>.   For most TDS servers, <literal>lservname</> is a user-defined string with no inherent meaning.  ASA servers, however, requires that <literal>lservname</>  contain a valid database name, and sets that as the default database for the connection.  FreeTDS normally fills <literal>lservname</>  with the [<replaceable>section</>]text..   This entry instead sets the database name independently of the [<replaceable>section</>] name.   </entry>
+ 	</row>
+ 
+@@ -943,7 +979,7 @@ It bears mentioning here that prior versions of <productname>FreeTDS</productnam
+ 	<entry id="clientcharset">client charset</entry>
+ 	<entry>any valid iconv character set</entry>
+ 	<entry>ISO-8859-1<footnote><para>Valid for ISO 8859-1 character set.  See <link linkend="Localization">Localization and <acronym>TDS</> 7.0</link> for more information.  </para></footnote></entry>
+-	<entry>Makes <productname>FreeTDS</productname> use iconv to convert to and from the specified character set from UCS-2 in <acronym>TDS</> 7.0 or above.
++	<entry>Makes &freetds; use iconv to convert to and from the specified character set from UCS-2 in <acronym>TDS</> 7.0 or above.
+ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need to match the server's charset to insert any characters the server supports.</entry>
+ 	</row>
+ 	<row>
+@@ -974,9 +1010,9 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ </tgroup>
+ </table>
+ 			<sect3> <title>Overrides</>
+-			<para>Many settings in <filename>freetds.conf</> can be overridden by <link linkend="envvar">environment variables</link>.
++			<para>Many settings in &freetdsconf; can be overridden by <link linkend="envvar">environment variables</link>.
+ 			</para>
+-			<para>Also dataserver can be decorated adding informations for port or instance name using <link linkend="PortOverride">port override syntax</link>.
++			<para>The servername can also be decorated adding the port or instance name using <link linkend="PortOverride">port override syntax</link>.
+ 			</para>
+ 			</sect3>
+ 			<sect3> <title>Controlling log details</>
+@@ -985,7 +1021,7 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ <para>The log's granularity can be controlled with the <literal>debug flags</> entry. The default value (<literal>4FFF</> hex) gives a level of detail that is useful for resolving problems via the mailing list.  </para>
+ 
+ <table id="tab.freetds.conf.debugflags">
+-<title>Valid bitmask values for <literal>debug flags</> entry in <filename>freetds.conf</filename></title>
++<title>Valid bitmask values for <literal>debug flags</> entry in &freetdsconf;</title>
+ 	<tgroup cols="2">
+ 	<thead>
+ 	  <row>
+@@ -1043,14 +1079,14 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ 	</tgroup>
+ </table>
+ 
+-	<para>For more about the wonderful world of <productname>FreeTDS</productname> logs, see <link linkend="logging">Logging</link>.</para>
++	<para>For more about the wonderful world of &freetds; logs, see <link linkend="logging">Logging</link>.</para>
+ 			</sect3>
+ 
+ 			<sect3><title>Deprecated options</>	
+ 	<para>As of version 0.62 the following options are deprecated and supported only for backward compatibility.</para>
+ 
+ <itemizedlist id="lst.freetds.conf.deprecated" spacing="compact">
+-	<title>Deprecated <filename>freetds.conf</filename> settings</title>
++	<title>Deprecated &freetdsconf; settings</title>
+ 	<listitem><para><symbol>try server login</> </para></listitem>
+ 	<listitem><para><symbol>try domain login </> </para></listitem>
+ 	<listitem><para><symbol>nt domain </> </para></listitem>
+@@ -1067,26 +1103,26 @@ As of 0.62 FreeTDS uses iconv to convert all character data, so there's no need
+ 		<sect2 id="localespurpose">
+ 			<title>What it does</title>
+ 			<para>
+-For an English-speaking American, not much.  <productname>FreeTDS</productname>  originated in the United States, and uses U.S. conventions if no <filename>locales.conf</filename> is present.  The <filename>locales.conf</filename> provided with the installation also reflects these conventions.  
++For an English-speaking American, not much.  &freetds;  originated in the United States, and uses U.S. conventions if no <filename>locales.conf</filename> is present.  The <filename>locales.conf</filename> provided with the installation also reflects these conventions.  
+ 			</para>
+ <important>
+-	<para><filename>locales.conf</> will probably be dropped from <productname>FreeTDS</> one day.  Its only real purpose now is to control the format of date strings.  The Right Way&trade; to deduce the appropriate default date format is from the application's locale settings, while allowing an override in <filename>freetds.conf</>.  That's the direction we're headed.  </para>
+-	<para>If your purpose is to affect the client charset description, use <filename>freetds.conf</> instead.  </para>
++	<para><filename>locales.conf</> will probably be dropped from <productname>FreeTDS</> one day.  Its only real purpose now is to control the format of date strings.  The Right Way&trade; to deduce the appropriate default date format is from the application's locale settings, while allowing an override in &freetdsconf;.  That's the direction we're headed.  </para>
++	<para>If your purpose is to affect the client charset description, use &freetdsconf; instead.  </para>
+ </important>
+ 			<para>
+-Information on locales and locale strings is easily (even too easily!) found on the Internet, or see <command>man locale</> for your system.  <productname>FreeTDS</productname> will examine its environment for a <literal>LOCALE</> string.  If it finds one, it will look it up in <filename>locales.conf</> to find your preferred settings.  If it fails to find one, it will use its defaults.  
++Information on locales and locale strings is easily (even too easily!) found on the Internet, or see <command>man locale</> for your system.  &freetds; will examine its environment for a <literal>LOCALE</> string.  If it finds one, it will look it up in <filename>locales.conf</> to find your preferred settings.  If it fails to find one, it will use its defaults.  
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="localeslocation">
+ 			<title>Where it goes</title>
+ 			<para>
+-			Like <filename>freetds.conf</filename>, the location of <filename>locales.conf</> is determined by the value of <option>--sysconfdir</> to <command>configure</>.  The default is <literal>PREFIX/etc</>.
++			Like &freetdsconf;, the location of <filename>locales.conf</> is determined by the value of <option>--sysconfdir</> to <command>configure</>.  The default is <literal>PREFIX/etc</>.
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="localesformat">
+ 			<title>What it looks like</title>
+ 			<para>
+-The format of <filename>locales.conf</> is similar to that of <filename>freetds.conf</filename>.  There is a <literal>[default]</> section, and a section for each locale.  
++The format of <filename>locales.conf</> is similar to that of &freetdsconf;.  There is a <literal>[default]</> section, and a section for each locale.  
+ 			
+ <filename>locales.conf</> controls three settings
+ <variablelist id="tab.locales.conf">
+@@ -1094,13 +1130,13 @@ The format of <filename>locales.conf</> is similar to that of <filename>freetds.
+ 		<term><literal>date format</></term>
+ 		<listitem>
+ 			<para>This entry will be passed (almost) literally to <function>strftime(3)</> to convert dates to strings.  </para>
+-			<para>For the most part, see you system documentation for <function>strftime(3)</> (<command>man 3 strftime</command>).  You will see there though that <function>strftime(3)</> has no provision for milliseconds.  The <filename>locales.conf</> format string uses <literal>%z</> for milliseconds.  <note><para>If your system's <function>strftime(3)</> does employ <literal>%z</> for its own use, it will not be given that chance by <productname>FreeTDS</productname>.  <productname>FreeTDS</productname> will consume the <literal>%z</> for its milliseconds needs, and will not pass it on to <function>strftime(3)</>. </para></note></para>
++			<para>For the most part, see you system documentation for <function>strftime(3)</> (<command>man 3 strftime</command>).  You will see there though that <function>strftime(3)</> has no provision for milliseconds.  The <filename>locales.conf</> format string uses <literal>%z</> for milliseconds.  <note><para>If your system's <function>strftime(3)</> does employ <literal>%z</> for its own use, it will not be given that chance by &freetds;.  &freetds; will consume the <literal>%z</> for its milliseconds needs, and will not pass it on to <function>strftime(3)</>. </para></note></para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>	
+ 		<term><literal>language</></term>
+ 		<listitem>
+-			<para>The language that will be used for error/status messages from the server.  A <productname>SQL Server</productname> client can specify a language for such messages at login time. <note><para><productname>FreeTDS</productname> issues a few messages of its own.  Messages from the server are called <quote>messages</>; those from the client library (i.e., from <productname>FreeTDS</productname>) are called <quote>error messages</>.  <productname>FreeTDS</productname>-issued messages are not affected by <filename>locales.conf</filename>.  </para></note>
++			<para>The language that will be used for error/status messages from the server.  A <productname>SQL Server</productname> client can specify a language for such messages at login time. <note><para>&freetds; issues a few messages of its own.  Messages from the server are called <quote>messages</>; those from the client library (i.e., from &freetds;) are called <quote>error messages</>.  &freetds;-issued messages are not affected by <filename>locales.conf</filename>.  </para></note>
+ 	 </para>
+ 		</listitem>
+ 	</varlistentry>	
+@@ -1119,14 +1155,14 @@ The format of <filename>locales.conf</> is similar to that of <filename>freetds.
+ 
+ 
+ 		<sect1 id="envvar">
+-   			<title>Setting the environment variables</title>
++   			<title>Environment variables</title>
+ 			<sect2 id="Whatfor">
+ 			<title>What they're for</title>
+ 			<para>
+ You can use environment variables to 
+ <itemizedlist>
+-	<listitem><para>Advertise the location of the <productname>FreeTDS</productname> libraries to programs that want them.</para></listitem>
+-	<listitem><para>Override some of the settings in <productname>FreeTDS</productname>'s configuration file.  </para></listitem>
++	<listitem><para>Override some of the settings in &freetds;'s configuration file.  </para></listitem>
++	<listitem><para>Advertise the location of the &freetds; libraries to programs that want them.</para></listitem>
+ 	<listitem><para>Control how logging is done.  </para></listitem>
+ </itemizedlist>
+ 
+@@ -1141,17 +1177,17 @@ In a typical system, no environment variables need be used.  They're sometimes h
+ 	<varlistentry>
+ 		<term id="FREETDS"><envar>FREETDS</envar></term>
+ 		<listitem>
+-			<para>may be used to specify the name and location of the <filename>freetds.conf</filename> file.  In prior versions of <productname>FreeTDS</productname>, this variable was known as <envar>FREETDSCONF</envar>. </para>
++			<para>may be used to specify the name and location of the &freetdsconf; file.  In prior versions of &freetds;, this variable was known as <envar>FREETDSCONF</envar>. </para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>
+ 		<term id="TDSVER"><envar>TDSVER</envar></term>
+ 		<listitem>
+-			<para>governs the version of the <acronym>TDS</> protocol used to connect to your server.  For a given server, <productname>FreeTDS</productname> inspects four sources in the following order to determine which <acronym>TDS</> protocol version to use, using the first one it finds.  </para>
++			<para>governs the version of the <acronym>TDS</> protocol used to connect to your server.  For a given server, &freetds; inspects four sources in the following order to determine which <acronym>TDS</> protocol version to use, using the first one it finds.  </para>
+ 			<orderedlist>
+ 				<listitem><para>The value specified in <envar>TDSVER</envar> 
+ 					</para></listitem>
+-				<listitem><para>A <filename>freetds.conf</filename> file entry (see below)
++				<listitem><para>A &freetdsconf; file entry (see below)
+ 					</para></listitem>
+ 				<listitem><para>The <filename>interfaces</filename> file entry (see below)
+ 					</para></listitem>
+@@ -1163,15 +1199,15 @@ In a typical system, no environment variables need be used.  They're sometimes h
+ 	<varlistentry>
+ 		<term id="TDSPORT"><envar>TDSPORT</envar></term>
+ 		<listitem>
+-			<para>specifies a TCP port number at which the dataserver is listening.  It overrides the default port (1433 for TDS 4.2/7.0/7.1/7.2, 4000 for TDS 5.0) as well as any port specified in the <filename>freetds.conf</filename> file.</para>
++			<para>specifies a TCP port number at which the servername is listening.  It overrides the default port (1433 for TDS 4.2/7.0/7.1/7.2, 4000 for TDS 5.0) as well as any port specified in the &freetdsconf; file.</para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>
+ 		<term id="SYBASE"><envar>SYBASE</envar></term>
+ 		<listitem>
+-			<para>points to the <productname>FreeTDS</productname> run-time directory.  Use of this variable originated with Sybase (the company), and many programs still rely on <envar>SYBASE</envar> to discover the location of the <quote>SYBASE</quote> libraries.  </para>
++			<para>points to the &freetds; run-time directory.  Use of this variable originated with Sybase (the company), and many programs still rely on <envar>SYBASE</envar> to discover the location of the <quote>SYBASE</quote> libraries.  </para>
+ 			
+-			<para>The primary use of <envar>SYBASE</envar> is to advertise the location of the <productname>FreeTDS</productname> libraries.  A secondary use is to point to the location of the <filename>interfaces</filename> file (if used, see the <link  linkend="interfacesfile">Appendix</link>), which some programs examine directly.  </para>
++			<para>The primary use of <envar>SYBASE</envar> is to advertise the location of the &freetds; libraries.  A secondary use is to point to the location of the <filename>interfaces</filename> file (if used, see the <link  linkend="interfacesfile">Appendix</link>), which some programs examine directly.  </para>
+ 
+ 		</listitem>
+ 	</varlistentry>	
+@@ -1186,7 +1222,7 @@ In a typical system, no environment variables need be used.  They're sometimes h
+ 	<varlistentry>
+ 		<term id="TDSHOST"><envar>TDSHOST</envar></term>
+ 		<listitem>
+-			<para>overrides the host specified in the <filename>freetds.conf</>.</para>
++			<para>overrides the host specified in the &freetdsconf;.</para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<!--	
+@@ -1242,67 +1278,195 @@ When you're done, you should see something very like this:
+ 		<sect1 id="PortOverride">
+ 			<title>Port override syntax</title>
+ 
+-			<para>The port to which to connect can be overridden using a <productname>FreeTDS</productname> extended syntax.
++			<para>The port to which to connect can be overridden using a &freetds; extended syntax.
+ 			</para>
+ 
+-			<para>A port may be appended to the dataserver name:   <literal><replaceable>dataserver</replaceable>:<replaceable>port</replaceable></literal>.  <productname>FreeTDS</productname> will attempt to connect to specified port. Please note <replaceable>port</replaceable> must be a number; a service name is not supported.
++			<para>A port may be appended to the servername in the form  <literal><replaceable>servername</replaceable>:<replaceable>port</replaceable></literal>.  &freetds; will attempt to connect to specified port. Please note <replaceable>port</replaceable> must be a number; a service name is not supported.
+ 			</para>
+ 
+-			<para>If you specify <literal><replaceable>dataserver</replaceable>\<replaceable>instance</replaceable></literal>
+-			as dataserver during login, <productname>FreeTDS</productname> will attempt to connect to specified instance.
++			<para>If you specify <literal><replaceable>servername</replaceable>\<replaceable>instance</replaceable></literal>
++			as servername during login, &freetds; will attempt to connect to specified instance.
+ 			Only Microsoft SQL Server instances are supported.  (This server feature was introduced with SQL Server 2000.)
+ 			</para>
+ 
+-			<para>Note that other <filename>freetds.conf</> properties still apply.
++			<para>Note that other &freetdsconf; properties still apply.
+ 			</para>
+-			<para> For the technically curious: each SQL Server <firstterm>instance</> appears on the network as a server listening at a port.  The old way &mdash; and it still works &mdash; is to designate each instance in <filename>freetds.conf</> as a separate server.  The new <quote>named instance</> notation, if we can call it that, instead uses the server to discover the port.  The library sends a UDP packet containing the instance name to the server at a <emphasis>well known port</>, port 1434.  The server responds with a port number.  <productname>FreeTDS</productname> then uses that number to connect in the usual way.  
++			<para> For the technically curious: each SQL Server <firstterm>instance</> appears on the network as a server listening at a port.  The old way &mdash; and it still works &mdash; is to designate each instance in &freetdsconf; as a separate server.  The new <quote>named instance</> notation, if we can call it that, instead uses the server to discover the port.  The library sends a UDP packet containing the instance name to the server at a <emphasis>well known port</>, port 1434.  The server responds with a port number.  &freetds; then uses that number to connect in the usual way.  
+ 			</para>
+ 		</sect1>
+ 		
+ 		<sect1 id="ConfirmInstall"><title>Confirm the installation</title>
+ 			
++			<para>We want to make sure that when your application requests a connection to your server, it actually works.  In detail, we want to know:
++				<itemizedlist>
++					<listitem><para>&freetds; can find and read &freetdsconf; </para></listitem>
++					<listitem><para><replaceable>servername</> exists in &freetdsconf; </para></listitem>
++					<listitem><para>a <replaceable>host</> property exists for <replaceable>servername</></para></listitem>
++					<listitem><para><replaceable>host</> can be resolved to a network address</para></listitem>
++					<listitem><para>the server is listening to the <replaceable>port</> or named <replaceable>instance</>   </para></listitem>
++					<listitem><para>the user can log in to the server </para></listitem>
++					<!-- listitem><para> </para></listitem -->
++				</itemizedlist>
++			
++			
++			Each of the above can be confirmed independently with tsql.  Once you're sure you can connect and log in, you can run the unit tests to see if the software works as promised.  
++			</para>
++			
+ 			<sect2 id="tsql"><title><application>tsql</application></title>
+ 
+-			<para>The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  </para>
+-			<para><command>tsql</> can either use or bypass the configuration files.  By trying both options, you can usually determine if it's your dataserver that's not responding, or your configuration files that are messed up. </para> 
++			<para>The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  For details on the use of <command>tsql</>, consult its man page. </para>
++			<para><command>tsql</> can either use or bypass the configuration files.  By trying both options, you can usually determine if it's your server that's not responding, or your configuration files that are messed up. </para> 
+ 
+-			<bridgehead renderas='sect3'>Using <filename>freetds.conf</>:</bridgehead>
+-			<para>
+-<cmdsynopsis label="Syntax synopsis for tsql">
+-  <command>tsql</command> 
+-	<arg choice='req'>-S<replaceable>server</replaceable></arg>
+-	<arg choice='req'>-U<replaceable>username</replaceable></arg>
+-	<arg choice='opt'>-P<replaceable>password</replaceable></arg>
+-	<arg choice='opt'>-C</arg>
+-</cmdsynopsis>
++			<sect3 id="tsql.freetds.conf"><title><replaceable>servername</> Lookup</title>
++			<para><application>tsql</> reports where it looks for &freetdsconf; and other compile-time settings with <command>tsql -C</>.  
++			</para>
++<example id="e.g.tsqlShowsettings">
++<title>Show compile-time settings with <command>tsql</></title>
++<screen>
++<prompt>$ </prompt><userinput>tsql -C </userinput>
++<prompt>Password: </prompt>
++<computeroutput>
++locale is "C"
++locale charset is "646"
++Compile-time settings (established with the "configure" script):
++                           Version: freetds &version;
++            freetds.conf directory: /usr/local/etc
++    MS db-lib source compatibility: no
++       Sybase binary compatibility: no
++                     Thread safety: yes
++                     iconv library: no
++                       TDS version: 7.0
++                             iODBC: no
++                          unixodbc: no
++</computeroutput>
++</screen>
++</example>
++
++			<para>When <replaceable>servername</> cannot be converted to an address, up to two messages may result.  Successful conversion (by any means) never produces an error message.  
++			
++<example id="e.g.notfound">
++<title>Failure to find or resolve <replaceable>servername</></title>
++<screen>
++<prompt>$ </prompt><userinput>tsql -S <replaceable>nobox</replaceable> -U <replaceable>sa</replaceable> </userinput>
++<prompt>Password: </prompt>
++<computeroutput>
++locale is "C"
++locale charset is "646"
++Msg 20012, Level 2, State -1, Server OpenClient, Line -1
++Server name not found in configuration files.
++Msg 20013, Level 2, State -1, Server OpenClient, Line -1
++Unknown host machine name.
++There was a problem connecting to the server
++</computeroutput>
++<prompt>$ </prompt><userinput>host emforester</userinput>
++<computeroutput>
++Host not found.
++</computeroutput>
++</screen>
++</example>
++
++In the above case <literal>nobox</> was not found in &freetdsconf; and was is not a valid hostname according to DNS.  
+ 			</para>
+ 
+-<example id="e.g.tsqlFail">
++			<para>If <replaceable>servername</> is found but refers to an invalid hostname, only message 20013 is returned. 
++
++<example id="e.g.badname">
++<title>Failure to resolve hostname for <replaceable>servername</></title>
++<screen>
++<prompt>$ </prompt><userinput>tsql -S <replaceable>nonesuch</replaceable> -U <replaceable>sa</replaceable>   </userinput>
++<prompt>Password: </prompt>
++<computeroutput>
++locale is "C"
++locale charset is "646"
++Msg 20013, Level 2, State -1, Server OpenClient, Line -1
++Unknown host machine name.
++There was a problem connecting to the server
++</computeroutput>
++</screen>
++</example>	
++			Unfortunately, the <quote>host machine name</quote> isn't mentioned in the error message.  Fortunately, this kind of setup problem is rarely encountered by users.  
++			</para>
++			<para>If name lookup succeeds, &freetds; next attempts to connect to the server.  <emphasis>To connect</> means to form at TCP connection by calling <function>connect(2)</>.  A valid connection must exist before any information can be exchanged with the server.  Specifically, we need a connection before we can log in.  
++			</para>
++			<para>A few things can go wrong at this point.  The address returned by DNS may not be that of the machine hosting the server.  The machine may be down.  The server may not be running.  The server may be running but not listening to the port &freetds; is attempting to connect to.  In rare cases, both ends are correctly configured, but a firewall stands in the way. 
++			</para>
++			<para>If no server accepts the connection, no connection can be established.  It's difficult to know why, and the message is consequently vague. 
++
++<example id="e.g.noconnect">
+ <title>Failing to connect with tsql</title>
+ <screen>
+ <prompt>$ </prompt><userinput>tsql -S <replaceable>emforester</replaceable> -U <replaceable>sa</replaceable>   #only connect?</userinput>
+ <prompt>Password: </prompt>
+ <computeroutput>
+-src/tds/login.c: tds_connect: 192.168.1.12:4100: Connection refused
+-Msg 20009, Level 9, State 0, Server OpenClient, Line 0
+-Server is unavailable or does not exist.
++Msg 20009, Level 9, State -1, Server OpenClient, Line -1
++Unable to connect: Adaptive Server is unavailable or does not exist
+ There was a problem connecting to the server
+ </computeroutput>
+ </screen>
+ </example>
++			If you get message 20009, remember you haven't connected to the machine.  It's a configuration or network issue,  <emphasis>not a protocol failure</>.  Verify the server is up, has the name and IP address &freetds; is using, and is listening to the configured port.  
++			</para>
++			<para>Named instances provide another way for connections to fail.  You can verify the instance name and the port the server is using with <command>tsql -L</>.  
++	
++<example id="e.g.instance.name">
++<title>Getting instance information with tsql</title>
++<screen>
++<prompt>$ </prompt><userinput>tsql -LH <replaceable>servername</replaceable> </userinput>
++<computeroutput>
++locale is "C"
++locale charset is "646"
++     ServerName TITAN
++   InstanceName MSSQLSERVER
++    IsClustered No
++        Version 8.00.194
++            tcp 1433
++             np \\TITAN\pipe\sql\query
++</computeroutput>
++</screen>
++</example>
++			<replaceable>servername</replaceable> could be configured to use instance <literal>MSSQLSERVER</> or port <literal>1433</>.  
++			</para>
+ 
+-<example id="e.g.tsqlservername">
+-<title>Connect with <command>tsql</> using a servername in <filename>freetds.conf</></title>
++			<para>After a valid connection is formed, &freetds; sends a login packet.  The TDS protocol provides no way to interrogate the server for its TDS version.  If you specify the wrong one, you'll get an error. 
++	
++<example id="e.g.bad.tdsver">
++<title>Using the wrong protocol for the server</title>
+ <screen>
+-<prompt>$ </prompt><userinput>tsql -S <replaceable>sandbox</replaceable> -U <replaceable>sa</replaceable></userinput>
++<prompt>$ </prompt><userinput>tsql -S <replaceable>servername</replaceable> </userinput>
+ <prompt>Password: </prompt>
+ <computeroutput>
+-1> 
++Msg 20017, Level 9, State -1, Server OpenClient, Line -1
++Unexpected EOF from the server
++Msg 20002, Level 9, State -1, Server OpenClient, Line -1
++Adaptive Server connection failed
++There was a problem connecting to the server
++</computeroutput>
++</screen>
++</example>
++
++			<quote>Unexpected EOF from the server</quote> seems to be a fairly common message when the wrong TDS version is used.  Note that there's no complaint about the login.  
++			</para>
++			
++			<para>If the right TDS version is used, the server will accept the login packet and examine its contents to authenticate the user.  If there's a problem, the server will say so.  This is the first time we're receiving a message from the server.  <footnote><para>If you'd like to help the project and want to so something fairly easy but still useful, modify tsql to distinguish clearly between errors returned by the library, and those returned by the server.  Errors should be marked <quote>error</> and don't return <emphasis>state</> or a line number, but can contain an error code (and message) from the operating system.</para></footnote>
++			
++
++<example id="e.g.bad.login">
++<title>Login failure</title>
++<screen>
++<prompt>$ </prompt><userinput>tsql -S <replaceable>servername</replaceable> -U notme </userinput>
++<prompt>Password: </prompt>
++<computeroutput>
++Msg 18456, Level 14, State 1, Server [<replaceable>servername</replaceable>], Line 0
++Login failed for user 'notme'.
++Msg 20002, Level 9, State -1, Server OpenClient, Line -1
++Adaptive Server connection failed
++There was a problem connecting to the server
+ </computeroutput>
+ </screen>
+ </example>
++			</para>
+ 
+-			<bridgehead renderas='sect3'>Bypassing <filename>freetds.conf</>:</bridgehead>
++			<bridgehead renderas='sect3'>Bypassing &freetdsconf;:</bridgehead>
+ 			<para>
+ <cmdsynopsis label="Syntax synopsis for tsql">
+   <command>tsql</command> 
+@@ -1313,7 +1477,7 @@ There was a problem connecting to the server
+ 	<arg choice='opt'>-C</arg>
+ </cmdsynopsis>
+ 
+-			Keep in mind that the TDS protocol version normally comes from <filename>freetds.conf</>.  When using <command>tsql</> this way, the library uses the compiled-in default (set by the <filename>configure</> script).  If that's not what you want, override it using the <envar>TDSVER</> environment variable.  
++			Keep in mind that the TDS protocol version normally comes from &freetdsconf;.  When using <command>tsql</> this way, the library uses the compiled-in default (set by the <filename>configure</> script).  If that's not what you want, override it using the <envar>TDSVER</> environment variable.  
+ 			</para>
+ 
+ <example id="e.g.tsqlhostname">
+@@ -1329,35 +1493,14 @@ There was a problem connecting to the server
+ 
+ 
+ 
+-<para>Another handy diagnostic feature of <command>tsql</> is that it can show you the compile-time settings of the installed version of <productname>FreeTDS</productname>:  </para>
+-
+-<example id="e.g.tsqlShowsettings">
+-<title>Show compile-time settings with <command>tsql</></title>
+-<screen>
+-<prompt>$ </prompt><userinput>tsql -C </userinput>
+-<prompt>Password: </prompt>
+-<computeroutput>
+-locale is "C"
+-locale charset is "646"
+-Compile-time settings (established with the "configure" script):
+-                           Version: freetds v0.62.dev.20030804
+-    MS db-lib source compatibility: no
+-       Sybase binary compatibility: unknown
+-                     Thread safety: no
+-                     iconv library: no
+-                       TDS version: 7.0
+-                             iODBC: no
+-                          unixodbc: no
+-</computeroutput>
+-</screen>
+-</example>
+ 			<para>
+ For details on <command>tsql</>, see the its man page.  
+ 			</para>
++			</sect3>
+ 			</sect2>
+ 			<sect2 id="Tests"><title><application>Unit Tests</application></title>
+ 			<para>
+-The source code directory of each <productname>FreeTDS</productname> library includes a <filename>unittests</> directory.  
++The source code directory of each &freetds; library includes a <filename>unittests</> directory.  
+ 
+ <screen>
+ <prompt>$ </prompt><userinput>ls -d -1 src/*/unittests</userinput>
+@@ -1372,7 +1515,7 @@ src/tds/unittests
+ The unit tests rely on the <filename>PWD</> file in root of the FreeTDS source tree.  
+ <filename>PWD</> holds a username, password, servername, and database to be used for the unit tests.  We try to make sure to leave nothing behind: any data and objects created are either temporary or removed at the end of the test.  The tests should all work, subject to disclaimers in the directory's <filename>README</>.  			</para>
+ 			<para>
+-To invoke the tests, edit the <filename>PWD</> file and issue the command <command>make check</command>.  In order to execute all tests successfully, you must indicate a working, available dataserver in <filename>PWD</>.
++To invoke the tests, edit the <filename>PWD</> file and issue the command <command>make check</command>.  In order to execute all tests successfully, you must indicate a working, available servername in <filename>PWD</>.
+ Some tests require permission to create stored procedures on server.
+ 			</para>
+ 			<para>
+@@ -1380,7 +1523,7 @@ To complete successfully, the ODBC tests require some additional setup.  In your
+ 			</para>
+ 			<para>
+ <tip><para>
+-The <filename>PWD</> provided by <productname>FreeTDS</productname> includes usernames and passwords that probably don't exist on your server.  
++The <filename>PWD</> provided by &freetds; includes usernames and passwords that probably don't exist on your server.  
+ </para></tip>
+ 			</para>
+ 			</sect2>
+@@ -1404,10 +1547,10 @@ The ODBC 3.0 specification introduced a new function: <function>SQLDriverConnect
+ The connection attributes are provided as a single argument, a string of concatenated name-value pairs.  <function>SQLDriverConnect</> subsumed the functionality of <function>SQLConnect</>, in that the name-value pair string allowed the caller to pass &mdash;  in addition the the original <literal>DSN</>, <literal>UID</>, and <literal>PWD</> &mdash; any other parameters the driver could accept. Moreover, the application can specify which driver to use.  In effect, it became possible to specify the entire set of DSN properties as parameters to <function>SQLDriverConnect</>, obviating the need for <filename>odbc.ini</>.  This led to the use of the so-called <firstterm>DSN-less</> configuration, a setup with no <filename>odbc.ini</>.  
+ 			</para>
+ 			<para>
+-But <productname>FreeTDS</> did not start out as an ODBC driver (remember db-lib and ct-lib), and has always had its own way to store server properties: <filename>freetds.conf</>.  When Brian added the <productname>FreeTDS</> ODBC driver, he began by supporting the old <function>SQLConnect</>, using <filename>odbc.ini</> to describe the DSN.  That choice complied with the expectations of the Driver Managers, and minimized the amount of duplicated information in the configuration files.  But it can be a little confusing, too, because <filename>odbc.ini</> in effect points to <filename>freetds.conf</>.  We call this configuration <firstterm>ODBC-combined</>, because it supports all three <productname>FreeTDS</> libraries.  
++But <productname>FreeTDS</> did not start out as an ODBC driver (remember db-lib and ct-lib), and has always had its own way to store server properties: &freetdsconf;.  When Brian added the <productname>FreeTDS</> ODBC driver, he began by supporting the old <function>SQLConnect</>, using <filename>odbc.ini</> to describe the DSN.  That choice complied with the expectations of the Driver Managers, and minimized the amount of duplicated information in the configuration files.  But it can be a little confusing, too, because <filename>odbc.ini</> in effect points to &freetdsconf;.  We call this configuration <firstterm>ODBC-combined</>, because it supports all three <productname>FreeTDS</> libraries.  
+ 			</para>
+ 			<para>
+-With version 0.60, the <productname>FreeTDS</> ODBC library started to see fuller implementation. The driver was made able to read the connection attributes directly from <filename>odbc.ini</>, rather than leaning on <filename>freetds.conf</>.  For installations that don't need db-lib and ct-lib, this <firstterm>ODBC-only</> setup is simpler.  			</para>
++With version 0.60, the <productname>FreeTDS</> ODBC library started to see fuller implementation. The driver was made able to read the connection attributes directly from <filename>odbc.ini</>, rather than leaning on &freetdsconf;.  For installations that don't need db-lib and ct-lib, this <firstterm>ODBC-only</> setup is simpler.  			</para>
+ 			<para>
+ More recently, <function>SQLDriverConnect</> was added to <productname>FreeTDS</>.  As described above, this function allows the application to specify connection attributes with reference to either, or neither, configuration file.  It's your choice.  In making that choice, keep the following terms clear in your mind:
+ 			</para>
+@@ -1416,7 +1559,7 @@ More recently, <function>SQLDriverConnect</> was added to <productname>FreeTDS</
+ 	<varlistentry>
+ 		<term><literal>SERVERNAME</></term>
+ 		<listitem>
+-			<para>specifies the <literal>[<replaceable>dataserver</>]</literal> entry in <filename>freetds.conf</>. </para>
++			<para>specifies the <literal>[<replaceable>servername</>]</literal> entry in &freetdsconf;. </para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>
+@@ -1435,7 +1578,7 @@ More recently, <function>SQLDriverConnect</> was added to <productname>FreeTDS</
+ </variablelist>
+ 
+ 			<para>
+-In sum, <productname>FreeTDS</productname> supports three ODBC three choices:
++In sum, &freetds; supports three ODBC three choices:
+ 			</para>
+ 
+ 
+@@ -1450,13 +1593,13 @@ In sum, <productname>FreeTDS</productname> supports three ODBC three choices:
+ 		<term>ODBC-only</term>
+ 		<listitem>
+ 			<para><emphasis>All</> connection information
+-is specified in <filename>odbc.ini</>, without the need for <filename>freetds.conf</>.  This is the <quote>traditional</> ODBC setup.  </para>
++is specified in <filename>odbc.ini</>, without the need for &freetdsconf;.  This is the <quote>traditional</> ODBC setup.  </para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>
+ 		<term>ODBC-combined</term>
+ 		<listitem>
+-			<para>Connection information maintained in <filename>freetds.conf</>.  <filename>odbc.ini</> contains DSN entries that refer to dataserver names in <filename>freetds.conf</>.  </para>
++			<para>Connection information maintained in &freetdsconf;.  <filename>odbc.ini</> contains DSN entries that refer to servernames in &freetdsconf;.  </para>
+ 		</listitem>
+ 	</varlistentry>	
+ </variablelist>
+@@ -1520,9 +1663,9 @@ The following table defines all possible ODBC connection attributes for the <pro
+ <tbody>
+ 	<row>
+ 	<entry><literal>Servername</></entry>
+-	<entry>A valid <filename>freetds.conf</> server section</entry>
++	<entry>A valid &freetdsconf; server section</entry>
+ 	<entry>none</entry>
+-	<entry>A <filename>freetds.conf</> servername, not a hostname as known to DNS. If you want to use ODBC-only configuration, use  <literal>Server</> instead.</entry>
++	<entry>A &freetdsconf; servername, not a hostname as known to DNS. If you want to use ODBC-only configuration, use  <literal>Server</> instead.</entry>
+ 	</row>
+ 	<row>
+ 	<entry><literal>Server</></entry>
+@@ -1534,7 +1677,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<entry><literal>Port</></entry>
+ 	<entry>Any TCP port</entry>
+ 	<entry>Depends on the TDS version specified with <command>configure</></entry>
+-	<entry>The TCP port  where the dataserver is listening.  </entry>
++	<entry>The TCP port  where the servername is listening.  </entry>
+ 	</row>
+ 	<row>
+ 	<entry><literal>TDS_Version</></entry>
+@@ -1545,7 +1688,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<row>
+ 	<entry><literal>ClientCharset</></entry>
+ 	<entry>A name recognized by the iconv library linked to FreeTDS.
+-	This correspond to <literal>client charset</> in <filename>freetds.conf</>.</entry>
++	This correspond to <literal>client charset</> in &freetdsconf;.</entry>
+ 	<entry>ISO8859-1</entry>
+ 	<entry>Character set (encoding) used by the client.</entry>
+ 	</row>
+@@ -1565,7 +1708,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<entry><literal>Address</></entry>
+ 	<entry>Any</entry>
+ 	<entry>none</entry>
+-	<entry>IP address of the dataserver.  Useful if you want to specify a server by address,  rather than by name.  The format is <replaceable>ip,port</>  or simply <replaceable>ip</> in standard dotted-decimal notation.   </entry>
++	<entry>IP address of the servername.  Useful if you want to specify a server by address,  rather than by name.  The format is <replaceable>ip,port</>  or simply <replaceable>ip</> in standard dotted-decimal notation.   </entry>
+ 	</row>
+ 	<row>
+ 	<entry><literal>Database</></entry>
+@@ -1592,7 +1735,7 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 		</sect1>
+ 		<sect1 id="dsnless"><title>DSN-less configuration</title>
+ 			<para>
+-In a DSN-less configuration, the <filename>odbc.ini</filename> file is not consulted for server connection properties.  To connect to a dataserver, your application may refer to a dataserver entry in <filename>freetds.conf</>, or explicitly specify the dataserver's hostname (bypassing <filename>freetds.conf</>).    
++In a DSN-less configuration, the <filename>odbc.ini</filename> file is not consulted for server connection properties.  To connect to a servername, your application may refer to a servername entry in &freetdsconf;, or explicitly specify the servername's hostname (bypassing &freetdsconf;).    
+ 
+ <example id="e.g.SampleDSNless"><title>Sample files for a DSN-less configuration</title>
+ <para>The <filename>odbcinst.ini</filename> is quite brief: </para>
+@@ -1605,7 +1748,7 @@ In a DSN-less configuration, the <filename>odbc.ini</filename> file is not consu
+ 	Driver = /usr/local/freetds/lib/libtdsodbc.so
+ 	</programlisting>
+ </blockquote>
+-<para>The <filename>freetds.conf</> might look something like:</para>
++<para>The &freetdsconf; might look something like:</para>
+ <blockquote>
+ 	<programlisting>
+ 	;
+@@ -1624,7 +1767,7 @@ In a DSN-less configuration, the <filename>odbc.ini</filename> file is not consu
+ /*
+  * application call
+  */
+-const char servername[] = "JDBC"; <footnote><para>refers to the <literal>[JDBC]</> entry in <filename>freetds.conf</>.</para></footnote>
++const char servername[] = "JDBC"; <footnote><para>refers to the <literal>[JDBC]</> entry in &freetdsconf;.</para></footnote>
+ sprintf(tmp, "DRIVER=FreeTDS<footnote><para>refers to the <literal>[FreeTDS]</> entry in <filename>odbcinst.ini</>.</para></footnote>;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", 
+ 	servername, username, password, dbname);
+ res = SQLDriverConnect(Connection, NULL, (SQLCHAR *) tmp, SQL_NTS, 
+@@ -1638,7 +1781,7 @@ if (!SQL_SUCCEEDED(res)) {
+ 
+ You can even establish a connection without reference to either <filename>odbc.ini</filename> or <filename>freetd.conf</filename>.
+ 
+-<example id="e.g.ConnectDSNlessnoconf"><title>Connecting with a DSN-less configuration that does not use <filename>freetds.conf</filename></title>
++<example id="e.g.ConnectDSNlessnoconf"><title>Connecting with a DSN-less configuration that does not use &freetdsconf;</title>
+ <programlisting>
+ /*
+  * application call
+@@ -1659,7 +1802,7 @@ if (!SQL_SUCCEEDED(res)) {
+ 		</sect1>
+ 		<sect1 id="odbcinionly"><title>ODBC-only configuration</title>
+ 			<para>
+-An ODBC-only configuration relies solely on <filename>odbc.ini</> for server properties.  Other <productname>FreeTDS</productname> drivers don't know about <filename>odbc.ini</>.  
++An ODBC-only configuration relies solely on <filename>odbc.ini</> for server properties.  Other &freetds; drivers don't know about <filename>odbc.ini</>.  
+  
+ <example id="e.g.SampleODBConly"><title>Sample ODBC-only <filename>odbc.ini</filename> file</title>
+ <programlisting>
+@@ -1684,7 +1827,7 @@ Driver          = /usr/local/freetds/lib/libtdsodbc.so
+ 
+ 		<sect1 id="odbcombo"><title>ODBC-combined configuration</title>
+ 			<para>
+-Like the DSN-less configuration, ODBC-combined keeps server properties in <filename>freetds.conf</>.  The difference is that your applications can refer to the server by its DSN.  To make that possible, the DSN entry in <filename>odbc.ini</> refers to the dataserver entry in <filename>freetds.conf</>.  
++Like the DSN-less configuration, ODBC-combined keeps server properties in &freetdsconf;.  The difference is that your applications can refer to the server by its DSN.  To make that possible, the DSN entry in <filename>odbc.ini</> refers to the servername entry in &freetdsconf;.  
+ 			
+ <example id="e.g.SampleODBCcombo"><title>Sample ODBC-combined <filename>odbc.ini</filename> file</title>
+ <programlisting>
+@@ -1695,14 +1838,14 @@ Like the DSN-less configuration, ODBC-combined keeps server properties in <filen
+ Driver          = /usr/local/freetds/lib/libtdsodbc.so
+ Description     = Sybase JDBC Server
+ Trace           = No
+-Servername      = JDBC<footnote><para>Refers to the <literal>[JDBC]</> entry in  <filename>freetds.conf</>. </para></footnote>
++Servername      = JDBC<footnote><para>Refers to the <literal>[JDBC]</> entry in  &freetdsconf;. </para></footnote>
+ Database        = pubs2
+ 
+ [Default]
+ Driver          = /usr/local/freetds/lib/libtdsodbc.so
+ </programlisting>
+ </example>
+-<example id="e.g.samplecombofile"><title>Sample ODBC-combined <filename>freetds.conf</filename> file</title>
++<example id="e.g.samplecombofile"><title>Sample ODBC-combined &freetdsconf; file</title>
+ <programlisting>
+ ;
+ ; freetds.conf
+@@ -1715,7 +1858,7 @@ Driver          = /usr/local/freetds/lib/libtdsodbc.so
+ </example>
+ 			</para>
+ 			<para>
+-With this arrangement, an application can connect to the server in two ways, via its DSN (<literal>JDBCdsn</>), or its dataserver name (<literal>JDBC</>).  
++With this arrangement, an application can connect to the server in two ways, via its DSN (<literal>JDBCdsn</>), or its servername (<literal>JDBC</>).  
+ 			</para>
+ 		</sect1>
+ 		
+@@ -1725,18 +1868,18 @@ With this arrangement, an application can connect to the server in two ways, via
+ Supposing everything compiles and installs without trouble, how do you know if your ODBC setup  works?  Or, if you know it doesn't, what then?  
+ 			</para>
+ 			<para>
+-First, try to connect with <command>tsql</>.  If you're intending to use <filename>freetds.conf</>, exercise it with 
++First, try to connect with <command>tsql</>.  If you're intending to use &freetdsconf;, exercise it with 
+ 	<command>tsql -S <replaceable>servername</></command>.  If not, use
+ 	<command>TDSVER=7.0 tsql -H <replaceable>hostname</> -p <replaceable>port</></command>
+ 			</para>
+ 			<para>
+-If <command>tsql</> works and <command>isql</> doesn't, you've isolated the problem to the ODBC setup.  <productname>FreeTDS</productname> might have some interoperability problems, but mere connection to the database isn't one of them!  If <command>tsql</> 
++If <command>tsql</> works and <command>isql</> doesn't, you've isolated the problem to the ODBC setup.  &freetds; might have some interoperability problems, but mere connection to the database isn't one of them!  If <command>tsql</> 
+ doesn't work, turn on logging with <envar>TDSDUMP</>.  The log will tell you what TCP/IP name (and address) <productname>FreeTDS</> is attempting to connect to, and what version of the TDS protocol it's using.   
+ 			</para>
+ 			
+ 		<sect2 id="with.iodbc"><title>With iODBC</title>
+ 			
+-	<para>	<productname>iODBC</productname> comes with a sample command line query program called <command>odbctest</> that is located in the <filename>iodbc/samples</filename> directory.  Using this program you can get a listing of DSNs, connect, and issue queries.  It is often useful to compile a program such as this directly against the <productname>FreeTDS</productname> driver instead of using a driver manager.  This makes it simpler to debug if something goes wrong.  To do so, simply compile and install the <systemitem class="library">ODBC</systemitem> driver with <productname>iODBC</productname> as normal <footnote><para>When compiling directly to <productname>FreeTDS</productname> you still need the Driver Manager's header files.</para></footnote>, then compile and link the program directly:
++	<para>	<productname>iODBC</productname> comes with a sample command line query program called <command>odbctest</> that is located in the <filename>iodbc/samples</filename> directory.  Using this program you can get a listing of DSNs, connect, and issue queries.  It is often useful to compile a program such as this directly against the &freetds; driver instead of using a driver manager.  This makes it simpler to debug if something goes wrong.  To do so, simply compile and install the <systemitem class="library">ODBC</systemitem> driver with <productname>iODBC</productname> as normal <footnote><para>When compiling directly to &freetds; you still need the Driver Manager's header files.</para></footnote>, then compile and link the program directly:
+ 
+ <example id="e.g.odbctest.nodm">
+ 	<title>Compile <filename>odbctest</> without a driver manager.</title>
+@@ -1837,11 +1980,11 @@ Several version of Microsoft SQL server have a bug that affects big endian clien
+ <Note><para>The terms <emphasis>big endian</emphasis> and <emphasis>little endian</emphasis> come originally from Gulliver's Travels.  In computer science they refer to the the integer byte-order for a processor.  Big endian processors, such as Sparc and PowerPC store the most significant byte in the first memory location of a multi-byte integer.  Little endian processors, such as Intel and Alpha do it the other way around.  So the 16-bit number 258 would be 0x0102 on big endian and 0x0201 on little endian machines.</para></Note>
+ 
+ <para>
+-In this example we want to force connections to a server named <literal>mssql</literal> to emulate a little endian client.  We are using protocol version 4.2 here, version 7.0 or above will automatically emulate little endian mode regardless of the <filename>freetds.conf</filename> setting.
++In this example we want to force connections to a server named <literal>mssql</literal> to emulate a little endian client.  We are using protocol version 4.2 here, version 7.0 or above will automatically emulate little endian mode regardless of the &freetdsconf; setting.
+ <emphasis>You shouldn't use this option, set another protocol version instead (7.0, 7.1 or 7.2)</emphasis>.
+ </para>
+ <example id="e.g.LittleEndian">
+-<title>Emulate Little Endian <filename>freetds.conf</filename> setting</title>
++<title>Emulate Little Endian &freetdsconf; setting</title>
+ <programlisting>
+ [mssql]
+ 	host = ntbox.mydomain.com
+@@ -1854,13 +1997,13 @@ In this example we want to force connections to a server named <literal>mssql</l
+ 		<sect1 id="Localization">
+ 			<title>Localization and <acronym>TDS</> 7.0</title>
+ 			<para>
+-<acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.  (Background information on Unicode and how it affects <productname>FreeTDS</productname> can be found in the <link linkend="Unicode">appendix</link>.)
++<acronym>TDS</> 7.0 uses 2-byte Unicode (technically, <acronym>UCS-2</>) to transfer character data between servers and clients.  Included in <quote>character data</quote> are query text (i.e., <acronym>SQL</>), metadata (table names and such), and <foreignphrase>bona fide</> data of datatypes <literal>nchar</>, <literal>nvarchar</>, and <literal>ntext</>.  (Background information on Unicode and how it affects &freetds; can be found in the <link linkend="Unicode">appendix</link>.)
+ 			</para>
+ 			<para>
+-Because most Unix tools and environments do not support <acronym>UCS-2</>, <productname>FreeTDS</productname> provides for conversion by the client to other character sets.  The mechanism used is determined by the <filename>configure</> script, which looks for a <function>iconv(3)</> function, an implementation of the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.    If no <function>iconv</> library is found, or if it is explicitly disabled, <productname>FreeTDS</productname> will use its built-in <function>iconv</> substitute, and will be capable of converting among only <acronym>ISO 8859-1</>, <acronym>UTF-8</>, and <acronym>UCS-2</>.  
++Because most Unix tools and environments do not support <acronym>UCS-2</>, &freetds; provides for conversion by the client to other character sets.  The mechanism used is determined by the <filename>configure</> script, which looks for a <function>iconv(3)</> function, an implementation of the <ulink url="http://www.opengroup.org/onlinepubs/7908799/xsh/iconv.html">iconv</ulink> standard.    If no <function>iconv</> library is found, or if it is explicitly disabled, &freetds; will use its built-in <function>iconv</> substitute, and will be capable of converting among only <acronym>ISO 8859-1</>, <acronym>UTF-8</>, and <acronym>UCS-2</>.  
+ 			</para>
+ 			<para>
+-To learn what character set the client wants, <productname>FreeTDS</productname> prefers the applicable <link linkend="clientcharset"><filename>freetds.conf</></link> <literal>client charset</> property.  If that is not set, it parses the <envar>LANG</> environment variable.  In either case, the found string is passed to <function>iconv</>(3) (or its built-in replacment).  <footnote><para>The built-in replacement expects GNU iconv names: <literal>ISO-8859-1</>, <literal>US-ASCII</>, or <literal>UTF-8</>.</para></footnote>.  If neither is found, <acronym>UCS-2</> data are converted to <acronym>ISO 8859-1</>.  
++To learn what character set the client wants, &freetds; prefers the applicable <link linkend="clientcharset">&freetdsconf;</link> <literal>client charset</> property.  If that is not set, it parses the <envar>LANG</> environment variable.  In either case, the found string is passed to <function>iconv</>(3) (or its built-in replacment).  <footnote><para>The built-in replacement expects GNU iconv names: <literal>ISO-8859-1</>, <literal>US-ASCII</>, or <literal>UTF-8</>.</para></footnote>.  If neither is found, <acronym>UCS-2</> data are converted to <acronym>ISO 8859-1</>.  
+ 			</para>
+ 
+ 			<para>
+@@ -1876,7 +2019,7 @@ For other systems, consult your documentation (most likely <command>man iconv</c
+ In this example a server named <literal>mssql</literal> will return data encoded in the GREEK character set.
+ 			</para>
+ <example id="e.g.GREEK">
+-<title>Configuring for GREEK <filename>freetds.conf</filename> setting</title>
++<title>Configuring for GREEK &freetdsconf; setting</title>
+ <programlisting>
+ [mssql]
+ 	host = ntbox.mydomain.com
+@@ -1886,17 +2029,17 @@ In this example a server named <literal>mssql</literal> will return data encoded
+ </programlisting>
+ </example>
+ 			<para>
+-If <productname>FreeTDS</productname> runs into a character it can not convert, its behavior varies according to the severity of the problem.  On retrieving data from the server, <productname>FreeTDS</productname> substitutes an <acronym>ASCII</> '?' in the character's place, and emits a warning message stating that some characters could not be converted.  On sending data to the server, <productname>FreeTDS</productname> aborts the query and emits an error message.  It is well to ensure that the data contained in the database is representable in the client's character set.</para>
++If &freetds; runs into a character it can not convert, its behavior varies according to the severity of the problem.  On retrieving data from the server, &freetds; substitutes an <acronym>ASCII</> '?' in the character's place, and emits a warning message stating that some characters could not be converted.  On sending data to the server, &freetds; aborts the query and emits an error message.  It is well to ensure that the data contained in the database is representable in the client's character set.</para>
+ 
+ 			<para>
+ If you have a mix of character data that can not be contained in a single-byte character set, you may wish to use <acronym>UTF-8</>.  <acronym>UTF-8</> is a variable length unicode encoding that is compatible with <acronym>ASCII</> in the range 0 to 127.  With <acronym>UTF-8</>, you are guaranteed to never have an unconvertible character.</para>
+ 
+-<Important><para><productname>FreeTDS</productname> is not fully compatible with multi-byte character sets such as <acronym>UCS-2</>.  You must use an ASCII-extension charset (e.g., UTF-8, ISO-8859-*)<footnote><para>not EBCDIC or other weird charsets</para></footnote>. Great care should be taken testing applications using these encodings. Specifically, many applications do not expect the number of characters returned to exceed the column size (in bytes).  </para></Important>
++<Important><para>&freetds; is not fully compatible with multi-byte character sets such as <acronym>UCS-2</>.  You must use an ASCII-extension charset (e.g., UTF-8, ISO-8859-*)<footnote><para>not EBCDIC or other weird charsets</para></footnote>. Great care should be taken testing applications using these encodings. Specifically, many applications do not expect the number of characters returned to exceed the column size (in bytes).  </para></Important>
+ 			<para>
+ In the following example, a server named <literal>mssql</literal> will return data encoded in the <acronym>UTF-8</> character set.
+ 			</para>
+ <example id="e.g.UTF8">
+-<title>Configuring for <acronym>UTF-8</> <filename>freetds.conf</filename> setting</title>
++<title>Configuring for <acronym>UTF-8</> &freetdsconf; setting</title>
+ <programlisting>
+ [mssql]
+ 	host = ntbox.mydomain.com
+@@ -1943,7 +2086,7 @@ Why this happens is anyone's guess.  Here's one: it makes the datatype of the co
+ <Note><para>Domain logins can be used only with TDS protocol versions 7.0 or above.</para></Note>
+ 			<para>
+ As mentioned in the installation chapter, <productname>Microsoft SQL Server</productname> includes the ability to use domain logins instead of standard server logins.  The advantage of doing this is that the passwords are encrypted on the wire using a challenge-response protocol.
+-<productname>FreeTDS</productname> began supporting domain logins in version 0.60.
++&freetds; began supporting domain logins in version 0.60.
+ 			</para>
+ 			<para>
+ To use domain logins, use the <literal>'DOMAIN\username'</> syntax for the username and use the domain password.  
+@@ -1960,16 +2103,16 @@ Changed language setting to middle_english.
+ </example>
+ 
+ 			<para>
+-When <productname>FreeTDS</productname> sees the <quote><literal>\</></quote> character, it automatically chooses a domain login.
++When &freetds; sees the <quote><literal>\</></quote> character, it automatically chooses a domain login.
+   			</para>
+ <Note><para>The term <firstterm>domain</> in this context is a Microsoft term.  It refers to what's sometimes called an <firstterm>NT domain</firstterm>.  It's unrelated to the DNS domain.  DNS domains are used for name resolution.  NT domains are used for authentication.  Authentication is done by the domain controller, often the <firstterm>Primary Domain Controller</firstterm> (PDC).  
+   			</para><para>
+-The SQL Server machine may belong to an NT domain.  <productname>FreeTDS</productname> provides an encrypted password &mdash; a domain password, known to the domain controller &mdash; that the server will ask the domain controller to verify.  </para></Note>
++The SQL Server machine may belong to an NT domain.  &freetds; provides an encrypted password &mdash; a domain password, known to the domain controller &mdash; that the server will ask the domain controller to verify.  </para></Note>
+ 
+ 		<sect2 id="domaindetails">
+ 			<title>Implementation details</title>
+ 			<para>
+-Support for domain logins in <productname>FreeTDS</productname> is limited to the TCP/IP network protocol stack.   <productname>FreeTDS</productname> does not currently implement support for Named Pipe-based SQL connections &mdash; that is, connections transported over the DCE/RPC interface, which uses TCP port 139, 445, or 135 on Win32 machines depending on the type of encapsulation used for DCE/RPC itself. Supporting this would require a fairly extensive DCE/RPC library for Unix.   <productname>Samba</productname> has one that is licensed under the GPL and therefore not usable by LGPL-licensed projects such as <productname>FreeTDS</productname> . 
++Support for domain logins in &freetds; is limited to the TCP/IP network protocol stack.   &freetds; does not currently implement support for Named Pipe-based SQL connections &mdash; that is, connections transported over the DCE/RPC interface, which uses TCP port 139, 445, or 135 on Win32 machines depending on the type of encapsulation used for DCE/RPC itself. Supporting this would require a fairly extensive DCE/RPC library for Unix.   <productname>Samba</productname> has one that is licensed under the GPL and therefore not usable by LGPL-licensed projects such as &freetds; . 
+ 			</para>
+ 			<para>
+ Your domain controller must allow authentication over TCP/IP, or you will be unable to log in.  One symptom of a server that requires Named Pipes for authentication is an error message such as:
+@@ -2006,10 +2149,10 @@ For a technical description of the protocol used for domain logins, see
+ 		<sect1 id="appendmode">
+ 			<title>Appending Dump Files</title>
+ 			<para>
+-When running <productname>FreeTDS</productname> with applications such as <productname>Apache</productname>/PHP it is often difficult to get a usable log file.  Since each of the many httpd children opens the file at the beginning of its connection and closes it on connection close, they tend to stomp all over each other.  In append mode, the log file is opened for append each time it is written to and then immediately closed.  If you are experiencing problems when running under <productname>Apache</productname> (or similar application) use append mode to generate useful logs.
++When running &freetds; with applications such as <productname>Apache</productname>/PHP it is often difficult to get a usable log file.  Since each of the many httpd children opens the file at the beginning of its connection and closes it on connection close, they tend to stomp all over each other.  In append mode, the log file is opened for append each time it is written to and then immediately closed.  If you are experiencing problems when running under <productname>Apache</productname> (or similar application) use append mode to generate useful logs.
+ 			</para>
+ <example id="e.g.DumpAppend">
+-<title>Turning on Dump File Append mode in  <filename>freetds.conf</filename></title>
++<title>Turning on Dump File Append mode in  &freetdsconf;</title>
+ <programlisting>
+ [mssql]
+ 	host = ntbox.mydomain.com
+@@ -2026,7 +2169,7 @@ In this example, the <filename>/tmp/freetds.log</filename> file will contain log
+ Because there will be one log file being opened and closed more or less continuously, there is going to be a negative impact on performance. Also, be advised that the log file will grow quite large.
+ </para></Important>
+ <para>
+-As an alternative to <productname>FreeTDS</productname> logging, you might also consider using <application>tcpdump</application> or <application>ethereal</application> to log network packets.  While not as useful as a <acronym>TDS</> log, it can also help to identify problems.
++As an alternative to &freetds; logging, you might also consider using <application>tcpdump</application> or <application>ethereal</application> to log network packets.  While not as useful as a <acronym>TDS</> log, it can also help to identify problems.
+ </para>
+ 
+ 
+@@ -2034,25 +2177,25 @@ As an alternative to <productname>FreeTDS</productname> logging, you might also
+ 		<sect1 id="tdspool">
+ 		<title>TDS Connection Pooling</title>
+ 		<para>
+-<productname>FreeTDS</productname> 0.52 was the first to include a <acronym>TDS</> Connection Pooling server.  It lives in the <filename>src/pool</filename> directory.
++&freetds; 0.52 was the first to include a <acronym>TDS</> Connection Pooling server.  It lives in the <filename>src/pool</filename> directory.
+ 		</para>
+ 		<para>
+-The <productname>FreeTDS</productname> connection pool is a server process, it acts just like a <productname>SQL Server</productname>.  You can use any program to attach to it that you could use to attach to a real <productname>SQL Server</productname>.  The pool in turn connects to the <productname>SQL Server</productname> and database you specify, and attempts to share these connections.  See the <filename>README</filename> in the pool directory for a more detailed description of its inner workings.
++The &freetds; connection pool is a server process, it acts just like a <productname>SQL Server</productname>.  You can use any program to attach to it that you could use to attach to a real <productname>SQL Server</productname>.  The pool in turn connects to the <productname>SQL Server</productname> and database you specify, and attempts to share these connections.  See the <filename>README</filename> in the pool directory for a more detailed description of its inner workings.
+ 		</para>
+ 		<para>
+-To configure the pooling server, first make sure <productname>FreeTDS</productname> has a working entry for the real <productname>SQL Server</productname> by connecting to it with <application>SQSH</application> or another program. 
++To configure the pooling server, first make sure &freetds; has a working entry for the real <productname>SQL Server</productname> by connecting to it with <application>SQSH</application> or another program. 
+ 		</para>
+ <Note><para>
+-The <productname>FreeTDS</productname> connection pool currently only supports <acronym>TDS</> version 4.2.  <emphasis>This restriction applies to both the client-to-pool and pool-to-server connections!</emphasis>
++The &freetds; connection pool currently only supports <acronym>TDS</> version 4.2.  <emphasis>This restriction applies to both the client-to-pool and pool-to-server connections!</emphasis>
+ </para></Note>
+ 		<para>
+ After FreeTDS has been installed, you will find an executable named <command>tdspool</command> in the <filename>/usr/local/bin</filename> directory (or whatever directory was specified with the <command>configure</> <option>--with-prefix flag</> option).
+ 		</para>
+ 		<para>
+-Next, edit the <filename>pool.conf</filename> file in the <productname>FreeTDS</productname>'s <filename>etc</filename> directory.  The <filename>pool.conf</filename> file is formatted like the <filename>freetds.conf</filename> with a section name in brackets and options for each section in key/value pairs.
++Next, edit the <filename>pool.conf</filename> file in the &freetds;'s <filename>etc</filename> directory.  The <filename>pool.conf</filename> file is formatted like the &freetdsconf; with a section name in brackets and options for each section in key/value pairs.
+ 		</para>
+ 		<para>
+-Just like the <filename>freetds.conf</filename> file there are two types of sections, a <literal>[global]</literal> section whose options affect all pools, and a section with the name of the pool for pool-specific options.  The following options are supported and may appear in either section.
++Just like the &freetdsconf; file there are two types of sections, a <literal>[global]</literal> section whose options affect all pools, and a section with the name of the pool for pool-specific options.  The following options are supported and may appear in either section.
+ 		</para>
+ 		<para>
+ 
+@@ -2072,25 +2215,25 @@ Just like the <filename>freetds.conf</filename> file there are two types of sect
+ 	<entry>user</entry>
+ 	<entry>Any valid user</entry>
+ 	<entry>none</entry>
+-	<entry>The username used to connect to the dataserver.</entry>
++	<entry>The username used to connect to the servername.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>password</entry>
+ 	<entry>Any</entry>
+ 	<entry>none</entry>
+-	<entry>The password of the user at the dataserver.</entry>
++	<entry>The password of the user at the servername.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>server</entry>
+ 	<entry>Any <emphasis>TDS 4.2</emphasis> entry in the freetds.conf file</entry>
+ 	<entry>none</entry>
+-	<entry>The alias from the freetds.conf file representing the dataserver that will be connected to.</entry>
++	<entry>The alias from the freetds.conf file representing the servername that will be connected to.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>database</entry>
+ 	<entry>Any valid database</entry>
+ 	<entry>User's default database</entry>
+-	<entry>The database on the dataserver to use.</entry>
++	<entry>The database on the servername to use.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>port</entry>
+@@ -2102,13 +2245,13 @@ Just like the <filename>freetds.conf</filename> file there are two types of sect
+ 	<entry>min pool conn</entry>
+ 	<entry>1 or more</entry>
+ 	<entry>none</entry>
+-	<entry>Minimum number of open connections to maintain to the dataserver.</entry>
++	<entry>Minimum number of open connections to maintain to the servername.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>max pool conn</entry>
+ 	<entry>1 or more</entry>
+ 	<entry>none</entry>
+-	<entry>Maximum number of open connections to open against the dataserver.</entry>
++	<entry>Maximum number of open connections to open against the servername.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>max member age</entry>
+@@ -2152,7 +2295,7 @@ Now you can run <Command>tdspool</Command> with the name of the pool you are ser
+ </screen>
+ 		</para>
+ 		<para>
+-Before your clients connect to the pool, you must edit your <filename>freetds.conf</filename> to include the host and port of the pooling server, and point your clients at it.
++Before your clients connect to the pool, you must edit your &freetdsconf; to include the host and port of the pooling server, and point your clients at it.
+ 		</para>
+ 		</sect1>
+ 		
+@@ -2196,10 +2339,10 @@ To set up FreeTDS over stunnel between a Linux webserver and a W2k SQL server:
+ 				</para></listitem>
+ 			<listitem>
+ 				<para>Set up FreeTDS to use the tunnel.  If this is your unencrypted entry in
+-   <filename>freetds.conf</filename>:
++   &freetdsconf;:
+ 				</para>
+ <example id="e.g.Unencrypted">
+-<title>Unencrypted entry in <filename>freetds.conf</filename></title>
++<title>Unencrypted entry in &freetdsconf;</title>
+ <programlisting>
+    [win2kserver]
+         host = win2kserver
+@@ -2209,7 +2352,7 @@ To set up FreeTDS over stunnel between a Linux webserver and a W2k SQL server:
+ 				<para>   the encrypted equivalent uses:
+ 				</para>
+ <example id="e.g.Encrypted">
+-<title>Encrypted entry in <filename>freetds.conf</filename></title>
++<title>Encrypted entry in &freetdsconf;</title>
+ <programlisting>
+    [win2kserver]
+         host = localhost
+@@ -2222,10 +2365,10 @@ To set up FreeTDS over stunnel between a Linux webserver and a W2k SQL server:
+ 	</chapter>
+ 				<!-- ////////////////// CHAPTER /////////////////////// -->
+ 	<chapter id="usefreetds">
+-		<title>Use <productname>FreeTDS</productname> </title>
+-		<abstract><para><productname>FreeTDS</productname>  includes several utilities.  Some are testing tools, some demonstration projects, some intended for day-to-day use.  All have man pages. </para></abstract>
++		<title>Use &freetds; </title>
++		<abstract><para>&freetds;  includes several utilities.  Some are testing tools, some demonstration projects, some intended for day-to-day use.  All have man pages. </para></abstract>
+ 		
+-		<sect1 id="utilities"><title><productname>FreeTDS</productname> Utilities</>
++		<sect1 id="utilities"><title>&freetds; Utilities</>
+ 
+ 		<variablelist><title>(listed alphabetically)</title>
+         		<varlistentry>
+@@ -2308,19 +2451,19 @@ To set up FreeTDS over stunnel between a Linux webserver and a W2k SQL server:
+ 	<chapter id="software">
+ 		<title>How to get what works with it working</title>
+ 		<para>
+-The following programs are known to work to some extent with <productname>FreeTDS</productname>.  Here you will find any special instructions for getting them compiled or running.
++The following programs are known to work to some extent with &freetds;.  Here you will find any special instructions for getting them compiled or running.
+ 		</para>
+ 		<sect1 id="sqsh">
+ 			<title><application>SQSH</application></title>
+ 			<para>
+-<application>SQSH</application> is a command line based query tool written by Scott Gray to replace the <command>isql</> utility that ships with <productname>Sybase ASE</productname>.  It makes a great diagnostic tool for <productname>FreeTDS</productname> as well.  If you are having trouble, install <application>SQSH</application> (it's easy) and try getting that to work before more complicated arrangements.
++<application>SQSH</application> is a command line based query tool written by Scott Gray to replace the <command>isql</> utility that ships with <productname>Sybase ASE</productname>.  It makes a great diagnostic tool for &freetds; as well.  If you are having trouble, install <application>SQSH</application> (it's easy) and try getting that to work before more complicated arrangements.
+ 
+ 	<tip><sidebar><para>That advice is so good, it bears repeating.  If you are having trouble, grab <application>SQSH</application> and get that to work. Not only will it help isolate the problem, it will give you a very capable tool.  </para></sidebar></tip>
+ 
+ 			</para>
+ 
+ 			<para>
+-<application>SQSH</application> 2.1 includes direct support for <productname>FreeTDS</productname>, so these instructions may not be necessary, but are still included just in case.  
++<application>SQSH</application> 2.1 includes direct support for &freetds;, so these instructions may not be necessary, but are still included just in case.  
+ 			</para>
+ 			<para>
+ After running <Command>configure</Command> in <application>SQSH</application>'s directory (make sure you set the Sybase environment variable first), look for the Sybase_LIBS definition in the Makefile.  Change the line to match this example.
+@@ -2356,7 +2499,7 @@ After that just type <command>make</command> and you are off and running.
+ 
+ 		<sect1 id="perl">
+ 			<title>Perl</title>
+-			<para>There are a few ways to use <productname>Perl</productname> to connect to a <productname>SQL Server</productname> using <productname>FreeTDS</productname>. </para>
++			<para>There are a few ways to use <productname>Perl</productname> to connect to a <productname>SQL Server</productname> using &freetds;. </para>
+ 			
+ 		<sect2 id="DBD.Sybase"><title>DBD::Sybase</title>
+ 			<para>The recommended choice is <systemitem class="library">DBD::Sybase</systemitem> from Michael Peppler.  Despite the name it works for any Sybase or Microsoft <productname>SQL Server</productname>.  <systemitem class="library">DBD::Sybase</systemitem> uses the <systemitem class="library">ct-lib</systemitem> <acronym>API</> and works well. </para>
+@@ -2364,7 +2507,7 @@ After that just type <command>make</command> and you are off and running.
+ 			
+ 		<sect2 id="DBD.ODBC"><title>DBD::ODBC</title>
+ 			<para>
+-You may also use <systemitem class="library">DBD::ODBC</systemitem> with the <productname>FreeTDS</productname> <systemitem class="library">ODBC</systemitem> driver.  You may find this attractive if you're familiar with <systemitem class="library">DBD::ODBC</systemitem>.
++You may also use <systemitem class="library">DBD::ODBC</systemitem> with the &freetds; <systemitem class="library">ODBC</systemitem> driver.  You may find this attractive if you're familiar with <systemitem class="library">DBD::ODBC</systemitem>.
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="Sybperl"><title>Sybperl</title>
+@@ -2466,7 +2609,7 @@ You'll note this is the same program as for <systemitem class="library">DBD::Syb
+ 		<sect1 id="php">
+ 			<title>PHP</title>
+ 			<para>
+-There are three options for building PHP with support for <productname>FreeTDS</productname> corresponding to the three <acronym>API</>s that <productname>FreeTDS</productname> supports: <systemitem class="library">db-lib</systemitem>, <systemitem class="library">ct-lib</systemitem>, and <systemitem class="library">ODBC</systemitem>.
++There are three options for building PHP with support for &freetds; corresponding to the three <acronym>API</>s that &freetds; supports: <systemitem class="library">db-lib</systemitem>, <systemitem class="library">ct-lib</systemitem>, and <systemitem class="library">ODBC</systemitem>.
+ <note><para>All these examples build the CGI version.  Consult <ulink url="http://www.php.net/docs.php">PHP's documentation</ulink> for building the Apache module and including other extensions.</para></note>
+ 			</para>
+ 		<sect2 id="phpDblib">
+@@ -2476,7 +2619,7 @@ PHP can be configured with <systemitem class="library">db-lib</systemitem> acces
+  			</para>
+ 			<para>
+ <example id="e.g.PHP.dblib"><title>PHP and <systemitem class="library">db-lib</systemitem> for <quote>Sybase</></title>
+-	<para>First build <productname>FreeTDS</productname> normally.</para>
++	<para>First build &freetds; normally.</para>
+ <screen>
+ <prompt>$ </prompt><userinput>./configure --prefix=/usr/local/freetds</userinput>
+ <prompt>$ </prompt><userinput>make</userinput>
+@@ -2500,7 +2643,7 @@ PHP can be configured with <systemitem class="library">db-lib</systemitem> acces
+ 		<sect2 id="ctlib">
+ 			<title><systemitem class="library">ct-lib</systemitem></title>
+ 			<para>
+-Option 2 is to use the <systemitem class="library">ct-lib</systemitem> <acronym>API</>.  Again here, we run into minor difficulties at build time.  Applications linking with Sybase's OpenClient have to link in a handful of libraries and these libraries vary slightly from platform to platform.  When creating <productname>FreeTDS</productname> it was decided that there would be only one library: <filename>libct</filename>.  This saves a great deal of library naming conflicts that Sybase ran into (e.g. <filename>libtcl</filename> is used both by Sybase and the language TCL), however some applications like PHP assume that all the Sybase libraries will be present. So, some hand editing of the Makefile is necessary to remove these extra libs.  Build <productname>FreeTDS</productname> just as you would for <systemitem class="library">db-lib</systemitem> in 
++Option 2 is to use the <systemitem class="library">ct-lib</systemitem> <acronym>API</>.  Again here, we run into minor difficulties at build time.  Applications linking with Sybase's OpenClient have to link in a handful of libraries and these libraries vary slightly from platform to platform.  When creating &freetds; it was decided that there would be only one library: <filename>libct</filename>.  This saves a great deal of library naming conflicts that Sybase ran into (e.g. <filename>libtcl</filename> is used both by Sybase and the language TCL), however some applications like PHP assume that all the Sybase libraries will be present. So, some hand editing of the Makefile is necessary to remove these extra libs.  Build &freetds; just as you would for <systemitem class="library">db-lib</systemitem> in 
+ <link linkend="phpDblib"> with <systemitem class="library">db-lib</systemitem></link>, above. Then configure PHP with <systemitem class="library">ct-lib</systemitem>.
+ <screen>
+ <prompt>$ </prompt><userinput>cd php</userinput>
+@@ -2513,13 +2656,13 @@ Now edit the <filename>Zend/Makefile</filename> looking for the <literal>libZend
+ <prompt>Password: </prompt>
+ <prompt>$ </prompt><userinput>make install</userinput>
+ </screen>
+-We hope an upcoming version of PHP will automatically detect the presence of <productname>FreeTDS</productname> and include only the <literal>-lct</literal> library.
++We hope an upcoming version of PHP will automatically detect the presence of &freetds; and include only the <literal>-lct</literal> library.
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="ODBC">
+ 			<title><systemitem class="library">ODBC</systemitem></title>
+ 			<para>
+-The third and newest option is to use the <productname>FreeTDS</productname> <systemitem class="library">ODBC</systemitem> driver with PHP.  First build the <productname>iODBC</productname> or <productname>unixODBC</productname> driver manager and <productname>FreeTDS</productname> as detailed <link linkend="prepodbc">in this guide</link>.  Then build PHP with support for ODBC.
++The third and newest option is to use the &freetds; <systemitem class="library">ODBC</systemitem> driver with PHP.  First build the <productname>iODBC</productname> or <productname>unixODBC</productname> driver manager and &freetds; as detailed <link linkend="prepodbc">in this guide</link>.  Then build PHP with support for ODBC.
+ <screen>
+ <prompt>$ </prompt><userinput>cd php</userinput>
+ <prompt>$ </prompt><userinput>./configure --with-iodbc=/usr/local</userinput>
+@@ -2528,7 +2671,7 @@ The third and newest option is to use the <productname>FreeTDS</productname> <sy
+ <prompt>Password: </prompt>
+ <prompt>$ </prompt><userinput>make install</userinput>
+ </screen>
+-Now everything should run.  There is a sample PHP script in the <productname>FreeTDS</productname> samples directory called <filename>odbctest.php</filename>.
++Now everything should run.  There is a sample PHP script in the &freetds; samples directory called <filename>odbctest.php</filename>.
+ 			</para>
+ 		</sect2>
+ 		</sect1>
+@@ -2538,7 +2681,7 @@ Now everything should run.  There is a sample PHP script in the <productname>Fre
+ <productname>SybSQL</productname> is a <productname>Qt</productname>-based <acronym>GUI</> interface to <productname>Sybase</productname> databases that uses the <systemitem class="library">db-lib</systemitem> <acronym>API</>.
+ 			</para>
+ 			<para>
+-<productname>SybSQL</productname> has a fairly basic build process that simply uses a Makefile.  In order for <productname>SybSQL</productname> to find <productname>Qt</productname> and <productname>FreeTDS</productname> you need to define <envar>QTDIR</envar> and <envar>SYBASE</envar> environment variables.  If you have <productname>Qt</productname> installed, you may have <envar>QTDIR</envar> defined already.  To verify, type <command>echo $QTDIR</command> at the shell prompt.  This example uses my own installation path of <filename>qt-2.3.1</filename> (from RedHat 7.2), YMMV.
++<productname>SybSQL</productname> has a fairly basic build process that simply uses a Makefile.  In order for <productname>SybSQL</productname> to find <productname>Qt</productname> and &freetds; you need to define <envar>QTDIR</envar> and <envar>SYBASE</envar> environment variables.  If you have <productname>Qt</productname> installed, you may have <envar>QTDIR</envar> defined already.  To verify, type <command>echo $QTDIR</command> at the shell prompt.  This example uses my own installation path of <filename>qt-2.3.1</filename> (from RedHat 7.2), YMMV.
+ <screen>
+ <prompt>$ </prompt><userinput>export QTDIR=/usr/lib/qt-2.3.1</userinput>
+ <prompt>$ </prompt><userinput>export SYBASE=/usr/local</userinput>
+@@ -2547,10 +2690,10 @@ Now everything should run.  There is a sample PHP script in the <productname>Fre
+ When finished you'll have an executable named <filename>sybsql</filename> that you can run.  
+ 			</para>
+ 			<para>
+-One caveat to the way in which <productname>SybSQL</productname> and <productname>FreeTDS</productname> interact is that <productname>SybSQL</productname> expects to be running under <productname>OpenClient</productname>, and makes the assumption that a valid <envar>$SYBASE</envar><filename>/interfaces</filename> file exists.  Since <productname>FreeTDS</productname> has deprecated use of the <filename>interfaces</filename> file in favor of the <filename>freetds.conf</filename> config file, you may have to create a <filename>interfaces</> file just to satisfy <productname>SybSQL</productname>.
++One caveat to the way in which <productname>SybSQL</productname> and &freetds; interact is that <productname>SybSQL</productname> expects to be running under <productname>OpenClient</productname>, and makes the assumption that a valid <envar>$SYBASE</envar><filename>/interfaces</filename> file exists.  Since &freetds; has deprecated use of the <filename>interfaces</filename> file in favor of the &freetdsconf; config file, you may have to create a <filename>interfaces</> file just to satisfy <productname>SybSQL</productname>.
+ 			</para>
+ 			<para>
+-By defining <envar>SYBASE</envar> to the parent directory of the <filename>interfaces</filename> file, you may put it wherever you like; it does not have to be in <filename>/usr/local</filename>.  When using <filename>freetds.conf</filename>, <productname>FreeTDS</productname> does not rely on the <envar>SYBASE</envar> variable for finding its own components, so it is safe to point it elsewhere.
++By defining <envar>SYBASE</envar> to the parent directory of the <filename>interfaces</filename> file, you may put it wherever you like; it does not have to be in <filename>/usr/local</filename>.  When using &freetdsconf;, &freetds; does not rely on the <envar>SYBASE</envar> variable for finding its own components, so it is safe to point it elsewhere.
+ 			</para>
+ 		</sect1>
+ 		<sect1 id="Python">
+@@ -2607,7 +2750,7 @@ or with the newer SQL92 <command>CAST</command> syntax e.g.,
+ <userinput>SELECT CAST(mycol as TEXT) FROM mytable</userinput></screen>
+ 			</para>
+ 			<para>
+-A related problem is that some people have reported problems with <type>text</type> field using <acronym>TDS</> version 7.0.  One known workaround is to convert long strings to <type>varchar(8000)</type> in your query text with <command>CAST( <parameter>variable_name</parameter> as <type>varchar</type>(8000) ) as <parameter>variable_name</parameter></command>.  Text datatype handling is fixed in <productname>FreeTDS</productname> 0.60, except for bcp operations.  
++A related problem is that some people have reported problems with <type>text</type> field using <acronym>TDS</> version 7.0.  One known workaround is to convert long strings to <type>varchar(8000)</type> in your query text with <command>CAST( <parameter>variable_name</parameter> as <type>varchar</type>(8000) ) as <parameter>variable_name</parameter></command>.  Text datatype handling is fixed in &freetds; 0.60, except for bcp operations.  
+ 			</para>
+ 			<para>
+ There is also a bug (<quote>Lions and tigers and bugs!  Oh, my!</quote>) in Microsoft's implementation of <type>text</type> fields.  Disregardless [sic] of their documentation, you must explicitly set the value of <envar>TEXTSIZE</envar>, else the text fields will be represented to have a maximum size of 4 gigabytes or so.  The usual manifestation is some sort of spurious <quote>out of memory</quote> error or segment fault.  To avoid this, set <envar>TEXTSIZE</envar> to some reasonable value before querying any <type>TEXT</type> fields.  For example, in <application>isql</application>:
+@@ -2616,27 +2759,27 @@ There is also a bug (<quote>Lions and tigers and bugs!  Oh, my!</quote>) in Micr
+ <prompt>2></prompt><userinput>go</userinput>
+ </screen>
+ 
+-Another way to handle control the default <envar>TEXTSIZE</envar> is to use the setting in <link linkend="freetdsconfformat"><filename>freetds.conf</filename></link>.  
++Another way to handle control the default <envar>TEXTSIZE</envar> is to use the setting in <link linkend="freetdsconfformat">&freetdsconf;</link>.  
+ 			</para>
+ 			</sect2>
+ 		<sect2 id="Endianism">
+     			<title>Endianism</title>
+ 			<para>
+-If either your server or your client is a big endian system, pay careful attention to all references to endianism anywhere near <productname>FreeTDS</productname>.  See the section on <link linkend="emulle">Little Endian Emulation</link> for details.
++If either your server or your client is a big endian system, pay careful attention to all references to endianism anywhere near &freetds;.  See the section on <link linkend="emulle">Little Endian Emulation</link> for details.
+ 			</para>
+ 		</sect2>
+ 			<sect2 id="Datetime">
+ 				<title><type>Datetime</type> and <type>Money</type></title>
+ 			<para>
+ Big endian clients may experience difficulty with Microsoft servers.  Some versions of <productname>SQL Server</productname> 7 did not handle these types on these machines correctly, according to the protocol.  According to 
+-<ulink url="http://support.microsoft.com/support/kb/articles/Q254/1/23.ASP"> http://support.microsoft.com/support/kb/articles/Q254/1/23.ASP</ulink> on the Microsoft support site, it's fixed as of service pack 3.  Unfortunately, there's no direct way for <productname>FreeTDS</productname> to know whether or not a service pack has been installed, and how/whether to support the buggy version is an outstanding issue.  Your best bet is to apply their patch.  
++<ulink url="http://support.microsoft.com/support/kb/articles/Q254/1/23.ASP"> http://support.microsoft.com/support/kb/articles/Q254/1/23.ASP</ulink> on the Microsoft support site, it's fixed as of service pack 3.  Unfortunately, there's no direct way for &freetds; to know whether or not a service pack has been installed, and how/whether to support the buggy version is an outstanding issue.  Your best bet is to apply their patch.  
+ 		<note><para>The Knowledge Base article states <quote>The Sybase CT-Lib client is the only known big-endian client that can connect to <productname>SQL Server</productname>.</quote>  Depends on who's doing the knowing, of course.  </para></note>
+ 			</para>
+ 			</sect2>
+ 			<sect2 id="IntegratedSecurity">
+ 				<title>Microsoft's <quote>Integrated Security</quote></title>
+ 			<para>
+-<productname>FreeTDS</productname> may be unable to connect to the server.  The error message that appears will be <computeroutput>"Login failed for user 'example'.  Reason: Not associated with a trusted SQL Server connection"</computeroutput>.  To solve this, turn on <productname>SQL Server</productname> authentication:
++&freetds; may be unable to connect to the server.  The error message that appears will be <computeroutput>"Login failed for user 'example'.  Reason: Not associated with a trusted SQL Server connection"</computeroutput>.  To solve this, turn on <productname>SQL Server</productname> authentication:
+ </para>
+ 			<ItemizedList>
+ 				<listitem><para>
+@@ -2684,10 +2827,10 @@ Server</productname> uses the facilities of the host operating system (<productn
+ username alone, without requiring a separate login name and password.
+ 			</para>
+ <Note><para>
+-The <productname>FreeTDS</productname> supports integrated security mode.  If you have <productname>SQL Server</productname> running in integrated (domain) mode along with a Windows PDC, and wish to try it, see <link linkend="domains">Domain Logins</link> in the <link linkend="configs">Advanced Configurations</link> chapter.
++The &freetds; supports integrated security mode.  If you have <productname>SQL Server</productname> running in integrated (domain) mode along with a Windows PDC, and wish to try it, see <link linkend="domains">Domain Logins</link> in the <link linkend="configs">Advanced Configurations</link> chapter.
+ </para></Note>
+ 			<para>
+-<productname>FreeTDS</productname> supports the traditional database
++&freetds; supports the traditional database
+ security model, which Microsoft terms <quote>SQL Server
+ Authentication</quote> but is frequently known as <quote>standard
+ security</quote>. Username+Password pairs have to be passed to the
+@@ -2727,7 +2870,7 @@ A successful ping shows that your network isn't preventing you from reaching the
+ 			<sect2 id="serverthere.telnet">
+ 				<title>Test with <command>telnet</></title>
+ 			<para>
+-Attempt to <command>telnet</> to the port, to verify that the dataserver is listening.
++Attempt to <command>telnet</> to the port, to verify that the servername is listening.
+ <example id="e.g.troubleshooting.telnet">
+ 	<title>Finding the server</title>
+ <screen>
+@@ -2739,7 +2882,7 @@ Escape character is '^]'.
+ </computeroutput>
+ </screen>
+ </example>
+-If you get output as above, the dataserver is listening.  If you get a 'Connection Refused' message, you're talking to the wrong host, wrong port, or the dataserver is down.
++If you get output as above, the servername is listening.  If you get a 'Connection Refused' message, you're talking to the wrong host, wrong port, or the servername is down.
+ 	<footnote><para>To exit <command>telnet</>:  When connected, telnet's command mode may be entered by
+      typing the telnet <firstterm>escape character</firstterm> (initially <keysym>Ctrl</keysym>-<keysym>]</keysym>, as above).  Once in command mode, <command>telnet</> may be exited with the command <command>quit</>.
+ 	</para></footnote>
+@@ -2748,9 +2891,9 @@ If you get output as above, the dataserver is listening.  If you get a 'Connecti
+ 			<sect2 id="serverthere.tsql">
+ 				<title>Test with <command>tsql</></title>
+ 			<para>
+-<command>tsql</> can be run in two ways, one which uses <filename>freetds.conf</> and one which connects directly using the host and port.  First attempt a connection using host and port.
++<command>tsql</> can be run in two ways, one which uses &freetdsconf; and one which connects directly using the host and port.  First attempt a connection using host and port.
+ <example id="e.g.troubleshooting.tsql.noconf">
+-	<title>Connecting to the server, bypassing <filename>freetds.conf</></title>
++	<title>Connecting to the server, bypassing &freetdsconf;</title>
+ <screen>
+ <prompt>$ </prompt><userinput>cd src/apps</userinput>
+ <prompt>$ </prompt><userinput>TDSVER=7.0 ./tsql -H <replaceable>myhost</> -p <replaceable>1433</> -U <replaceable>user</></userinput>
+@@ -2769,21 +2912,21 @@ If you receive a message like
+ 
+ 			</para>
+ 			<para>
+-Finally, if you received a prompt, then try <command>tsql</> using the dataserver name.
++Finally, if you received a prompt, then try <command>tsql</> using the servername.
+ <example id="e.g.troubleshooting.tsql">
+-	<title>Connecting to the server using <filename>freetds.conf</></title>
++	<title>Connecting to the server using &freetdsconf;</title>
+ <screen>
+ <prompt>$ </prompt><userinput>./tsql -S <replaceable>myserver</> -U <replaceable>user</></userinput>
+ </screen>
+ </example>
+-If this fails, FreeTDS is either not finding your <filename>freetds.conf</filename> file, finding the wrong one, or there is an error in the file.
++If this fails, FreeTDS is either not finding your &freetdsconf; file, finding the wrong one, or there is an error in the file.
+ 			</para>
+ 			</sect2>
+ 		</sect1>
+ 		<sect1 id="Logging">
+ 			<title>Logging</title>
+ 			<para>
+-<productname>FreeTDS</productname> has quite extensive logging capabilities.  These are often invaluable in setting up new configurations, when it's hard to be sure precisely what configuration information is being used, and what communication is (not) working.   Often such questions can be quickly resolved by turning on logging and examining the logs.  
++&freetds; has quite extensive logging capabilities.  These are often invaluable in setting up new configurations, when it's hard to be sure precisely what configuration information is being used, and what communication is (not) working.   Often such questions can be quickly resolved by turning on logging and examining the logs.  
+ 			</para>
+         		<sect2 id="Environment"><title>Environment Variables that Control Logging</title>
+ <variablelist id="tab.Logging.control.envar">
+@@ -2804,7 +2947,7 @@ Will generate a log file named <filename>freetds.log</filename> in the <filename
+ 		<listitem>
+ 			<para>Set <envar>TDSDUMPCONFIG</envar> to a file to
+ write information to on how the configuration information is being
+-obtained, e.g. from environment variables, a <filename>freetds.conf</filename> file, or <filename>interfaces</filename> file.  Sometimes it's unclear what source of information <productname>FreeTDS</productname> is using to connect to a given dataserver.  This variable can make that bright and clear.  </para>
++obtained, e.g. from environment variables, a &freetdsconf; file, or <filename>interfaces</filename> file.  Sometimes it's unclear what source of information &freetds; is using to connect to a given servername.  This variable can make that bright and clear.  </para>
+ 			
+ 		</listitem>
+ 	</varlistentry>	
+@@ -2812,32 +2955,32 @@ obtained, e.g. from environment variables, a <filename>freetds.conf</filename> f
+ 
+ 			<tip><para>
+ What if you were running <productname>Apache</productname>/PHP?  <productname>Apache</productname> has many children.
+-Setting the <envar>TDSDUMP</envar> (and/or <envar>TDSDUMPCONFIG</envar>) variable to a null string will cause <productname>FreeTDS</productname> to open a log under every PID.
++Setting the <envar>TDSDUMP</envar> (and/or <envar>TDSDUMPCONFIG</envar>) variable to a null string will cause &freetds; to open a log under every PID.
+ <screen>
+ <prompt>$ </prompt><userinput>export TDSDUMP=""</userinput>
+ </screen>
+ The log files will be named <filename>/tmp/freetds.log.<replaceable>9999</replaceable></filename>, where <replaceable>9999</replaceable> is the pid number of the process generating the log.
+ 			</para></tip>
+ 			<para>
+-A couple of important notes about using the logs with <productname>FreeTDS</productname>.  First,
++A couple of important notes about using the logs with &freetds;.  First,
+ the logs tend to grow large, so trim or archive them often.  Secondly,
+-<productname>FreeTDS</productname> will record certain network packets to the log, this
++&freetds; will record certain network packets to the log, this
+ <emphasis>includes login packets which can contain clear text or clear text
+ equivalent passwords.</emphasis> So, if this is a concern (most likely
+ is) make sure that the files are not world readable, and avoid posting
+ them to mailing lists.
+ 			</para>
+ 			<para>
+-Once in a while, someone writes to the mailing list, asking why <productname>FreeTDS</productname> is so <emphasis>slow</>.  It sometimes turns out that logging was left turned on.  Don't you be the next victim!  <productname>FreeTDS</productname> logs are meant for development and debugging, not as a system monitoring tool.  
++Once in a while, someone writes to the mailing list, asking why &freetds; is so <emphasis>slow</>.  It sometimes turns out that logging was left turned on.  Don't you be the next victim!  &freetds; logs are meant for development and debugging, not as a system monitoring tool.  
+ 			</para>
+ 		        </sect2>
+         		
+ 			<sect2 id="Logging.freetds.conf">
+-			<title><filename>freetds.conf</filename> variables that Control Logging</title>
++			<title>&freetdsconf; variables that Control Logging</title>
+ 			<para>
+-			See <link linkend="tab.freetds.conf.debugflags">Valid bitmask values for <literal>debug flags</> entry in <filename>freetds.conf</filename></link>
++			See <link linkend="tab.freetds.conf.debugflags">Valid bitmask values for <literal>debug flags</> entry in &freetdsconf;</link>
+ 			</para>
+-			<para>The logfile is normally truncated each time <productname>FreeTDS</productname> connects to the server.  
++			<para>The logfile is normally truncated each time &freetds; connects to the server.  
+ 			</para>
+ 		        
+ 			</sect2>
+@@ -2869,10 +3012,10 @@ Will generate a log file named <filename>sql.log</filename> in the <filename>/tm
+ 		<sect1 id="pagenodata">
+ 			<title>"Page contains no data"</title>
+ 			<para>
+-Web browsers display this error when the underlying script didn't return any information.  The error could be in any of several places, of which <productname>FreeTDS</productname> is one.  To isolate the cause, turn on enough logs to see the query, and execute the query through <application>SQSH</application>.  If that works, the problem lies further up the chain.  If it doesn't, take a look at the <link linkend="knownissues">known issues</link> section.  
++Web browsers display this error when the underlying script didn't return any information.  The error could be in any of several places, of which &freetds; is one.  To isolate the cause, turn on enough logs to see the query, and execute the query through <application>SQSH</application>.  If that works, the problem lies further up the chain.  If it doesn't, take a look at the <link linkend="knownissues">known issues</link> section.  
+ 			</para>
+ 			<para>
+-<productname>FreeTDS</productname> under PHP executing within an <productname>Apache</productname> process may abort with a segmentation fault.  The evidence of this is the words "Segmentation Fault" or "Bus Error" in the <productname>Apache</productname> error log, and a "Page contains no data" warning displayed by the web browser.  The unexpected termination of the process causes the connection to the client to be closed before any buffered data is sent.
++&freetds; under PHP executing within an <productname>Apache</productname> process may abort with a segmentation fault.  The evidence of this is the words "Segmentation Fault" or "Bus Error" in the <productname>Apache</productname> error log, and a "Page contains no data" warning displayed by the web browser.  The unexpected termination of the process causes the connection to the client to be closed before any buffered data is sent.
+ 			</para>
+ 			<para>
+ To diagnose this sort of problem, follow this procedure;
+@@ -2929,7 +3072,7 @@ backtrace.</para>
+ 
+ <para>Read the backtrace to determine what the cause of the problem
+ is.  Examine each line, assigning responsibility by component; some
+-code is PHP, some is <productname>FreeTDS</productname>, and some may be glibc.  You will need
++code is PHP, some is &freetds;, and some may be glibc.  You will need
+ the source code for each component, and software engineering debugging
+ skills.</para>
+ 
+@@ -2937,7 +3080,7 @@ skills.</para>
+ to the <link linkend="mailinglist">mailing list</link>, along with the
+ PHP script.  It helps to make the script as small as possible, but
+ still fail.  It also helps to report the version numbers of PHP, and
+-<productname>FreeTDS</productname>.</para>
++&freetds;.</para>
+ 
+ </listitem>
+ </itemizedlist>
+@@ -2946,15 +3089,15 @@ still fail.  It also helps to report the version numbers of PHP, and
+ 		<sect1 id="seemtooslow">
+ 			<title>Slow connection or data retrieval</title>
+ 			<para>
+-<productname>FreeTDS</productname> is <emphasis>not</> slow.  We know this because we've tested it.  It's measurably slower than the vendors' products for some operations, but it's not noticeably slower and it's certainly no laggard.  If your experience is different, if you're waiting 30 seconds for simple operations or minutes instead of seconds for for query results, something is up with your setup.  There are two likely culprits.  
++&freetds; is <emphasis>not</> slow.  We know this because we've tested it.  It's measurably slower than the vendors' products for some operations, but it's not noticeably slower and it's certainly no laggard.  If your experience is different, if you're waiting 30 seconds for simple operations or minutes instead of seconds for for query results, something is up with your setup.  There are two likely culprits.  
+ 		</para>
+ 
+ <itemizedlist mark='bullet'>
+ 	<listitem>
+-		<para>Logging.  If everything seems a bit sluggish, check to make sure logging is turned off. <envar>TDSDUMP</> should not be defined, and there should be no <literal>dump file</>  mentioned in <filename>freetds.conf</>.  You can double-check by setting <envar>TDSDUMPCONFIG</> temporarily, which will log only the startup process. </para>
++		<para>Logging.  If everything seems a bit sluggish, check to make sure logging is turned off. <envar>TDSDUMP</> should not be defined, and there should be no <literal>dump file</>  mentioned in &freetdsconf;.  You can double-check by setting <envar>TDSDUMPCONFIG</> temporarily, which will log only the startup process. </para>
+ 	</listitem>
+ 	<listitem>
+-		<para>DNS.  If connecting to the server takes 30 seconds or 1 minute, you could do worse than to check your <filename>resolv.conf</>.  Use <command>host</> or <command>nslookup</> to confirm that <productname>FreeTDS</productname> can actually resolve the name/address you provided in <filename>freetds.conf</>.  Give particular attention to reverse DNS lookups, if you were forced (or thought you were forced) to identify the server by number, instead of by name, as Vint intended.  You can defeat <productname>FreeTDS</productname>'s automatic reverse-DNS lookup feature by inserting
++		<para>DNS.  If connecting to the server takes 30 seconds or 1 minute, you could do worse than to check your <filename>resolv.conf</>.  Use <command>host</> or <command>nslookup</> to confirm that &freetds; can actually resolve the name/address you provided in &freetdsconf;.  Give particular attention to reverse DNS lookups, if you were forced (or thought you were forced) to identify the server by number, instead of by name, as Vint intended.  You can defeat &freetds;'s automatic reverse-DNS lookup feature by inserting
+ 		<programlisting>
+ 		#define NOREVERSELOOKUPS
+ 		</programlisting>
+@@ -2963,7 +3106,7 @@ in <filename>src/tds/config.c</>, rebuilding, and reinstalling.
+ 		</para>
+ 	</listitem>
+ 	<listitem>
+-		<para>Packet size.  Check packet size setting on <filename>freetds.conf</> (see <literal>initial block size</>). Default value (no configuration) is usually fine. The slowness is due to multiple packet to use. 
++		<para>Packet size.  Check packet size setting on &freetdsconf; (see <literal>initial block size</>). Default value (no configuration) is usually fine. The slowness is due to multiple packet to use. 
+ 		Under <productname><acronym>GNU</>/Linux</productname> system we use an optimization to reduce network traffic so you shouldn't see much difference using this system. </para>
+ 	</listitem>
+ </itemizedlist>
+@@ -2982,7 +3125,7 @@ in <filename>src/tds/config.c</>, rebuilding, and reinstalling.
+ 	Won't you please, please help me?
+ </literallayout></para>
+ </epigraph>
+-			<para>In the battle against frustration and wasted motion, this manual is our first defense.  Our documentation is intended to make it possible for a knowledgeable user to, well, <emphasis>use</> <productname>FreeTDS</productname> without further assistance.  We strive to include all known features and behaviors here, so you can work quickly and anonymously, and go home before 5:00.  Would that it were always thus.  
++			<para>In the battle against frustration and wasted motion, this manual is our first defense.  Our documentation is intended to make it possible for a knowledgeable user to, well, <emphasis>use</> &freetds; without further assistance.  We strive to include all known features and behaviors here, so you can work quickly and anonymously, and go home before 5:00.  Would that it were always thus.  
+ 			</para>
+ 			
+ 		<sect1 id="IsolateCause"><title>Isolate the cause</title>
+@@ -2990,16 +3133,16 @@ in <filename>src/tds/config.c</>, rebuilding, and reinstalling.
+ Successful problem isolation will yield earliest resolution.  You (believe it or not) have more information about your environment than anyone else does, and have the greatest motivation to solve your problem.  The resources at your disposal will be much more useful if the problem is specific.  (Sorry if this is obvious.  If it is, you might be surprised how often it's not.)
+ 			</para>
+ 			<para>
+-If you can demonstrate the problem with <command>tsql</> or <command>sqsh</>, you can expect a quick answer to your question, possibly even a fairly quick fix.  (It has happened several times in the last few years that bug reports to small problems were fixed the same day.  On a few occasions, new functions were added in a few days.  Making <productname>FreeTDS</productname> useful and bugless is the goal of the project, after all.)  
++If you can demonstrate the problem with <command>tsql</> or <command>sqsh</>, you can expect a quick answer to your question, possibly even a fairly quick fix.  (It has happened several times in the last few years that bug reports to small problems were fixed the same day.  On a few occasions, new functions were added in a few days.  Making &freetds; useful and bugless is the goal of the project, after all.)  
+ 			</para>
+ 			<para>
+-<productname>FreeTDS</productname> being what it is, problems frequently arise amidst complex environments.  It can be hard for both you and the list participants &mdash; who are your allies and best resource &mdash; to determine what's going wrong.  If you can submit a script that they can use to try to reproduce your results, you have a much better chance of happy resolution.  
++&freetds; being what it is, problems frequently arise amidst complex environments.  It can be hard for both you and the list participants &mdash; who are your allies and best resource &mdash; to determine what's going wrong.  If you can submit a script that they can use to try to reproduce your results, you have a much better chance of happy resolution.  
+ 			</para>
+ 			<para>
+-On the plus side, the list includes people with a variety of backgrounds, who frequently answer questions that aren't really about <productname>FreeTDS</productname> <foreignphrase>per se</foreignphrase>.  Clear questions have sometimes even led to submitting patches to other projects.  
++On the plus side, the list includes people with a variety of backgrounds, who frequently answer questions that aren't really about &freetds; <foreignphrase>per se</foreignphrase>.  Clear questions have sometimes even led to submitting patches to other projects.  
+ 			</para>
+ 		<sect2 id="help.otherclient"><title>Try a different client</>
+-			<para><productname>FreeTDS</productname> comes with its own utilities that use the various libraries.  It's a good idea to run your query through one of them &mdash; the one that uses the same API you're using &mdash; to see if it produces the same behavior you're seeing.  That helps eliminate your application (and the rest of the calling hierarchy) as a source of the problem.  </para>
++			<para>&freetds; comes with its own utilities that use the various libraries.  It's a good idea to run your query through one of them &mdash; the one that uses the same API you're using &mdash; to see if it produces the same behavior you're seeing.  That helps eliminate your application (and the rest of the calling hierarchy) as a source of the problem.  </para>
+ 		</sect2>
+ 		
+ 		</sect1>
+@@ -3015,9 +3158,9 @@ On the plus side, the list includes people with a variety of backgrounds, who fr
+  		
+ 		<sect2 id="Archive"><title>The Archive</title>
+ 			
+-			<para>The <productname>FreeTDS</productname> mailing list <ulink url="http://lists.ibiblio.org/pipermail/freetds/">archive</ulink> is a good place to start.  It is searchable.  It should be considered the most up to date (and least edited) source of information.  
++			<para>The &freetds; mailing list <ulink url="http://lists.ibiblio.org/pipermail/freetds/">archive</ulink> is a good place to start.  It is searchable.  It should be considered the most up to date (and least edited) source of information.  
+ 			</para>
+-			<para>New developments between releases tend <emphasis>not</> to be announced on the website.  The website is updated only intermittently, when we post a new release or <productname>FreeTDS</productname> is somehow in the news, say.  If you found a bug or need a feature, you may find it was announced/discussed/fixed by perusing the archive.  
++			<para>New developments between releases tend <emphasis>not</> to be announced on the website.  The website is updated only intermittently, when we post a new release or &freetds; is somehow in the news, say.  If you found a bug or need a feature, you may find it was announced/discussed/fixed by perusing the archive.  
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="Asklist">
+@@ -3038,7 +3181,7 @@ Many of the original authors and anyone maintaining or extending the code reads
+ 			<para>It's important to convey your setup and configuration.  
+ <simplelist type='vert' columns='1'>
+ 	<member><productname>SQL Server</productname> version</member>
+-	<member><productname>FreeTDS</productname> version (or snapshot date, if not a release)</member>
++	<member>&freetds; version (or snapshot date, if not a release)</member>
+ 	<member>which client library you are using</member>
+ 	<member>what language or Perl module, as appropriate, you're using</member>
+ 	<member>your client OS and hardware architecture</member>
+@@ -3062,7 +3205,7 @@ Moving down, Perl or PHP code provided it creates all the tables it needs and po
+ 			<tip><para>If you provide an SQL query in your question to the list, provide a table definition, too.  Problems are often related to specific datatypes, so a table definition is an absolute must.  You can run <command>sp_help <parameter>table</parameter></command> to generate one.  </para></tip>
+ 			</para>
+ 			<para>
+-It is very helpful if you can show an example of the problem using <command>sqsh</> or an appropriate <link linkend="utilities">utility</>.  Using those programs limits the scope of question to <productname>FreeTDS</productname> itself.  
++It is very helpful if you can show an example of the problem using <command>sqsh</> or an appropriate <link linkend="utilities">utility</>.  Using those programs limits the scope of question to &freetds; itself.  
+ 			</para>
+ <para>If the problem is a segmentation fault or bus error, that's bad.  Please obtain a
+ backtrace and include it in your mail.  See the <link
+@@ -3082,7 +3225,7 @@ do this.</para>
+ </para>
+ </epigraph>
+ 		<para>
+-<productname>FreeTDS</productname> is a cooperative, volunteer effort.  Flame wars on the list are unknown and the signal to noise ratio is pretty high for its venue.  Many people have contributed patches, and few have been turned away.  
++&freetds; is a cooperative, volunteer effort.  Flame wars on the list are unknown and the signal to noise ratio is pretty high for its venue.  Many people have contributed patches, and few have been turned away.  
+ 		</para>
+ 		<sect1 id="Pickweakspot">
+ 			<title>Pick a weak spot and fix it.</title>
+@@ -3103,13 +3246,13 @@ do this.</para>
+ 		<sect2 id="Sendpatch">
+     			<title>Send a patch</title>
+ 			<para>
+-Good patches are nearly always applied in short order.  Patches uploaded to <ulink url="http://sourceforge.net/tracker/?group_id=33106&amp;atid=407808">SourceForge</ulink> trigger automatic notification to the <productname>FreeTDS</productname>  mailing list.  
++Good patches are nearly always applied in short order.  Patches uploaded to <ulink url="http://sourceforge.net/tracker/?group_id=33106&amp;atid=407808">SourceForge</ulink> trigger automatic notification to the &freetds;  mailing list.  
+ 			</para>
+ 		</sect2>
+ 		<sect2 id="Correct">
+     			<title>Correct this User Guide</title>
+ 			<para>
+-Any corrections or suggestions, be they typographical, grammatical, structural, factual, or mineral are most  welcome.  Please send it to <ulink url="mailto:jklowden@freetds.org"><productname>FreeTDS</productname> FAQ Master</ulink>, or post a message to the list.  
++Any corrections or suggestions, be they typographical, grammatical, structural, factual, or mineral are most  welcome.  Please send it to <ulink url="mailto:jklowden@freetds.org">&freetds; FAQ Master</ulink>, or post a message to the list.  
+ 			</para>
+ 			<para>
+ The User Guide is maintained in <acronym>SGML</> DocBook format; the file in your distibution is  <filename>doc/userguide.sgml</>.  It is a flat ASCII file that you can edit with any text editor.  You don't have to know <acronym>SGML</> to correct or add to the User Guide, however.  Just open it up, find the place you're interested in, and type away.  Do a <command>diff -u <replaceable>old_version</> <replaceable>your_version</></command> and post your patch to the SourceForge site.  Any errors or lackings in your markup will be graciously emended by yours truly.  
+@@ -3118,7 +3261,7 @@ The User Guide is maintained in <acronym>SGML</> DocBook format; the file in you
+ 		<sect2 id="Documentapi">
+     			<title>Document an <acronym>API</></title>
+ 			<para>
+-We have just begun an independent reference manual to <productname>FreeTDS</productname>; the main <acronym>API</> documents are the work of the server vendors.  We're using <ulink url="http://www.stack.nl/~dimitri/doxygen/">Doxygen</>, which extracts documentation directly from comments in the source code, and we're maybe 25% done. 
++We have just begun an independent reference manual to &freetds;; the main <acronym>API</> documents are the work of the server vendors.  We're using <ulink url="http://www.stack.nl/~dimitri/doxygen/">Doxygen</>, which extracts documentation directly from comments in the source code, and we're maybe 25% done. 
+ 			</para>
+ 			<para>
+ The <acronym>TDS</> protocol is partly documented, as are the <acronym>API</>s to <filename>libtds</filename> and <systemitem class="library">db-lib</>, but much remains.  
+@@ -3134,10 +3277,10 @@ The FAQ and in particular the news don't get updated often enough.  If that's yo
+ 		<sect1 id="Advocacy">
+     			<title>Advocacy</title>
+ 			<para>
+-Out of ten people you know, it's a fair bet 10 never heard of <productname>FreeTDS</productname> and nine don't understand the problem it solves.  Lots of places have begun to use Microsoft <productname>SQL Server</productname>s in all sorts of ways, and if you adhere to the Microsoft line, there's only one way to connect to them: from a Microsoft OS.  
++Out of ten people you know, it's a fair bet 10 never heard of &freetds; and nine don't understand the problem it solves.  Lots of places have begun to use Microsoft <productname>SQL Server</productname>s in all sorts of ways, and if you adhere to the Microsoft line, there's only one way to connect to them: from a Microsoft OS.  
+ 			</para>
+ 			<para>
+-What can <productname>FreeTDS</productname> do that can't be done any other way?  Glad you asked.  <productname>FreeTDS</productname> can
++What can &freetds; do that can't be done any other way?  Glad you asked.  &freetds; can
+ 			</para>
+ <ItemizedList>
+ 	<listitem><para>Connect to every version of either vendor's server, using the same binaries.</para></listitem>
+@@ -4051,22 +4194,22 @@ err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr,
+ 		<sect1 id="interfacesorigin">
+ 			<title>Where it came from</title>
+ 			<para>
+-Under Sybase OpenClient there is a file called <filename>interfaces</filename> that defines servers available to the software.  <productname>FreeTDS</productname> inherited this file structure with minor alterations.  The <filename>interfaces</filename> remains supported for backward compatibility, and for those running in a mixed <productname>FreeTDS</productname>/Sybase environment.
++Under Sybase OpenClient there is a file called <filename>interfaces</filename> that defines servers available to the software.  &freetds; inherited this file structure with minor alterations.  The <filename>interfaces</filename> remains supported for backward compatibility, and for those running in a mixed &freetds;/Sybase environment.
+ 			</para>
+ 			<para>
+-The <filename>interfaces</filename> is not read by <productname>FreeTDS</productname> unless it does not find <filename>freetds.conf</filename>.  Note also that <command>make install</command> will install a skeleton <filename>freetds.conf</filename>, which you'll have to remove if you want to use <filename>interfaces</filename> instead.  
++The <filename>interfaces</filename> is not read by &freetds; unless it does not find &freetdsconf;.  Note also that <command>make install</command> will install a skeleton &freetdsconf;, which you'll have to remove if you want to use <filename>interfaces</filename> instead.  
+ 			</para>
+ 		</sect1>
+ 		<sect1 id="interfaceslocation">
+ 			<title>Where it goes</title>
+ 			<para>
+-Anywhere.  The <envar>SYBASE</envar> environment variable must contain the location of  <filename>interfaces</filename>; that is how <productname>FreeTDS</productname> will find it.  
++Anywhere.  The <envar>SYBASE</envar> environment variable must contain the location of  <filename>interfaces</filename>; that is how &freetds; will find it.  
+ 			</para>
+ 		</sect1>
+ 		<sect1 id="interfacespurpose">
+ 			<title>What it does</title>
+ 			<para>
+-The <filename>interfaces</filename> file aliases a dataserver name to the hostname and port number of the dataserver's machine.  When <productname>FreeTDS</productname> receives a request to connect to a database server, it looks up the dataserver name in <filename>interfaces</filename>.  There, it finds the machine name (or address) and port number to connect to, that is, the port where the database server is listening.  
++The <filename>interfaces</filename> file aliases a servername to the hostname and port number of the servername's machine.  When &freetds; receives a request to connect to a database server, it looks up the servername in <filename>interfaces</filename>.  There, it finds the machine name (or address) and port number to connect to, that is, the port where the database server is listening.  
+ 			</para>
+ 
+ 			<tip><sidebar><title>How's that again?</title>
+@@ -4075,9 +4218,9 @@ The <filename>interfaces</filename> file sometimes trips people up.  It seems in
+ 			</para>
+ 
+ 			<itemizedlist mark=bullet>
+-				<listitem><para>The <emphasis>dataserver name</emphasis> is the name of the database server.  When a database client specifies the <quote>name of the server</quote> to connect to, it's the <emphasis>dataserver name</emphasis> that is used.  
++				<listitem><para>The <emphasis>servername</emphasis> is the name of the database server.  When a database client specifies the <quote>name of the server</quote> to connect to, it's the <emphasis>servername</emphasis> that is used.  
+ 					</para></listitem>
+-				<listitem><para>The <emphasis>host name</emphasis> is the name of the host (machine) where the database server is running.  It has an IP address, and in almost any environment, you can <command>ping</command> the machine name to see if you've got it right.  After it uses the <emphasis>dataserver name</emphasis>  to look up the <emphasis>host name</emphasis>, <productname>FreeTDS</productname> will do the same thing <command>ping</command> does to get the IP address of the machine to connect to. 
++				<listitem><para>The <emphasis>host name</emphasis> is the name of the host (machine) where the database server is running.  It has an IP address, and in almost any environment, you can <command>ping</command> the machine name to see if you've got it right.  After it uses the <emphasis>servername</emphasis>  to look up the <emphasis>host name</emphasis>, &freetds; will do the same thing <command>ping</command> does to get the IP address of the machine to connect to. 
+ 					</para></listitem>
+ 				<listitem><para>Finally, the <emphasis>port number</emphasis> is frequently overlooked.  From the network's point of view, knowing the IP address without the port number is a little like knowing the address of an apartment building without knowing the apartment number.  In both cases, it will be hard to find what you came for.  Make sure you <emphasis>know</emphasis> the port number, and that it's correctly entered in the <filename>interfaces</filename> file.  
+ 					</para></listitem>
+@@ -4102,7 +4245,7 @@ myserver
+ 			</para>
+ 			<para>
+ The entry starts with the servername beginning in the first column (no 
+-whitespace preceding it).  Following the servername are one or more services lines which <emphasis>must</emphasis> be indented with whitespace.  <productname>FreeTDS</productname> uses only the query line, although others may be present to retain compatibility with Sybase.
++whitespace preceding it).  Following the servername are one or more services lines which <emphasis>must</emphasis> be indented with whitespace.  &freetds; uses only the query line, although others may be present to retain compatibility with Sybase.
+ 
+ 			</para>
+ 			<para>
+@@ -4126,12 +4269,12 @@ The fields in the services lines are as follows.
+ 	<row>
+ 	<entry>transport</entry>
+ 	<entry>tcp</entry>
+-	<entry>The transport protocol to use.  Only tcp is supported by <productname>FreeTDS</productname>.</entry>
++	<entry>The transport protocol to use.  Only tcp is supported by &freetds;.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>physical</entry>
+ 	<entry>4.2</entry>
+-	<entry>Historically this field referred the physical/datalink layer, however it appears to simply a comment field.  Therefore, <productname>FreeTDS</productname> optionally uses it to specify the protocol version to connect with.</entry>
++	<entry>Historically this field referred the physical/datalink layer, however it appears to simply a comment field.  Therefore, &freetds; optionally uses it to specify the protocol version to connect with.</entry>
+ 	</row>
+ 	<row>
+ 	<entry>hostname/IP</entry>
+@@ -4148,13 +4291,13 @@ The fields in the services lines are as follows.
+ </table>
+ 			</para>
+ 			<para>
+-In the example above, the <literal>hostname</literal> was entered as an IP address.  It needn't be; it could just as well be a name.  <productname>FreeTDS</productname> can use a name rather than an address; it will just let the network (specifically, the <application>resolver</application> get the address.   
++In the example above, the <literal>hostname</literal> was entered as an IP address.  It needn't be; it could just as well be a name.  &freetds; can use a name rather than an address; it will just let the network (specifically, the <application>resolver</application> get the address.   
+ 			</para>
+ 		</sect1>
+ 	</Appendix>
+ 	<Appendix id="AboutUnicode"><title>About Unicode, UCS-2, and UTF-8</title>
+ 			<para>
+-For better or worse, <productname>FreeTDS</productname> brings the otherwise innocent programmer into contact with the arcane business of how data are stored and transported.  <productname>FreeTDS</productname> is a data communications library that of course connects to databases, which are charged with storing information in a way that is neutral to all architectures and languages.  On the surface, that might not seem very complex, even worth discussing.  Under the surface, things are not so simple.  
++For better or worse, &freetds; brings the otherwise innocent programmer into contact with the arcane business of how data are stored and transported.  &freetds; is a data communications library that of course connects to databases, which are charged with storing information in a way that is neutral to all architectures and languages.  On the surface, that might not seem very complex, even worth discussing.  Under the surface, things are not so simple.  
+ 			</para>
+ 		<section id="ascii"><title><acronym>ASCII</>: What everyone knows</title>
+ 			<para>
+@@ -4247,10 +4390,10 @@ While UTF-8 solves many technical problems, it doesn't magically transform every
+ 		</section>
+ 		<section id="UnicodeFreeTDS"><title>Unicode and FreeTDS</title>
+ 			<para>
+-Microsoft servers using TDS 7.0 and above (anything since SQL Server 6.5) transmit their data in UCS-2 format (16-bit integers).  Because most applications linked to <productname>FreeTDS</productname> are not prepared to deal with UCS-2 data, <productname>FreeTDS</productname> can convert the data to something more acceptable, including <acronym>ASCII</>.  To do so, it employs an  <productname>iconv</productname>  library.  <productname>FreeTDS</productname> determines the server's encoding from the TDS protocol and information reported by the server (generally per connection, but in the case of TDS 7.1, per result set column).  It discovers the client's encoding in <filename>freetds.conf</filename>.  <productname>FreeTDS</productname> will happily convert and convey your data in any <emphasis>single-byte</emphasis> format that <productname>iconv</productname> can provide.  In practice, this normally means some form of ISO 8859-x or UTF-8.
++Microsoft servers using TDS 7.0 and above (anything since SQL Server 6.5) transmit their data in UCS-2 format (16-bit integers).  Because most applications linked to &freetds; are not prepared to deal with UCS-2 data, &freetds; can convert the data to something more acceptable, including <acronym>ASCII</>.  To do so, it employs an  <productname>iconv</productname>  library.  &freetds; determines the server's encoding from the TDS protocol and information reported by the server (generally per connection, but in the case of TDS 7.1, per result set column).  It discovers the client's encoding in &freetdsconf;.  &freetds; will happily convert and convey your data in any <emphasis>single-byte</emphasis> format that <productname>iconv</productname> can provide.  In practice, this normally means some form of ISO 8859-x or UTF-8.
+ 			</para>
+ 			<para>
+-At some future time, <productname>FreeTDS</productname> aims to support Unicode and other multi-byte character sets.  It does not do so at the current time.  
++At some future time, &freetds; aims to support Unicode and other multi-byte character sets.  It does not do so at the current time.  
+ 			</para>
+ 			<para>
+ Sybase servers, by the way, adhere to a <quote>server makes right</quote> policy: they transmit their data in whatever character set the client requested at login time.  The list of available character sets is fairly short, but includes UTF-8.  While  <productname>FreeTDS</> <emphasis>could</> convert Sybase data streams as easily as it does Microsoft data streams, to our knowledge no one is doing so.  The Sybase server can perform the conversion itself, making <productname>FreeTDS</>'s capability in this regard largely redundant and irrelevant.  
+
+commit 2db9da7f0545a94ed76103eeca43a8384053fddf
+Author: freddy77 <freddy77>
+Date:   Tue Dec 15 09:13:45 2009 +0000
+
+    Update Unixodbc configuration settings for TDS version
+
+diff --git a/ChangeLog b/ChangeLog
+index be0bf2b..07942cf 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Dec 15 10:13:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c:
++	- Update Unixodbc configuration settings for TDS version
++
+ Sun Dec 13 20:01:01 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* doc/freetds.conf.5 doc/userguide.sgml
+ 	- updated documentation in preparation for upcoming release. 
+@@ -1978,4 +1982,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2904 2009/12/14 01:02:26 jklowden Exp $
++$Id: ChangeLog,v 1.2905 2009/12/15 09:13:45 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 82f1194..f7739f2 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.77 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.78 2009/12/15 09:13:46 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -514,7 +514,8 @@ static const char *const aTDSver[] = {
+ 	"4.2",
+ 	"5.0",
+ 	"7.0",
+-	"8.0",
++	"7.1",
++	"7.2",
+ 	NULL
+ };
+ 
+@@ -627,8 +628,9 @@ ODBCINSTGetProperties(HODBCINSTPROPERTY hLastProperty)
+ 		"The TDS protocol version.\n"
+ 		" 4.2 MSSQL 6.5 or Sybase < 10.x\n"
+ 		" 5.0 Sybase >= 10.x\n"
+-		" 7.0 MSSQL 7 or MSSQL 2000\n"
+-		" 8.0 MSSQL 2000");
++		" 7.0 MSSQL 7\n"
++		" 7.1 MSSQL 2000\n"
++		" 7.2 MSSQL 2005");
+ 
+ 	hLastProperty = definePropertyList(hLastProperty, odbc_param_Language, "us_english", (void*) aLanguage, sizeof(aLanguage),
+ 		"The default language setting.");
+
+commit 2b4e646abb110d8cb9c89dfb6969e8f35010833a
+Author: freddy77 <freddy77>
+Date:   Tue Dec 15 09:53:26 2009 +0000
+
+    Avoid wrong configuration problem reporting problems
+
+diff --git a/ChangeLog b/ChangeLog
+index 07942cf..a2020ac 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Dec 15 10:52:43 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/connectparams.c src/odbc/odbc.c:
++	- Avoid wrong configuration problem reporting problems
++
+ Tue Dec 15 10:13:12 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c:
+ 	- Update Unixodbc configuration settings for TDS version
+@@ -1982,4 +1986,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2905 2009/12/15 09:13:45 freddy77 Exp $
++$Id: ChangeLog,v 1.2906 2009/12/15 09:53:26 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 3997a0e..231008d 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.113 2008/10/23 15:07:48 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.114 2009/12/15 09:53:27 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -433,8 +433,8 @@ BOOL get_login_info(HWND hwndParent, TDSCONNECTION * connection);
+  * \param connection          structure where to store informations
+  * \return 0 if error, 1 otherwise
+  */
+-int odbc_parse_connect_string(const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection);
+-int odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection);
++int odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection);
++int odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection);
+ 
+ /*
+  * convert_tds2sql.c
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index f7739f2..99ead31 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.78 2009/12/15 09:13:46 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.79 2009/12/15 09:53:27 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -111,20 +111,24 @@ static int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR
+ #endif
+ 
+ static int
+-parse_server(char *server, TDSCONNECTION * connection)
++parse_server(TDS_DBC *dbc, char *server, TDSCONNECTION * connection)
+ {
+ 	char ip[64];
+ 	char *p = (char *) strchr(server, '\\');
+ 
+ 	if (p) {
+-		if (!tds_dstr_copy(&connection->instance_name, p+1))
++		if (!tds_dstr_copy(&connection->instance_name, p+1)) {
++			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			return 0;
++		}
+ 		*p = 0;
+ 	}
+ 
+ 	tds_lookup_host(server, ip);
+-	if (!tds_dstr_copy(&connection->ip_addr, ip))
++	if (!tds_dstr_copy(&connection->ip_addr, ip)) {
++		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		return 0;
++	}
+ 
+ 	return 1;
+ }
+@@ -143,21 +147,30 @@ myGetPrivateProfileString(const char *DSN, const char *key, char *buf)
+  * @return 1 if success 0 otherwhise
+  */
+ int
+-odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection)
++odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection)
+ {
+ 	char tmp[FILENAME_MAX];
+ 	int freetds_conf_less = 1;
+-	int address_specified = 0;
+ 
+ 	/* use old servername */
+ 	if (myGetPrivateProfileString(DSN, odbc_param_Servername, tmp) > 0) {
+ 		freetds_conf_less = 0;
+ 		tds_dstr_copy(&connection->server_name, tmp);
+ 		tds_read_conf_file(connection, tmp);
++		if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
++			odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
++			return 0;
++		}
++		if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
++			odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS");
++			return 0;
++		}
+ 	}
+ 
+ 	/* search for server (compatible with ms one) */
+ 	if (freetds_conf_less) {
++		int address_specified = 0;
++
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
+ 			address_specified = 1;
+ 			/* TODO parse like MS */
+@@ -167,7 +180,7 @@ odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection)
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
+ 			tds_dstr_copy(&connection->server_name, tmp);
+ 			if (!address_specified) {
+-				if (!parse_server(tmp, connection))
++				if (!parse_server(dbc, tmp, connection))
+ 					return 0;
+ 			}
+ 		}
+@@ -218,11 +231,12 @@ odbc_get_dsn_info(const char *DSN, TDSCONNECTION * connection)
+  * @return 1 if success 0 otherwhise
+  */
+ int
+-odbc_parse_connect_string(const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection)
++odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection)
+ {
+ 	const char *p, *end;
+ 	DSTR *dest_s, value;
+-	int reparse = 0;	/* flag for indicate second parse of string */
++	enum { CFG_DSN = 1, CFG_SERVER = 2, CFG_SERVERNAME = 4 };
++	unsigned int cfgs = 0;	/* flags for indicate second parse of string */
+ 	char option[16];
+ 
+ 	tds_dstr_init(&value);
+@@ -266,31 +280,52 @@ odbc_parse_connect_string(const char *connect_string, const char *connect_string
+ 		if (!end)
+ 			end = connect_string_end;
+ 
+-		if (!tds_dstr_copyn(&value, p, end - p))
++		if (!tds_dstr_copyn(&value, p, end - p)) {
++			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			return 0;
++		}
+ 
+ 		if (strcasecmp(option, "SERVER") == 0) {
+-			/* ignore if servername or DSN specified */
+-			if (!reparse) {
++			/* error if servername or DSN specified */
++			if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
++				tds_dstr_free(&value);
++				odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				return 0;
++			}
++			if (!cfgs) {
+ 				dest_s = &connection->server_name;
+ 				/* not that safe cast but works -- freddy77 */
+-				if (!parse_server((char *) tds_dstr_cstr(&value), connection)) {
++				if (!parse_server(dbc, (char *) tds_dstr_cstr(&value), connection)) {
+ 					tds_dstr_free(&value);
+ 					return 0;
+ 				}
++				cfgs = CFG_SERVER;
+ 			}
+ 		} else if (strcasecmp(option, "SERVERNAME") == 0) {
+-			if (!reparse) {
++			if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
++				tds_dstr_free(&value);
++				odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				return 0;
++			}
++			if (!cfgs) {
+ 				tds_dstr_dup(&connection->server_name, &value);
+ 				tds_read_conf_file(connection, tds_dstr_cstr(&value));
+-				reparse = 1;
++				cfgs = CFG_SERVERNAME;
+ 				p = connect_string;
+ 				continue;
+ 			}
+ 		} else if (strcasecmp(option, "DSN") == 0) {
+-			if (!reparse) {
+-				odbc_get_dsn_info(tds_dstr_cstr(&value), connection);
+-				reparse = 1;
++			if ((cfgs & (CFG_SERVER|CFG_SERVERNAME)) != 0) {
++				tds_dstr_free(&value);
++				odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				return 0;
++			}
++			if (!cfgs) {
++				if (!odbc_get_dsn_info(dbc, tds_dstr_cstr(&value), connection)) {
++					tds_dstr_free(&value);
++					return 0;
++				}
++				cfgs = CFG_DSN;
+ 				p = connect_string;
+ 				continue;
+ 			}
+@@ -344,7 +379,7 @@ odbc_parse_connect_string(const char *connect_string, const char *connect_string
+ 	}
+ 
+ 	tds_dstr_free(&value);
+-	return p != NULL;
++	return 1;
+ }
+ 
+ #if !HAVE_SQLGETPRIVATEPROFILESTRING
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 51f2693..9edba50 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.517 2009/11/29 18:56:47 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.518 2009/12/15 09:53:27 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -447,7 +447,7 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 		tds_dstr_dup(&connection->database, &dbc->attr.current_catalog);
+ 
+ 	/* parse the DSN string */
+-	odbc_parse_connect_string((const char *) szConnStrIn, (const char *) szConnStrIn + conlen, connection);
++	odbc_parse_connect_string(dbc, (const char *) szConnStrIn, (const char *) szConnStrIn + conlen, connection);
+ 
+ 	/* add login info */
+ 	if (hwnd) {
+@@ -1716,9 +1716,8 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 		tds_dstr_copy(&dbc->dsn, "DEFAULT");
+ 
+ 
+-	if (!odbc_get_dsn_info(tds_dstr_cstr(&dbc->dsn), connection)) {
++	if (!odbc_get_dsn_info(dbc, tds_dstr_cstr(&dbc->dsn), connection)) {
+ 		tds_free_connection(connection);
+-		odbc_errs_add(&dbc->errs, "IM007", "Error getting DSN information");
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+ 
+
+commit 6a2083295555b5d9774df6644b90b5dd744e15cf
+Author: freddy77 <freddy77>
+Date:   Tue Dec 15 11:23:46 2009 +0000
+
+    Fix data_type returned from statistics function
+
+diff --git a/ChangeLog b/ChangeLog
+index a2020ac..3b54ad5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Dec 15 12:23:27 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/Makefile.am:
++	* src/odbc/unittests/common.h src/odbc/unittests/stats.c:
++	- Fix data_type returned from statistics function
++
+ Tue Dec 15 10:52:43 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/connectparams.c src/odbc/odbc.c:
+ 	- Avoid wrong configuration problem reporting problems
+@@ -1986,4 +1991,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2906 2009/12/15 09:53:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2907 2009/12/15 11:23:46 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 9edba50..de28180 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.518 2009/12/15 09:53:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.519 2009/12/15 11:23:47 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -916,9 +916,10 @@ SQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbC
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName, szColumnName, cbColumnName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_sproc_columns ", 4, "O@procedure_qualifier", szCatalogName, cbCatalogName,
++		odbc_stat_execute(stmt, "sp_sproc_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4,
++				  "O@procedure_qualifier", szCatalogName, cbCatalogName,
+ 				  "P@procedure_owner", szSchemaName, cbSchemaName, "P@procedure_name", szProcName, cbProcName,
+-				  "P@column_name", szColumnName, cbColumnName);
++				  "P@column_name", szColumnName, cbColumnName, "V@ODBCVer", (char*) NULL, 0);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "PROCEDURE_CAT");
+ 		odbc_col_setname(stmt, 2, "PROCEDURE_SCHEM");
+@@ -4531,9 +4532,10 @@ SQLColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName,	/* object_qualifier */
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName, szColumnName, cbColumnName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_columns ", 4, "P@table_name", szTableName, cbTableName, "P@table_owner", szSchemaName,
++		odbc_stat_execute(stmt, "sp_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4,
++				  "P@table_name", szTableName, cbTableName, "P@table_owner", szSchemaName,
+ 				  cbSchemaName, "O@table_qualifier", szCatalogName, cbCatalogName, "P@column_name", szColumnName,
+-				  cbColumnName);
++				  cbColumnName, "V@ODBCVer", (char*) NULL, 0);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "TABLE_CAT");
+ 		odbc_col_setname(stmt, 2, "TABLE_SCHEM");
+@@ -6384,9 +6386,10 @@ SQLSpecialColumns(SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR FAR * szCatalog
+ 		col_type = 'V';
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_special_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 6 : 4, "O", szTableName,
++		odbc_stat_execute(stmt, "sp_special_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 7 : 4, "O", szTableName,
+ 				  cbTableName, "O", szSchemaName, cbSchemaName, "O@qualifier", szCatalogName, cbCatalogName,
+-				  "@col_type", &col_type, 1, "@scope", &scope, 1, "@nullable", &nullable, 1);
++				  "@col_type", &col_type, 1, "@scope", &scope, 1, "@nullable", &nullable, 1,
++				  "V@ODBCVer", (char*) NULL, 0);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 5, "COLUMN_SIZE");
+ 		odbc_col_setname(stmt, 6, "BUFFER_LENGTH");
+@@ -6781,6 +6784,8 @@ odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...)
+ 		p = va_arg(marker, char *);
+ 
+ 		switch (*p) {
++		case 'V':	/* ODBC version */
++			len += strlen(p) + 3;
+ 		case 'O':	/* ordinary arguments */
+ 		case 'P':	/* pattern value arguments */
+ 			params[i].type = *p++;
+@@ -6821,14 +6826,17 @@ odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...)
+ 	strcpy(p, begin);
+ 	p += strlen(begin);
+ 	for (i = 0; i < nparams; ++i) {
+-		if (!params[i].value)
++		if (!params[i].value && params[i].type != 'V')
+ 			continue;
+ 		if (params[i].name[0]) {
+ 			strcpy(p, params[i].name);
+ 			p += strlen(params[i].name);
+ 			*p++ = '=';
+ 		}
+-		p += odbc_quote_metadata(stmt->dbc, params[i].type, p, params[i].value, params[i].len);
++		if (params[i].type != 'V')
++			p += odbc_quote_metadata(stmt->dbc, params[i].type, p, params[i].value, params[i].len);
++		else
++			*p++ = (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) ? '3': '2';
+ 		*p++ = ',';
+ 	}
+ 	*--p = '\0';
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 6df8c3f..5edf080 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.80 2009/02/11 14:40:15 freddy77 Exp $
++# $Id: Makefile.am,v 1.81 2009/12/15 11:23:47 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -22,7 +22,8 @@ TESTS		=	\
+ 			cursor3$(EXEEXT) cursor4$(EXEEXT) cursor5$(EXEEXT) \
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+ 			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT) \
+-			cursor6$(EXEEXT) cursor7$(EXEEXT) utf8$(EXEEXT) utf8_2$(EXEEXT)
++			cursor6$(EXEEXT) cursor7$(EXEEXT) utf8$(EXEEXT) utf8_2$(EXEEXT) \
++			stats$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -89,6 +90,7 @@ cursor6_SOURCES	= cursor6.c common.c common.h
+ cursor7_SOURCES	= cursor7.c common.c common.h
+ utf8_SOURCES	= utf8.c common.c common.h
+ utf8_2_SOURCES	= utf8_2.c common.c common.h
++stats_SOURCES	= stats.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 35ed75c..cbf0104 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.28 2008/12/03 12:55:52 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.29 2009/12/15 11:23:47 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -140,6 +140,10 @@ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 	CHKR2(SQLSetStmtOption, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
+ #define CHKTables(a,b,c,d,e,f,g,h,res) \
+ 	CHKR2(SQLTables, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++#define CHKProcedureColumns(a,b,c,d,e,f,g,h,res) \
++	CHKR2(SQLProcedureColumns, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++#define CHKColumns(a,b,c,d,e,f,g,h,res) \
++	CHKR2(SQLColumns, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
+ 
+ int Connect(void);
+ int Disconnect(void);
+diff --git a/src/odbc/unittests/stats.c b/src/odbc/unittests/stats.c
+new file mode 100644
+index 0000000..0b66617
+--- /dev/null
++++ b/src/odbc/unittests/stats.c
+@@ -0,0 +1,110 @@
++#include "common.h"
++
++static char software_version[] = "$Id: stats.c,v 1.1 2009/12/15 11:23:47 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++static SQLLEN cnamesize;
++static char output[256];
++
++static void
++ReadCol(int i)
++{
++	memset(output, 'x', sizeof(output));
++	strcpy(output, "NULL");
++	CHKGetData(i, SQL_C_CHAR, output, sizeof(output), &cnamesize, "S");
++}
++
++static const char *catalog = NULL;
++static const char *schema = NULL;
++static const char *proc = "stat_proc";
++static const char *table = "stat_proc";
++static const char *column = "@t";
++
++#define LEN(x) (x) ? strlen(x) : SQL_NULL_DATA
++
++static void
++TestProc(const char *type, const char *expected)
++{
++	char sql[256];
++
++	Command("IF OBJECT_ID('stat_proc') IS NOT NULL DROP PROC stat_proc");
++
++	sprintf(sql, "CREATE PROC stat_proc(@t %s) AS RETURN 0", type);
++	Command(sql);
++
++	column = "@t";
++	CHKProcedureColumns((SQLCHAR *) catalog, LEN(catalog), (SQLCHAR *) schema, LEN(schema), (SQLCHAR *) proc, LEN(proc), (SQLCHAR *) column, LEN(column), "SI");
++
++	CHKFetch("SI");
++
++	ReadCol(6);
++	if (strcmp(output, expected) != 0) {
++		fprintf(stderr, "Got \"%s\" expected \"%s\"\n", output, expected);
++		Disconnect();
++		exit(1);
++	}
++
++	CHKCloseCursor("SI");
++}
++
++static void
++TestTable(const char *type, const char *expected)
++{
++	char sql[256];
++
++	Command("IF OBJECT_ID('stat_t') IS NOT NULL DROP TABLE stat_t");
++
++	sprintf(sql, "CREATE TABLE stat_t(t %s)", type);
++	Command(sql);
++
++	column = "t";
++	table = "stat_t";
++	CHKColumns((SQLCHAR *) catalog, LEN(catalog), (SQLCHAR *) schema, LEN(schema), (SQLCHAR *) table, LEN(table), (SQLCHAR *) column, LEN(column), "SI");
++
++	CHKFetch("SI");
++
++	ReadCol(5);
++	if (strcmp(output, expected) != 0) {
++		fprintf(stderr, "Got \"%s\" expected \"%s\"\n", output, expected);
++		Disconnect();
++		exit(1);
++	}
++
++	CHKCloseCursor("SI");
++}
++
++
++#define STR(n) str(int_buf, n)
++
++static const char *
++str(char *buf, int n)
++{
++	sprintf(buf, "%d", n);
++	return buf;
++}
++
++int
++main(int argc, char *argv[])
++{
++	char int_buf[32];
++
++	use_odbc_version3 = 0;
++	Connect();
++
++	TestProc("DATETIME", STR(SQL_TIMESTAMP));
++	TestTable("DATETIME", STR(SQL_TIMESTAMP));
++
++	Disconnect();
++
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	TestProc("DATETIME", STR(SQL_TYPE_TIMESTAMP));
++	TestTable("DATETIME", STR(SQL_TYPE_TIMESTAMP));
++
++	Disconnect();
++
++	printf("Done.\n");
++	return 0;
++}
+
+commit 1c092819de532ac599b055f4dae7422bbbaa03b5
+Author: freddy77 <freddy77>
+Date:   Tue Dec 15 11:46:39 2009 +0000
+
+    Fix compile under Windows
+
+diff --git a/ChangeLog b/ChangeLog
+index 3b54ad5..5d10067 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Dec 15 12:45:47 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c win32/winsetup.c:
++	- Fix compile under Windows
++
+ Tue Dec 15 12:23:27 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/Makefile.am:
+ 	* src/odbc/unittests/common.h src/odbc/unittests/stats.c:
+@@ -1991,4 +1995,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2907 2009/12/15 11:23:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2908 2009/12/15 11:46:39 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 99ead31..c9fbc49 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.79 2009/12/15 09:53:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.80 2009/12/15 11:46:39 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -118,7 +118,8 @@ parse_server(TDS_DBC *dbc, char *server, TDSCONNECTION * connection)
+ 
+ 	if (p) {
+ 		if (!tds_dstr_copy(&connection->instance_name, p+1)) {
+-			odbc_errs_add(&dbc->errs, "HY001", NULL);
++			if (dbc)
++				odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			return 0;
+ 		}
+ 		*p = 0;
+@@ -126,7 +127,8 @@ parse_server(TDS_DBC *dbc, char *server, TDSCONNECTION * connection)
+ 
+ 	tds_lookup_host(server, ip);
+ 	if (!tds_dstr_copy(&connection->ip_addr, ip)) {
+-		odbc_errs_add(&dbc->errs, "HY001", NULL);
++		if (dbc)
++			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		return 0;
+ 	}
+ 
+@@ -158,11 +160,13 @@ odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection)
+ 		tds_dstr_copy(&connection->server_name, tmp);
+ 		tds_read_conf_file(connection, tmp);
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
+-			odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
++			if (dbc)
++				odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
+ 			return 0;
+ 		}
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
+-			odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS");
++			if (dbc)
++				odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS");
+ 			return 0;
+ 		}
+ 	}
+@@ -281,7 +285,8 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 			end = connect_string_end;
+ 
+ 		if (!tds_dstr_copyn(&value, p, end - p)) {
+-			odbc_errs_add(&dbc->errs, "HY001", NULL);
++			if (dbc)
++				odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			return 0;
+ 		}
+ 
+@@ -289,7 +294,8 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 			/* error if servername or DSN specified */
+ 			if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+-				odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				if (dbc)
++					odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+ 				return 0;
+ 			}
+ 			if (!cfgs) {
+@@ -304,7 +310,8 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 		} else if (strcasecmp(option, "SERVERNAME") == 0) {
+ 			if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
+ 				tds_dstr_free(&value);
+-				odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				if (dbc)
++					odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+ 				return 0;
+ 			}
+ 			if (!cfgs) {
+@@ -317,7 +324,8 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 		} else if (strcasecmp(option, "DSN") == 0) {
+ 			if ((cfgs & (CFG_SERVER|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+-				odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				if (dbc)
++					odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+ 				return 0;
+ 			}
+ 			if (!cfgs) {
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index 6970710..b361af7 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -133,7 +133,7 @@ parse_wacky_dsn_string(LPCSTR attribs, DSNINFO * di)
+ 	}
+ 
+ 	/* let odbc_parse_connect_string() parse the ;-delimited version */
+-	odbc_parse_connect_string(build, build + strlen(build), di->connection);
++	odbc_parse_connect_string(NULL, build, build + strlen(build), di->connection);
+ }
+ 
+ 
+
+commit 01ca929fa2dd68bf3624c9ac2a77a37bfd93c41a
+Author: freddy77 <freddy77>
+Date:   Tue Dec 15 14:36:53 2009 +0000
+
+    fix problem with hard link
+
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 848e34c..0ac7c00 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -150,7 +150,7 @@ fi
+ 
+ # save logs for debug
+ rm -f $HOME/log_tds.txt
+-ln logs/log.txt $HOME/log_tds.txt
++ln logs/log.txt ../log_tds.txt
+ 
+ # test Perl
+ save_coverage
+
+commit a22e69ba7e5fdae320da7dec1bc4be9566f08299
+Author: freddy77 <freddy77>
+Date:   Wed Dec 16 08:22:57 2009 +0000
+
+    Fix uninitilized memory access problem
+
+diff --git a/ChangeLog b/ChangeLog
+index 5d10067..d8630e0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Dec 16 09:22:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: Fix uninitilized memory access problem
++
+ Tue Dec 15 12:45:47 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c win32/winsetup.c:
+ 	- Fix compile under Windows
+@@ -1995,4 +1998,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2908 2009/12/15 11:46:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2909 2009/12/16 08:22:57 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index d8f3e6b..ef7239e 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.357 2009/12/02 22:58:21 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.358 2009/12/16 08:22:57 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -4542,7 +4542,6 @@ RETCODE
+ dbsqlok(DBPROCESS * dbproc)
+ {
+ 	TDSSOCKET *tds;
+-	int done_flags;
+ 	TDS_INT result_type;
+ 	RETCODE return_code = SUCCEED;
+ 
+@@ -4569,6 +4568,8 @@ dbsqlok(DBPROCESS * dbproc)
+          */
+ 	for (;;) {
+ 		int tds_code;
++		int done_flags = 0;
++
+ 		/* 
+ 		 * If we hit an end token -- e.g. if the command
+ 		 * submitted returned no data (like an insert) -- then
+
+commit 1b6e9651b16579f7ba2e953299c144c0752d9be1
+Author: freddy77 <freddy77>
+Date:   Wed Dec 16 12:55:21 2009 +0000
+
+    Fix conversion for uni(var)char
+
+diff --git a/ChangeLog b/ChangeLog
+index d8630e0..2b247a0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Dec 16 13:54:52 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c: Fix conversion for uni(var)char
++
+ Wed Dec 16 09:22:41 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: Fix uninitilized memory access problem
+ 
+@@ -1998,4 +2001,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2909 2009/12/16 08:22:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2910 2009/12/16 12:55:21 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index a3d4f7b..a233a28 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.66 2009/10/01 09:48:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.67 2009/12/16 12:55:21 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -157,6 +157,10 @@ odbc_tds2sql(TDS_STMT * stmt, TDSCOLUMN *curcol, int srctype, TDS_CHAR * src, TD
+ 
+ 	if (curcol) {
+ 		if (is_blob_col(curcol)) {
++			if (srctype == SYBLONGBINARY && (
++			    curcol->column_usertype == USER_UNICHAR_TYPE ||
++			    curcol->column_usertype == USER_UNIVARCHAR_TYPE))
++				srctype = SYBTEXT;
+ 			if (curcol->column_type == SYBVARIANT)
+ 				srctype = ((TDSVARIANT *) src)->type;
+ 			src = ((TDSBLOB *) src)->textvalue;
+
+commit 5f43430cad354a9abfa7491c0479698f1a223ef6
+Author: freddy77 <freddy77>
+Date:   Wed Dec 16 12:56:55 2009 +0000
+
+    opps...
+
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 0ac7c00..cfaf7af 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -149,7 +149,7 @@ if test \( "$OUTDIR" = "out" -o "$OUTDIR" = "out82" \) -a -r doc/doxy.log; then
+ fi
+ 
+ # save logs for debug
+-rm -f $HOME/log_tds.txt
++rm -f ../log_tds.txt
+ ln logs/log.txt ../log_tds.txt
+ 
+ # test Perl
+
+commit ee8645869cd254d7a81bc745c5776fd91b907067
+Author: freddy77 <freddy77>
+Date:   Wed Dec 16 13:06:30 2009 +0000
+
+    Simplified yesterday path for Windows compile
+
+diff --git a/ChangeLog b/ChangeLog
+index 2b247a0..77b4434 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Dec 16 14:06:17 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/connectparams.c src/odbc/error.c:
++	* src/odbc/odbc.c:
++	- Simplified yesterday path for Windows compile
++
+ Wed Dec 16 13:54:52 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c: Fix conversion for uni(var)char
+ 
+@@ -2001,4 +2006,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2910 2009/12/16 12:55:21 freddy77 Exp $
++$Id: ChangeLog,v 1.2911 2009/12/16 13:06:30 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 231008d..53a7db9 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.114 2009/12/15 09:53:27 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.115 2009/12/16 13:06:30 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -91,12 +91,14 @@ struct _sql_error
+ 
+ struct _sql_errors
+ {
+-	SQLRETURN lastrc;
+-	int num_errors;
+ 	struct _sql_error *errs;
++	int num_errors;
++	SQLRETURN lastrc;
+ 	char ranked;
+ };
+ 
++typedef struct _sql_errors TDS_ERRS;
++
+ #if ENABLE_EXTRA_CHECKS
+ void odbc_check_struct_extra(void *p);
+ 
+@@ -433,8 +435,8 @@ BOOL get_login_info(HWND hwndParent, TDSCONNECTION * connection);
+  * \param connection          structure where to store informations
+  * \return 0 if error, 1 otherwise
+  */
+-int odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection);
+-int odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection);
++int odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection);
++int odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSCONNECTION * connection);
+ 
+ /*
+  * convert_tds2sql.c
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index c9fbc49..631d379 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.80 2009/12/15 11:46:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.81 2009/12/16 13:06:30 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -111,15 +111,14 @@ static int SQLGetPrivateProfileString(LPCSTR pszSection, LPCSTR pszEntry, LPCSTR
+ #endif
+ 
+ static int
+-parse_server(TDS_DBC *dbc, char *server, TDSCONNECTION * connection)
++parse_server(TDS_ERRS *errs, char *server, TDSCONNECTION * connection)
+ {
+ 	char ip[64];
+ 	char *p = (char *) strchr(server, '\\');
+ 
+ 	if (p) {
+ 		if (!tds_dstr_copy(&connection->instance_name, p+1)) {
+-			if (dbc)
+-				odbc_errs_add(&dbc->errs, "HY001", NULL);
++			odbc_errs_add(errs, "HY001", NULL);
+ 			return 0;
+ 		}
+ 		*p = 0;
+@@ -127,8 +126,7 @@ parse_server(TDS_DBC *dbc, char *server, TDSCONNECTION * connection)
+ 
+ 	tds_lookup_host(server, ip);
+ 	if (!tds_dstr_copy(&connection->ip_addr, ip)) {
+-		if (dbc)
+-			odbc_errs_add(&dbc->errs, "HY001", NULL);
++		odbc_errs_add(errs, "HY001", NULL);
+ 		return 0;
+ 	}
+ 
+@@ -149,7 +147,7 @@ myGetPrivateProfileString(const char *DSN, const char *key, char *buf)
+  * @return 1 if success 0 otherwhise
+  */
+ int
+-odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection)
++odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSCONNECTION * connection)
+ {
+ 	char tmp[FILENAME_MAX];
+ 	int freetds_conf_less = 1;
+@@ -160,13 +158,11 @@ odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection)
+ 		tds_dstr_copy(&connection->server_name, tmp);
+ 		tds_read_conf_file(connection, tmp);
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
+-			if (dbc)
+-				odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
++			odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and SERVER");
+ 			return 0;
+ 		}
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Address, tmp) > 0) {
+-			if (dbc)
+-				odbc_errs_add(&dbc->errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS");
++			odbc_errs_add(errs, "HY000", "You cannot specify both SERVERNAME and ADDRESS");
+ 			return 0;
+ 		}
+ 	}
+@@ -184,7 +180,7 @@ odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection)
+ 		if (myGetPrivateProfileString(DSN, odbc_param_Server, tmp) > 0) {
+ 			tds_dstr_copy(&connection->server_name, tmp);
+ 			if (!address_specified) {
+-				if (!parse_server(dbc, tmp, connection))
++				if (!parse_server(errs, tmp, connection))
+ 					return 0;
+ 			}
+ 		}
+@@ -235,7 +231,7 @@ odbc_get_dsn_info(TDS_DBC *dbc, const char *DSN, TDSCONNECTION * connection)
+  * @return 1 if success 0 otherwhise
+  */
+ int
+-odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection)
++odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection)
+ {
+ 	const char *p, *end;
+ 	DSTR *dest_s, value;
+@@ -285,8 +281,7 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 			end = connect_string_end;
+ 
+ 		if (!tds_dstr_copyn(&value, p, end - p)) {
+-			if (dbc)
+-				odbc_errs_add(&dbc->errs, "HY001", NULL);
++			odbc_errs_add(errs, "HY001", NULL);
+ 			return 0;
+ 		}
+ 
+@@ -294,14 +289,13 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 			/* error if servername or DSN specified */
+ 			if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+-				if (dbc)
+-					odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+ 				return 0;
+ 			}
+ 			if (!cfgs) {
+ 				dest_s = &connection->server_name;
+ 				/* not that safe cast but works -- freddy77 */
+-				if (!parse_server(dbc, (char *) tds_dstr_cstr(&value), connection)) {
++				if (!parse_server(errs, (char *) tds_dstr_cstr(&value), connection)) {
+ 					tds_dstr_free(&value);
+ 					return 0;
+ 				}
+@@ -310,8 +304,7 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 		} else if (strcasecmp(option, "SERVERNAME") == 0) {
+ 			if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
+ 				tds_dstr_free(&value);
+-				if (dbc)
+-					odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+ 				return 0;
+ 			}
+ 			if (!cfgs) {
+@@ -324,12 +317,11 @@ odbc_parse_connect_string(TDS_DBC *dbc, const char *connect_string, const char *
+ 		} else if (strcasecmp(option, "DSN") == 0) {
+ 			if ((cfgs & (CFG_SERVER|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+-				if (dbc)
+-					odbc_errs_add(&dbc->errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
++				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+ 				return 0;
+ 			}
+ 			if (!cfgs) {
+-				if (!odbc_get_dsn_info(dbc, tds_dstr_cstr(&value), connection)) {
++				if (!odbc_get_dsn_info(errs, tds_dstr_cstr(&value), connection)) {
+ 					tds_dstr_free(&value);
+ 					return 0;
+ 				}
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index cdae3fc..e5eaa09 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.57 2008/08/18 13:31:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.58 2009/12/16 13:06:30 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -384,10 +384,13 @@ void
+ odbc_errs_add(struct _sql_errors *errs, const char *sqlstate, const char *msg)
+ {
+ 	struct _sql_error *p;
+-	int n = errs->num_errors;
++	int n;
+ 
+ 	assert(sqlstate);
++	if (!errs)
++		return;
+ 
++	n = errs->num_errors;
+ 	if (errs->errs)
+ 		p = (struct _sql_error *) realloc(errs->errs, sizeof(struct _sql_error) * (n + 1));
+ 	else
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index de28180..40618a0 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.519 2009/12/15 11:23:47 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.520 2009/12/16 13:06:30 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -447,7 +447,7 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 		tds_dstr_dup(&connection->database, &dbc->attr.current_catalog);
+ 
+ 	/* parse the DSN string */
+-	odbc_parse_connect_string(dbc, (const char *) szConnStrIn, (const char *) szConnStrIn + conlen, connection);
++	odbc_parse_connect_string(&dbc->errs, (const char *) szConnStrIn, (const char *) szConnStrIn + conlen, connection);
+ 
+ 	/* add login info */
+ 	if (hwnd) {
+@@ -1717,7 +1717,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 		tds_dstr_copy(&dbc->dsn, "DEFAULT");
+ 
+ 
+-	if (!odbc_get_dsn_info(dbc, tds_dstr_cstr(&dbc->dsn), connection)) {
++	if (!odbc_get_dsn_info(&dbc->errs, tds_dstr_cstr(&dbc->dsn), connection)) {
+ 		tds_free_connection(connection);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+
+commit 8e32ce74587f708bcd2085bfd5d73d25816da508
+Author: freddy77 <freddy77>
+Date:   Wed Dec 16 13:07:55 2009 +0000
+
+    *** empty log message ***
+
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index fb2e37e..37692f5 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -73,4 +73,4 @@ wchar
+ transaction2
+ utf8
+ utf8_2
+-
++stats
+
+commit 83ac94c82e6e637edad1ebd2877484be4fde0b1d
+Author: freddy77 <freddy77>
+Date:   Thu Dec 17 10:33:59 2009 +0000
+
+    Fix statistics functions for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 77b4434..6aaa23f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Dec 17 11:33:39 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c:
++	- Fix statistics functions for Sybase
++
+ Wed Dec 16 14:06:17 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/connectparams.c src/odbc/error.c:
+ 	* src/odbc/odbc.c:
+@@ -2006,4 +2010,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2911 2009/12/16 13:06:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2912 2009/12/17 10:33:59 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 53a7db9..ce4b566 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.115 2009/12/16 13:06:30 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.116 2009/12/17 10:33:59 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -326,6 +326,15 @@ typedef enum
+ 	PRE_NORMAL_ROW
+ } TDS_ODBC_ROW_STATUS;
+ 
++typedef enum
++{
++	ODBC_SPECIAL_NONE = 0,
++	ODBC_SPECIAL_GETTYPEINFO = 1,
++	ODBC_SPECIAL_COLUMNS = 2,
++	ODBC_SPECIAL_PROCEDURECOLUMNS = 3,
++	ODBC_SPECIAL_SPECIALCOLUMNS = 4
++} TDS_ODBC_SPECIAL_ROWS;
++
+ struct _hstmt
+ {
+ 	SQLSMALLINT htype;	/* do not reorder this field */
+@@ -370,7 +379,7 @@ struct _hstmt
+ 	SQLULEN sql_rowset_size;
+ 	struct _hsattr attr;
+ 	DSTR cursor_name;	/* auto generated cursor name */
+-	int special_row;
++	TDS_ODBC_SPECIAL_ROWS special_row;
+ 	/* do NOT free cursor, free from socket or attach to connection */
+ 	TDSCURSOR *cursor;
+ 	unsigned char cancel_sent;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 40618a0..3f17c30 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.520 2009/12/16 13:06:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.521 2009/12/17 10:33:59 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
+@@ -666,7 +666,7 @@ SQLMoreResults(SQLHSTMT hstmt)
+ 		ODBC_RETURN(stmt, SQL_NO_DATA);
+ 
+ 	stmt->row_count = TDS_NO_COUNT;
+-	stmt->special_row = 0;
++	stmt->special_row = ODBC_SPECIAL_NONE;
+ 
+ 	/* TODO this code is TOO similar to _SQLExecute, merge it - freddy77 */
+ 	/* try to go to the next recordset */
+@@ -927,6 +927,8 @@ SQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbC
+ 		odbc_col_setname(stmt, 9, "BUFFER_LENGTH");
+ 		odbc_col_setname(stmt, 10, "DECIMAL_DIGITS");
+ 		odbc_col_setname(stmt, 11, "NUM_PREC_RADIX");
++		if (TDS_IS_SYBASE(stmt->dbc->tds_socket))
++			stmt->special_row = ODBC_SPECIAL_PROCEDURECOLUMNS;
+ 	}
+ 	ODBC_RETURN_(stmt);
+ }
+@@ -3435,6 +3437,38 @@ odbc_process_tokens(TDS_STMT * stmt, unsigned flag)
+ 	}
+ }
+ 
++static void
++odbc_fix_data_type_col(TDS_STMT *stmt, int idx)
++{
++	TDSSOCKET *tds = stmt->dbc->tds_socket;
++	TDSRESULTINFO *resinfo;
++	TDSCOLUMN *colinfo;
++
++	if (!tds)
++		return;
++
++	resinfo = tds->current_results;
++	if (!resinfo || resinfo->num_cols <= idx)
++		return;
++
++	colinfo = resinfo->columns[idx];
++	if (colinfo->column_cur_size < 0)
++		return;
++
++	switch (tds_get_conversion_type(colinfo->column_type, colinfo->column_size)) {
++	case SYBINT2: {
++		TDS_SMALLINT *data = (TDS_SMALLINT *) colinfo->column_data;
++		*data = odbc_swap_datetime_sql_type(*data);
++		}
++		break;
++	case SYBINT4: {
++		TDS_INT *data = (TDS_INT *) colinfo->column_data;
++		*data = odbc_swap_datetime_sql_type(*data);
++		}
++		break;
++	}
++}
++
+ /*
+  * - handle correctly SQLGetData (for forward cursors accept only row_size == 1
+  *   for other types application must use SQLSetPos)
+@@ -3591,7 +3625,7 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 				 * if compute tds_process_tokens above returns TDS_NO_MORE_RESULTS
+ 				 */
+ 				stmt->row_status = PRE_NORMAL_ROW;
+-				stmt->special_row = 0;
++				stmt->special_row = ODBC_SPECIAL_NONE;
+ #if 0
+ 				odbc_populate_ird(stmt);
+ #endif
+@@ -3607,15 +3641,21 @@ _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ 
+ 			/* handle special row */
+ 			switch (stmt->special_row) {
+-			case 1: /* GetTypeInfo row convert type */
+-				resinfo = tds->current_results;
+-				if (resinfo->num_cols >= 2) {
+-					colinfo = resinfo->columns[1];
+-					if (colinfo->column_type == SYBINT2) {
+-						TDS_SMALLINT *data = (TDS_SMALLINT *) colinfo->column_data;
+-						*data = odbc_swap_datetime_sql_type(*data);
+-					}
+-				}
++			case ODBC_SPECIAL_GETTYPEINFO:
++				odbc_fix_data_type_col(stmt, 1);
++				break;
++			case ODBC_SPECIAL_COLUMNS:
++				odbc_fix_data_type_col(stmt, 4);
++				odbc_fix_data_type_col(stmt, 13); /* TODO sure ?? */
++				break;
++			case ODBC_SPECIAL_PROCEDURECOLUMNS:
++				odbc_fix_data_type_col(stmt, 5);
++				odbc_fix_data_type_col(stmt, 14); /* TODO sure ?? */
++				break;
++			case ODBC_SPECIAL_SPECIALCOLUMNS:
++				odbc_fix_data_type_col(stmt, 2);
++				break;
++			case ODBC_SPECIAL_NONE:
+ 				break;
+ 			}
+ 		}
+@@ -4543,6 +4583,8 @@ SQLColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName,	/* object_qualifier */
+ 		odbc_col_setname(stmt, 8, "BUFFER_LENGTH");
+ 		odbc_col_setname(stmt, 9, "DECIMAL_DIGITS");
+ 		odbc_col_setname(stmt, 10, "NUM_PREC_RADIX");
++		if (TDS_IS_SYBASE(stmt->dbc->tds_socket))
++			stmt->special_row = ODBC_SPECIAL_COLUMNS;
+ 	}
+ 	ODBC_RETURN_(stmt);
+ }
+@@ -5754,25 +5796,30 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 	int varchar_pos = -1, n;
+ 	static const char sql_templ[] = "EXEC sp_datatype_info %d";
+ 	char sql[sizeof(sql_templ) + 30];
++	int odbc3;
+ 
+ 	INIT_HSTMT;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetTypeInfo(%p, %d)\n", hstmt, fSqlType);
+ 
+ 	tds = stmt->dbc->tds_socket;
++	odbc3 = (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3);
+ 
+ 	/* For MSSQL6.5 and Sybase 11.9 sp_datatype_info work */
+ 	/* TODO what about early Sybase products ? */
+ 	/* TODO Does Sybase return all ODBC3 columns? Add them if not */
+ 	/* TODO ODBC3 convert type to ODBC version 2 (date) */
+-	if (TDS_IS_SYBASE(tds) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+-		fSqlType = odbc_swap_datetime_sql_type(fSqlType);
+-		stmt->special_row = 1;
++	if (odbc3) {
++		if (TDS_IS_SYBASE(tds)) {
++			sprintf(sql, sql_templ, odbc_swap_datetime_sql_type(fSqlType));
++			stmt->special_row = ODBC_SPECIAL_GETTYPEINFO;
++		} else {
++			sprintf(sql, sql_templ, fSqlType);
++			strcat(sql, ",3");
++		}
++	} else {
++		sprintf(sql, sql_templ, fSqlType);
+ 	}
+-
+-	sprintf(sql, sql_templ, fSqlType);
+-	if (TDS_IS_MSSQL(tds) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3)
+-		strcat(sql, ",3");
+ 	if (SQL_SUCCESS != odbc_set_stmt_query(stmt, sql, strlen(sql)))
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 
+@@ -5780,17 +5827,17 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 	res = _SQLExecute(stmt);
+ 
+ 	odbc_upper_column_names(stmt);
+-	if (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
++	if (odbc3) {
+ 		odbc_col_setname(stmt, 3, "COLUMN_SIZE");
+ 		odbc_col_setname(stmt, 11, "FIXED_PREC_SCALE");
+ 		odbc_col_setname(stmt, 12, "AUTO_UNIQUE_VALUE");
+ 	}
+ 
+ 	/* workaround for a mispelled column name in Sybase */
+-	if (TDS_IS_SYBASE(stmt->dbc->tds_socket) && stmt->dbc->env->attr.odbc_version != SQL_OV_ODBC3)
++	if (TDS_IS_SYBASE(stmt->dbc->tds_socket) && !odbc3)
+ 		odbc_col_setname(stmt, 3, "PRECISION");
+ 
+-	if (TDS_IS_MSSQL(stmt->dbc->tds_socket) || fSqlType != 12 || res != SQL_SUCCESS)
++	if (TDS_IS_MSSQL(stmt->dbc->tds_socket) || fSqlType != SQL_VARCHAR || res != SQL_SUCCESS)
+ 		ODBC_RETURN(stmt, res);
+ 
+ 	/*
+@@ -6394,6 +6441,8 @@ SQLSpecialColumns(SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR FAR * szCatalog
+ 		odbc_col_setname(stmt, 5, "COLUMN_SIZE");
+ 		odbc_col_setname(stmt, 6, "BUFFER_LENGTH");
+ 		odbc_col_setname(stmt, 7, "DECIMAL_DIGITS");
++		if (TDS_IS_SYBASE(stmt->dbc->tds_socket))
++			stmt->special_row = ODBC_SPECIAL_SPECIALCOLUMNS;
+ 	}
+ 	ODBC_RETURN_(stmt);
+ }
+
+commit 128b7a304cc4c694bc5e3c55ae525f8b91a860aa
+Author: freddy77 <freddy77>
+Date:   Thu Dec 17 21:08:59 2009 +0000
+
+    Automatic odbc version selection
+
+diff --git a/ChangeLog b/ChangeLog
+index 6aaa23f..395816e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Dec 17 22:08:50 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: Automatic odbc version selection
++
+ Thu Dec 17 11:33:39 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/odbc.c:
+ 	- Fix statistics functions for Sybase
+@@ -2010,4 +2013,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2912 2009/12/17 10:33:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2913 2009/12/17 21:08:59 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 3f17c30..c2387f3 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,10 +60,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.521 2009/12/17 10:33:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.522 2009/12/17 21:08:59 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+-static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv);
++static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+ static SQLRETURN _SQLAllocStmt(SQLHDBC hdbc, SQLHSTMT FAR * phstmt);
+ static SQLRETURN _SQLAllocDesc(SQLHDBC hdbc, SQLHDESC FAR * phdesc);
+ static SQLRETURN _SQLFreeConnect(SQLHDBC hdbc);
+@@ -1320,7 +1320,7 @@ SQLAllocHandle(SQLSMALLINT HandleType, SQLHANDLE InputHandle, SQLHANDLE * Output
+ 		return _SQLAllocConnect(InputHandle, OutputHandle);
+ 		break;
+ 	case SQL_HANDLE_ENV:
+-		return _SQLAllocEnv(OutputHandle);
++		return _SQLAllocEnv(OutputHandle, SQL_OV_ODBC3);
+ 		break;
+ 	case SQL_HANDLE_DESC:
+ 		return _SQLAllocDesc(InputHandle, OutputHandle);
+@@ -1392,20 +1392,20 @@ SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc)
+ }
+ 
+ static SQLRETURN
+-_SQLAllocEnv(SQLHENV FAR * phenv)
++_SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version)
+ {
+ 	TDS_ENV *env;
+ 	TDSCONTEXT *ctx;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_SQLAllocEnv(%p)\n", 
+-			phenv);
++	tdsdump_log(TDS_DBG_FUNC, "_SQLAllocEnv(%p, %d)\n",
++			phenv, (int) odbc_version);
+ 
+ 	env = (TDS_ENV *) calloc(1, sizeof(TDS_ENV));
+ 	if (!env)
+ 		return SQL_ERROR;
+ 
+ 	env->htype = SQL_HANDLE_ENV;
+-	env->attr.odbc_version = SQL_OV_ODBC2;
++	env->attr.odbc_version = odbc_version;
+ 	/* TODO use it */
+ 	env->attr.output_nts = SQL_TRUE;
+ 
+@@ -1432,7 +1432,7 @@ SQLAllocEnv(SQLHENV FAR * phenv)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLAllocEnv(%p)\n", phenv);
+ 
+-	return _SQLAllocEnv(phenv);
++	return _SQLAllocEnv(phenv, SQL_OV_ODBC2);
+ }
+ 
+ static SQLRETURN
+
+commit e6af93c34c779743087752436c68d071846d4c82
+Author: freddy77 <freddy77>
+Date:   Tue Dec 22 18:56:22 2009 +0000
+
+    Don't call SQLAllocEnv for ODBC 3
+
+diff --git a/ChangeLog b/ChangeLog
+index 395816e..dd61f0a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Dec 22 20:00:18 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c: Don't call SQLAllocEnv for ODBC 3
++
+ Thu Dec 17 22:08:50 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: Automatic odbc version selection
+ 
+@@ -2013,4 +2016,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2913 2009/12/17 21:08:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2914 2009/12/22 18:56:22 freddy77 Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 3c1c049..998301d 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.54 2009/03/16 12:19:03 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.55 2009/12/22 18:56:22 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -199,12 +199,15 @@ Connect(void)
+ 	if (read_login_info())
+ 		exit(1);
+ 
+-	CHKAllocEnv(&Environment, "S");
+-
+-	if (use_odbc_version3)
++	if (use_odbc_version3) {
++		CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &Environment, "S");
+ 		SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++		CHKAllocHandle(SQL_HANDLE_DBC, Environment, &Connection, "S");
++	} else {
++		CHKAllocEnv(&Environment, "S");
++		CHKAllocConnect(&Connection, "S");
++	}
+ 
+-	CHKAllocConnect(&Connection, "S");
+ 	printf("odbctest\n--------\n\n");
+ 	printf("connection parameters:\nserver:   '%s'\nuser:     '%s'\npassword: '%s'\ndatabase: '%s'\n",
+ 	       SERVER, USER, "????" /* PASSWORD */ , DATABASE);
+
+commit 1ec35a90d4670e2296c8aba3cd1ccc397ac4c9ba
+Author: freddy77 <freddy77>
+Date:   Tue Dec 22 18:57:20 2009 +0000
+
+    Better way to fix data_type for date
+
+diff --git a/ChangeLog b/ChangeLog
+index dd61f0a..3023f2e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Dec 22 20:01:16 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: Better way to fix data_type for date
++
+ Tue Dec 22 20:00:18 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/common.c: Don't call SQLAllocEnv for ODBC 3
+ 
+@@ -2016,4 +2019,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2914 2009/12/22 18:56:22 freddy77 Exp $
++$Id: ChangeLog,v 1.2915 2009/12/22 18:57:20 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index c2387f3..6b80a5b 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.522 2009/12/17 21:08:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.523 2009/12/22 18:57:20 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -88,7 +88,7 @@ static void odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name);
+ static SQLRETURN odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...);
+ static SQLRETURN odbc_free_dynamic(TDS_STMT * stmt);
+ static SQLRETURN odbc_free_cursor(TDS_STMT * stmt);
+-static SQLSMALLINT odbc_swap_datetime_sql_type(SQLSMALLINT sql_type);
++static SQLSMALLINT odbc_fix_datetime_sql_type(SQLSMALLINT sql_type, SQLINTEGER odbc_version);
+ static int odbc_process_tokens(TDS_STMT * stmt, unsigned flag);
+ static int odbc_lock_statement(TDS_STMT* stmt);
+ 
+@@ -3458,12 +3458,12 @@ odbc_fix_data_type_col(TDS_STMT *stmt, int idx)
+ 	switch (tds_get_conversion_type(colinfo->column_type, colinfo->column_size)) {
+ 	case SYBINT2: {
+ 		TDS_SMALLINT *data = (TDS_SMALLINT *) colinfo->column_data;
+-		*data = odbc_swap_datetime_sql_type(*data);
++		*data = odbc_fix_datetime_sql_type(*data, stmt->dbc->env->attr.odbc_version);
+ 		}
+ 		break;
+ 	case SYBINT4: {
+ 		TDS_INT *data = (TDS_INT *) colinfo->column_data;
+-		*data = odbc_swap_datetime_sql_type(*data);
++		*data = odbc_fix_datetime_sql_type(*data, stmt->dbc->env->attr.odbc_version);
+ 		}
+ 		break;
+ 	}
+@@ -5761,26 +5761,20 @@ odbc_upper_column_names(TDS_STMT * stmt)
+ }
+ 
+ static SQLSMALLINT
+-odbc_swap_datetime_sql_type(SQLSMALLINT sql_type)
++odbc_fix_datetime_sql_type(SQLSMALLINT sql_type, SQLINTEGER odbc_version)
+ {
+ 	switch (sql_type) {
+-	case SQL_TYPE_TIMESTAMP:
+-		sql_type = SQL_TIMESTAMP;
+-		break;
+ 	case SQL_TIMESTAMP:
+-		sql_type = SQL_TYPE_TIMESTAMP;
+-		break;
+-	case SQL_TYPE_DATE:
+-		sql_type = SQL_DATE;
++	case SQL_TYPE_TIMESTAMP:
++		sql_type = odbc_version != SQL_OV_ODBC2 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
+ 		break;
+ 	case SQL_DATE:
+-		sql_type = SQL_TYPE_DATE;
+-		break;
+-	case SQL_TYPE_TIME:
+-		sql_type = SQL_TIME;
++	case SQL_TYPE_DATE:
++		sql_type = odbc_version != SQL_OV_ODBC2 ? SQL_TYPE_DATE : SQL_DATE;
+ 		break;
+ 	case SQL_TIME:
+-		sql_type = SQL_TYPE_TIME;
++	case SQL_TYPE_TIME:
++		sql_type = odbc_version != SQL_OV_ODBC2 ? SQL_TYPE_TIME : SQL_TIME;
+ 		break;
+ 	}
+ 	return sql_type;
+@@ -5811,7 +5805,7 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 	/* TODO ODBC3 convert type to ODBC version 2 (date) */
+ 	if (odbc3) {
+ 		if (TDS_IS_SYBASE(tds)) {
+-			sprintf(sql, sql_templ, odbc_swap_datetime_sql_type(fSqlType));
++			sprintf(sql, sql_templ, odbc_fix_datetime_sql_type(fSqlType, SQL_OV_ODBC2));
+ 			stmt->special_row = ODBC_SPECIAL_GETTYPEINFO;
+ 		} else {
+ 			sprintf(sql, sql_templ, fSqlType);
+
+commit 54f31555142b117022c60411b690f1512381ad2c
+Author: jklowden <jklowden>
+Date:   Tue Dec 22 20:58:21 2009 +0000
+
+    added, builds db-lib on Win32 with nmake.exe
+
+diff --git a/ChangeLog b/ChangeLog
+index 3023f2e..dd0a5a4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Dec 22 15:56:11 EST 2009	JK Lowden <jklowden@freetds.org>
++	* Nmakefile added, builds db-lib on Win32 with nmake.exe
++	* src/odbc/convert_tds2sql.c remove unneeded cast
++
+ Tue Dec 22 20:01:16 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: Better way to fix data_type for date
+ 
+@@ -2019,4 +2023,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2915 2009/12/22 18:57:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2916 2009/12/22 20:58:21 jklowden Exp $
+diff --git a/Nmakefile b/Nmakefile
+new file mode 100755
+index 0000000..d003fd5
+--- /dev/null
++++ b/Nmakefile
+@@ -0,0 +1,246 @@
++# $Id: Nmakefile,v 1.1 2009/12/22 20:58:21 jklowden Exp $
++# Build FreeTDS and assorted utilities for Win32/Win64 without an IDE. 
++# Makefiles, unlike Visual Studio project files, are stable over time.  
++# Contributed to the public domain by James K. Lowden, February 2009
++
++# Define in the environment or on the command line:
++# 1. CONFIGURATION = debug/release
++# 2. PLATFORM = win32/x64
++# These will determine what is built and where outputs are placed. 
++#
++# Example invocation:
++#	nmake.exe -f Nmakefile -nologo PLATFORM=win32 CONFIGURATION=debug
++#	
++
++DBLIB_DIR        = src\dblib
++REPLACEMENTS_DIR = src\replacements
++TDS_DIR          = src\tds
++
++DBLIB_OUT        = $(DBLIB_DIR)\$(PLATFORM)\$(CONFIGURATION)
++REPLACEMENTS_OUT = $(REPLACEMENTS_DIR)\$(PLATFORM)\$(CONFIGURATION)
++TDS_OUT          = $(TDS_DIR)\$(PLATFORM)\$(CONFIGURATION)
++
++DBLIB_SRC = 	$(DBLIB_DIR)\bcp.c \
++		$(DBLIB_DIR)\dblib.c \
++		$(DBLIB_DIR)\dbopen.c \
++		$(DBLIB_DIR)\dbutil.c \
++		$(DBLIB_DIR)\rpc.c \
++		$(DBLIB_DIR)\xact.c 
++
++DBLIB_OBJ = 	$(DBLIB_OUT)\bcp.obj \
++		$(DBLIB_OUT)\dblib.obj \
++		$(DBLIB_OUT)\dbopen.obj \
++		$(DBLIB_OUT)\dbutil.obj \
++		$(DBLIB_OUT)\rpc.obj \
++		$(DBLIB_OUT)\xact.obj 
++
++REPLACEMENTS_SRC =	$(REPLACEMENTS_DIR)\asprintf.c \
++			$(REPLACEMENTS_DIR)\basename.c \
++			$(REPLACEMENTS_DIR)\fakepoll.c \
++			$(REPLACEMENTS_DIR)\gettimeofday.c \
++			$(REPLACEMENTS_DIR)\iconv.c \
++			$(REPLACEMENTS_DIR)\readpassphrase.c \
++			$(REPLACEMENTS_DIR)\strlcat.c \
++			$(REPLACEMENTS_DIR)\strlcpy.c \
++			$(REPLACEMENTS_DIR)\strtok_r.c \
++			$(REPLACEMENTS_DIR)\vasprintf.c 
++
++REPLACEMENTS_OBJ =	$(REPLACEMENTS_OUT)\asprintf.obj \
++			$(REPLACEMENTS_OUT)\basename.obj \
++			$(REPLACEMENTS_OUT)\fakepoll.obj \
++			$(REPLACEMENTS_OUT)\gettimeofday.obj \
++			$(REPLACEMENTS_OUT)\iconv.obj \
++			$(REPLACEMENTS_OUT)\readpassphrase.obj \
++			$(REPLACEMENTS_OUT)\strlcat.obj \
++			$(REPLACEMENTS_OUT)\strlcpy.obj \
++			$(REPLACEMENTS_OUT)\strtok_r.obj \
++			$(REPLACEMENTS_OUT)\vasprintf.obj 
++
++TDS_SRC =	$(TDS_DIR)\bulk.c \
++		$(TDS_DIR)\challenge.c \
++		$(TDS_DIR)\config.c \
++		$(TDS_DIR)\convert.c \
++		$(TDS_DIR)\data.c \
++		$(TDS_DIR)\des.c \
++		$(TDS_DIR)\getmac.c \
++		$(TDS_DIR)\gssapi.c \
++		$(TDS_DIR)\hmac_md5.c \
++		$(TDS_DIR)\iconv.c \
++		$(TDS_DIR)\locale.c \
++		$(TDS_DIR)\log.c \
++		$(TDS_DIR)\login.c \
++		$(TDS_DIR)\md4.c \
++		$(TDS_DIR)\md5.c \
++		$(TDS_DIR)\mem.c \
++		$(TDS_DIR)\net.c \
++		$(TDS_DIR)\numeric.c \
++		$(TDS_DIR)\query.c \
++		$(TDS_DIR)\read.c \
++		$(TDS_DIR)\tds_checks.c \
++		$(TDS_DIR)\tdsstring.c \
++		$(TDS_DIR)\threadsafe.c \
++		$(TDS_DIR)\token.c \
++		$(TDS_DIR)\util.c \
++		$(TDS_DIR)\vstrbuild.c \
++		$(TDS_DIR)\write.c 
++
++TDS_OBJ =	$(TDS_OUT)\bulk.obj \
++		$(TDS_OUT)\challenge.obj \
++		$(TDS_OUT)\config.obj \
++		$(TDS_OUT)\convert.obj \
++		$(TDS_OUT)\data.obj \
++		$(TDS_OUT)\des.obj \
++		$(TDS_OUT)\getmac.obj \
++		$(TDS_OUT)\gssapi.obj \
++		$(TDS_OUT)\hmac_md5.obj \
++		$(TDS_OUT)\iconv.obj \
++		$(TDS_OUT)\locale.obj \
++		$(TDS_OUT)\log.obj \
++		$(TDS_OUT)\login.obj \
++		$(TDS_OUT)\md4.obj \
++		$(TDS_OUT)\md5.obj \
++		$(TDS_OUT)\mem.obj \
++		$(TDS_OUT)\net.obj \
++		$(TDS_OUT)\numeric.obj \
++		$(TDS_OUT)\query.obj \
++		$(TDS_OUT)\read.obj \
++		$(TDS_OUT)\tds_checks.obj \
++		$(TDS_OUT)\tdsstring.obj \
++		$(TDS_OUT)\threadsafe.obj \
++		$(TDS_OUT)\token.obj \
++		$(TDS_OUT)\util.obj \
++		$(TDS_OUT)\vstrbuild.obj \
++		$(TDS_OUT)\write.obj 
++
++one: $(DBLIB_OUT)\db-lib.lib 
++
++#
++# Sadly the environment settings for building for different architectures
++# is undocumented.  Microsoft's directions are to run the requisite 
++# batch file without explaining what it does.  While it's possible to 
++# read the file -- and it's not complicated -- it's impossible to 
++# know the purpose of setting PATH/INCLUDE/LIB just so.  Worse, the 
++# settings are per-machine, and if the file is lost, the only way to 
++# recreate it is to reinstall the compiler.  
++#
++# The "solution" is to follow their advice.  Run vcvarsall.bat with the 
++# appropriate argument to set up the environment, and go from there.  
++#
++# As of this writing, the variables are:
++# x86 Native: Vcvarsall "x86" 
++# x64 Native: Vcvarsall "amd64"
++# x64 Cross:  Vcvarsall "x86_amd64"
++#
++
++all: build-win32d build-win32r build-win64d build-win64r
++
++build-win32d: 
++	$(MAKE) -fNmakefile -nologo PLATFORM=win32 CONFIGURATION=debug
++build-win32r: 
++	$(MAKE) -fNmakefile -nologo PLATFORM=win32 CONFIGURATION=release
++build-win64d: 
++	$(MAKE) -fNmakefile -nologo PLATFORM=win64 CONFIGURATION=debug
++build-win64r: 
++	$(MAKE) -fNmakefile -nologo PLATFORM=win64 CONFIGURATION=release
++
++$(DBLIB_OUT) $(REPLACEMENTS_OUT) $(TDS_OUT):
++	md $@
++
++$(DBLIB_OUT)\db-lib.lib: $(DBLIB_OUT) $(DBLIB_OBJ) $(REPLACEMENTS_OUT)\replacements.lib $(TDS_OUT)\tds.lib
++	@echo building $@ >&2
++	lib -nologo -out:"$@" 	$(DBLIB_OBJ) \
++				$(REPLACEMENTS_OUT)\replacements.lib \
++				$(TDS_OUT)\tds.lib
++$(REPLACEMENTS_OUT)\replacements.lib: $(REPLACEMENTS_OUT) $(REPLACEMENTS_OBJ)
++	lib -nologo -out:"$@" $(REPLACEMENTS_OBJ) 
++$(TDS_OUT)\tds.lib: $(TDS_OUT) $(TDS_OBJ)
++	lib -nologo -out:"$@" $(TDS_OBJ) 
++
++#
++# set compiler flags
++#
++INC = 	-I "include" -I "include\x64"
++FLG = 	-nologo	-W3 -Wp64 -c -EHsc -TC -Gm  -errorReport:prompt 
++DEF = 	-D "_MBCS" -D "_LIB" \
++	-D "_CRT_SECURE_NO_WARNINGS" \
++	-D "HAVE_CONFIG_H" \
++	-D "_FREETDS_LIBRARY_SOURCE" 
++DBG = -MTd -Od -D "_DEBUG"  -ZI -RTC1	
++REL = -MT  -O2 -D "_NDEBUG" -Zi	
++
++CC = cl $(FLG) $(DEF) $(INC)
++CC32 = $(CC) -D "WIN32"	
++CC64 = $(CC) 
++
++## Rules ##
++
++#
++# dblib
++#
++#c.{$(DBLIB_DIR)\win32\debug}.obj::
++{$(DBLIB_DIR)}.c{$(DBLIB_DIR)\win32\debug}.obj::
++	$(CC32) $(DBG) 	-Fo"$(DBLIB_OUT)\\" \
++			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$<
++
++{$(DBLIB_DIR)\}.c{$(DBLIB_DIR)\win32\release}.obj::
++	$(CC32) $(REL) 	-Fo"$(DBLIB_OUT)\\" \
++			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$<
++
++{$(DBLIB_DIR)}.c{$(DBLIB_DIR)\x64\debug}.obj::
++	$(CC64) $(DBG) 	-Fo"$(DBLIB_OUT)\\" \
++			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$<
++
++{$(DBLIB_DIR)}.c{$(DBLIB_DIR)\x64\release}.obj::
++	$(CC64) $(REL) 	-Fo"$(DBLIB_OUT)\\" \
++			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$<
++
++#
++# replacements
++#
++{$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\win32\debug}.obj::
++	$(CC32) $(DBG) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$<
++
++{$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\win32\release}.obj::
++	$(CC32) $(REL) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$<
++
++{$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\x64\debug}.obj::
++	$(CC64) $(DBG) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$<
++
++{$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\x64\release}.obj::
++	$(CC64) $(REL) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$<
++
++#
++# tds
++#
++{$(TDS_DIR)}.c{$(TDS_DIR)\win32\debug}.obj::
++	$(CC32) $(DBG) 	-Fo"$(TDS_OUT)\\" \
++			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$<
++
++{$(TDS_DIR)}.c{$(TDS_DIR)\win32\release}.obj::
++	$(CC32) $(REL) 	-Fo"$(TDS_OUT)\\" \
++			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$<
++
++{$(TDS_DIR)}.c{$(TDS_DIR)\x64\debug}.obj::
++	$(CC64) $(DBG) 	-Fo"$(TDS_OUT)\\" \
++			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$<
++
++{$(TDS_DIR)}.c{$(TDS_DIR)\x64\release}.obj::
++	$(CC64) $(REL) 	-Fo"$(TDS_OUT)\\" \
++			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$<
++
+
+commit a3792d5f6aa794cecfe83101ddf54a4b71690205
+Author: jklowden <jklowden>
+Date:   Tue Dec 22 20:58:25 2009 +0000
+
+    remove unneeded cast
+
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index a233a28..3e3b537 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.67 2009/12/16 12:55:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.68 2009/12/22 20:58:25 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -75,7 +75,7 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 	char_size = desttype == SQL_C_CHAR ? 1 : SIZEOF_SQLWCHAR;
+ 	if (destlen >= char_size) {
+ 		ol = destlen - char_size;
+-		memset(&conv->suppress, 0, sizeof(conv->suppress));
++		memset((TDSICONV *)&conv->suppress, 0, sizeof(conv->suppress));
+ 		err = tds_iconv(tds, conv, to_client, &ib, &il, &ob, &ol);
+ 		ol = ob - dest;
+ 		if (curcol)
+
+commit 000e8a9378b89ce7efbd309f79caf5be55cd79ce
+Author: freddy77 <freddy77>
+Date:   Mon Dec 28 12:42:14 2009 +0000
+
+    Fix problem with iODBC (where sizeof(SQLWCHAR) == 4)
+
+diff --git a/ChangeLog b/ChangeLog
+index dd0a5a4..b20749a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Dec 28 13:42:02 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/getdata.c:
++	- Fix problem with iODBC (where sizeof(SQLWCHAR) == 4)
++
+ Tue Dec 22 15:56:11 EST 2009	JK Lowden <jklowden@freetds.org>
+ 	* Nmakefile added, builds db-lib on Win32 with nmake.exe
+ 	* src/odbc/convert_tds2sql.c remove unneeded cast
+@@ -2023,4 +2027,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2916 2009/12/22 20:58:21 jklowden Exp $
++$Id: ChangeLog,v 1.2917 2009/12/28 12:42:14 freddy77 Exp $
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 36c6019..dde0347 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.14 2009/12/07 16:22:12 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.15 2009/12/28 12:42:14 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -108,7 +108,7 @@ main(int argc, char *argv[])
+ 			exit(1);
+ 		}
+ 
+-		CHKGetData(1, type, buf, 16, NULL, "S");
++		CHKGetData(1, type, buf, 20, NULL, "S");
+ 		if (mycmp(buf, "test") != 0) {
+ 			printf("Wrong data result 2 res = '%s'\n", buf);
+ 			exit(1);
+
+commit 7c34b7cd85d8c5f99074c1b21a89534551609e7b
+Author: freddy77 <freddy77>
+Date:   Mon Dec 28 13:30:31 2009 +0000
+
+    Fix SQLGetData converting fixed to variable with truncation
+
+diff --git a/ChangeLog b/ChangeLog
+index b20749a..3e2c4b4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Dec 28 14:30:21 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
++	* src/odbc/unittests/getdata.c:
++	- Fix SQLGetData converting fixed to variable with truncation
++
+ Mon Dec 28 13:42:02 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/getdata.c:
+ 	- Fix problem with iODBC (where sizeof(SQLWCHAR) == 4)
+@@ -2027,4 +2032,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2917 2009/12/28 12:42:14 freddy77 Exp $
++$Id: ChangeLog,v 1.2918 2009/12/28 13:30:31 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index ad67cc3..e4c3d16 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.323 2009/11/26 09:47:41 freddy77 Exp $ */
++/* $Id: tds.h,v 1.324 2009/12/28 13:30:31 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -995,7 +995,7 @@ typedef struct tds_column
+ 		TDS_INT column_size;
+ 	} on_server;
+ 
+-	const TDSICONV *char_conv;	/**< refers to previously allocated iconv information */
++	TDSICONV *char_conv;	/**< refers to previously allocated iconv information */
+ 
+ 	TDS_CHAR table_name[TDS_SYSNAME_SIZE];
+ 	TDS_CHAR column_name[TDS_SYSNAME_SIZE];
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 3e3b537..e661bde 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.68 2009/12/22 20:58:25 jklowden Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.69 2009/12/28 13:30:31 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -58,7 +58,7 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 
+ 	TDSSOCKET *tds = stmt->dbc->tds_socket;
+ 
+-	const TDSICONV *conv = curcol->char_conv;
++	TDSICONV *conv = curcol->char_conv;
+ 	if (!conv)
+ 		conv = tds->char_convs[client2server_chardata];
+ 	if (desttype == SQL_C_WCHAR) {
+@@ -75,7 +75,8 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 	char_size = desttype == SQL_C_CHAR ? 1 : SIZEOF_SQLWCHAR;
+ 	if (destlen >= char_size) {
+ 		ol = destlen - char_size;
+-		memset((TDSICONV *)&conv->suppress, 0, sizeof(conv->suppress));
++		memset(&conv->suppress, 0, sizeof(conv->suppress));
++		conv->suppress.e2big = 1;
+ 		err = tds_iconv(tds, conv, to_client, &ib, &il, &ob, &ol);
+ 		ol = ob - dest;
+ 		if (curcol)
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 6b80a5b..b0d2654 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.523 2009/12/22 18:57:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.524 2009/12/28 13:30:31 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -4779,6 +4779,11 @@ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgb
+ 			}
+ 		} else {
+ 			colinfo->column_text_sqlgetdatapos = colinfo->column_cur_size;
++			if (is_fixed_type(nSybType) && (fCType == SQL_C_CHAR || fCType == SQL_C_WCHAR || fCType == SQL_C_BINARY)
++			    && cbValueMax < *pcbValue) {
++				odbc_errs_add(&stmt->errs, "22003", NULL);
++				ODBC_RETURN(stmt, SQL_ERROR);
++			}
+ 		}
+ 	}
+ 	ODBC_RETURN_(stmt);
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index dde0347..032a73a 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.15 2009/12/28 12:42:14 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.16 2009/12/28 13:30:31 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char odbc_err[256];
+@@ -174,11 +174,13 @@ main(int argc, char *argv[])
+ 	/* error 22003 */
+ 	memset(buf, 'x', sizeof(buf));
+ 	CHKGetData(1, SQL_C_CHAR, buf, 4, NULL, "E");
++#ifdef ENABLE_DEVELOPING
+ 	buf[4] = 0;
+ 	if (strcmp(buf, "xxxx") != 0) {
+ 		fprintf(stderr, "Wrong buffer result buf = %s\n", buf);
+ 		exit(1);
+ 	}
++#endif
+ 	ReadError();
+ 	if (strcmp(odbc_sqlstate, "22003") != 0) {
+ 		fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
+
+commit a1304e7849e2db54953f6ae1cc8c7cf720841fbe
+Author: freddy77 <freddy77>
+Date:   Thu Jan 7 13:56:55 2010 +0000
+
+    added small comments
+
+diff --git a/ChangeLog b/ChangeLog
+index 3e2c4b4..fc5f130 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan  7 14:56:27 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c: added small comments
++
+ Mon Dec 28 14:30:21 CET 2009    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/convert_tds2sql.c src/odbc/odbc.c:
+ 	* src/odbc/unittests/getdata.c:
+@@ -2032,4 +2035,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2918 2009/12/28 13:30:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2919 2010/01/07 13:56:55 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index e661bde..e523362 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2003-2008  Frediano Ziglio
++ * Copyright (C) 2003-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -42,7 +42,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.69 2009/12/28 13:30:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.70 2010/01/07 13:56:55 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -78,7 +78,7 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 		memset(&conv->suppress, 0, sizeof(conv->suppress));
+ 		conv->suppress.e2big = 1;
+ 		err = tds_iconv(tds, conv, to_client, &ib, &il, &ob, &ol);
+-		ol = ob - dest;
++		ol = ob - dest; /* bytes written */
+ 		if (curcol)
+ 			curcol->column_text_sqlgetdatapos += ib - src;
+ 		/* terminate string */
+
+commit 5570ca88857188f4731b130c82ecc58944607082
+Author: jklowden <jklowden>
+Date:   Fri Jan 8 22:07:59 2010 +0000
+
+    Build some utilities under Win32.  Print useful log messages for win32 connection failures.
+
+diff --git a/ChangeLog b/ChangeLog
+index fc5f130..9429ddf 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Fri Jan  8 17:05:24 EST 2010	JK Lowden <jklowden@freetds.org>
++	* Nmakefile include/replacements.h win32/config.h
++	* src/apps/bsqldb.c src/apps/defncopy.c src/apps/tsql.c
++	* src/tds/config.c src/tds/hmac_md5.c src/tds/mem.c
++	* src/tds/net.c src/tds/numeric.c src/tds/token.c
++	- Build some utilities under Win32. 
++	- Print useful log messages for win32 connection failures. 	
++
+ Thu Jan  7 14:56:27 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c: added small comments
+ 
+@@ -2035,4 +2043,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2919 2010/01/07 13:56:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2920 2010/01/08 22:07:59 jklowden Exp $
+diff --git a/Nmakefile b/Nmakefile
+index d003fd5..d17881b 100755
+--- a/Nmakefile
++++ b/Nmakefile
+@@ -1,4 +1,4 @@
+-# $Id: Nmakefile,v 1.1 2009/12/22 20:58:21 jklowden Exp $
++# $Id: Nmakefile,v 1.2 2010/01/08 22:08:01 jklowden Exp $
+ # Build FreeTDS and assorted utilities for Win32/Win64 without an IDE. 
+ # Makefiles, unlike Visual Studio project files, are stable over time.  
+ # Contributed to the public domain by James K. Lowden, February 2009
+@@ -12,13 +12,17 @@
+ #	nmake.exe -f Nmakefile -nologo PLATFORM=win32 CONFIGURATION=debug
+ #	
+ 
++MKDIR = MD
++
+ DBLIB_DIR        = src\dblib
+ REPLACEMENTS_DIR = src\replacements
+ TDS_DIR          = src\tds
++APPS_DIR         = src\apps
+ 
+ DBLIB_OUT        = $(DBLIB_DIR)\$(PLATFORM)\$(CONFIGURATION)
+ REPLACEMENTS_OUT = $(REPLACEMENTS_DIR)\$(PLATFORM)\$(CONFIGURATION)
+ TDS_OUT          = $(TDS_DIR)\$(PLATFORM)\$(CONFIGURATION)
++APPS_OUT         = $(APPS_DIR)\$(PLATFORM)\$(CONFIGURATION)
+ 
+ DBLIB_SRC = 	$(DBLIB_DIR)\bcp.c \
+ 		$(DBLIB_DIR)\dblib.c \
+@@ -38,6 +42,7 @@ REPLACEMENTS_SRC =	$(REPLACEMENTS_DIR)\asprintf.c \
+ 			$(REPLACEMENTS_DIR)\basename.c \
+ 			$(REPLACEMENTS_DIR)\fakepoll.c \
+ 			$(REPLACEMENTS_DIR)\gettimeofday.c \
++			$(REPLACEMENTS_DIR)\getopt.c \
+ 			$(REPLACEMENTS_DIR)\iconv.c \
+ 			$(REPLACEMENTS_DIR)\readpassphrase.c \
+ 			$(REPLACEMENTS_DIR)\strlcat.c \
+@@ -49,6 +54,7 @@ REPLACEMENTS_OBJ =	$(REPLACEMENTS_OUT)\asprintf.obj \
+ 			$(REPLACEMENTS_OUT)\basename.obj \
+ 			$(REPLACEMENTS_OUT)\fakepoll.obj \
+ 			$(REPLACEMENTS_OUT)\gettimeofday.obj \
++			$(REPLACEMENTS_OUT)\getopt.obj \
+ 			$(REPLACEMENTS_OUT)\iconv.obj \
+ 			$(REPLACEMENTS_OUT)\readpassphrase.obj \
+ 			$(REPLACEMENTS_OUT)\strlcat.obj \
+@@ -112,7 +118,34 @@ TDS_OBJ =	$(TDS_OUT)\bulk.obj \
+ 		$(TDS_OUT)\vstrbuild.obj \
+ 		$(TDS_OUT)\write.obj 
+ 
+-one: $(DBLIB_OUT)\db-lib.lib 
++# not yet:	$(APPS_DIR)\bsqlodbc.c 
++
++APPS_SRC =	$(APPS_DIR)\bsqldb.c \
++		$(APPS_DIR)\datacopy.c \
++		$(APPS_DIR)\defncopy.c \
++		$(APPS_DIR)\freebcp.c \
++		$(APPS_DIR)\tsql.c 
++
++APPS_OBJ =	$(APPS_OUT)\bsqldb.obj \
++		$(APPS_OUT)\datacopy.obj \
++		$(APPS_OUT)\defncopy.obj \
++		$(APPS_OUT)\freebcp.obj \
++		$(APPS_OUT)\tsql.obj 
++
++APPS_EXE =	$(APPS_OUT)\bsqldb.exe \
++		$(APPS_OUT)\datacopy.exe \
++		$(APPS_OUT)\defncopy.exe \
++		$(APPS_OUT)\freebcp.exe \
++		$(APPS_OUT)\tsql.exe 
++
++db-lib: $(DBLIB_OUT)\db-lib.lib 
++
++apps: $(DBLIB_OUT)\db-lib.lib $(APPS_EXE)
++tsql: $(APPS_OUT)\tsql.exe 
++bsqldb: $(APPS_OUT)\bsqldb.exe 
++
++##(APPS_OUT)\bsqldb.exe: $(APPS_DIR)\bsqldb.exe $(DBLIB_OUT)\db-lib.lib
++# Don't know how to create this dependency without explicitly defining every output. 
+ 
+ #
+ # Sadly the environment settings for building for different architectures
+@@ -135,16 +168,33 @@ one: $(DBLIB_OUT)\db-lib.lib
+ all: build-win32d build-win32r build-win64d build-win64r
+ 
+ build-win32d: 
+-	$(MAKE) -fNmakefile -nologo PLATFORM=win32 CONFIGURATION=debug
++	$(MAKE) -fNmakefile -nologo apps PLATFORM=win32 CONFIGURATION=debug
+ build-win32r: 
+-	$(MAKE) -fNmakefile -nologo PLATFORM=win32 CONFIGURATION=release
++	$(MAKE) -fNmakefile -nologo apps PLATFORM=win32 CONFIGURATION=release
+ build-win64d: 
+-	$(MAKE) -fNmakefile -nologo PLATFORM=win64 CONFIGURATION=debug
++	$(MAKE) -fNmakefile -nologo apps PLATFORM=win64 CONFIGURATION=debug
+ build-win64r: 
+-	$(MAKE) -fNmakefile -nologo PLATFORM=win64 CONFIGURATION=release
++	$(MAKE) -fNmakefile -nologo apps PLATFORM=win64 CONFIGURATION=release
++
++clean:
++	@if "" equ "$(PLATFORM)" 	PLATFORM not defined, see comments in Nmakefile >&2 && exit 1
++	@if "" equ "$(CONFIGURATION)" 	CONFIGURATION not defined, see comments in Nmakefile >&2 && exit 1
++	if exist $(DBLIB_OUT) 		del /q $(DBLIB_OUT)\*.obj 
++	if exist $(REPLACEMENTS_OUT) 	del /q $(REPLACEMENTS_OUT)\*.obj 
++	if exist $(TDS_OUT) 		del /q $(TDS_OUT)\*.obj 
++	if exist $(APPS_OUT) 		del /q $(APPS_OUT)\*.obj $(APPS_OUT)\*.exe
+ 
+-$(DBLIB_OUT) $(REPLACEMENTS_OUT) $(TDS_OUT):
+-	md $@
++clean-app:
++	@if "" equ "$(PLATFORM)" 	PLATFORM not defined, see comments in Nmakefile >&2 && exit 1
++	@if "" equ "$(CONFIGURATION)" 	CONFIGURATION not defined, see comments in Nmakefile >&2 && exit 1
++	if exist $(APPS_OUT) 		del /q $(APPS_OUT)\*.obj $(APPS_OUT)\*.exe
++
++# Create output directories
++$(DBLIB_OUT) $(REPLACEMENTS_OUT) $(TDS_OUT) $(APPS_OUT):
++	@echo creating output directory for configuration: "$(PLATFORM)|$(CONFIGURATION)"
++	@if "" equ "$(PLATFORM)" 	PLATFORM not defined, see comments in Nmakefile >&2 && exit 1
++	@if "" equ "$(CONFIGURATION)" 	CONFIGURATION not defined, see comments in Nmakefile >&2 && exit 1
++	$(MKDIR) $@
+ 
+ $(DBLIB_OUT)\db-lib.lib: $(DBLIB_OUT) $(DBLIB_OBJ) $(REPLACEMENTS_OUT)\replacements.lib $(TDS_OUT)\tds.lib
+ 	@echo building $@ >&2
+@@ -159,18 +209,20 @@ $(TDS_OUT)\tds.lib: $(TDS_OUT) $(TDS_OBJ)
+ #
+ # set compiler flags
+ #
+-INC = 	-I "include" -I "include\x64"
+-FLG = 	-nologo	-W3 -Wp64 -c -EHsc -TC -Gm  -errorReport:prompt 
+-DEF = 	-D "_MBCS" -D "_LIB" \
+-	-D "_CRT_SECURE_NO_WARNINGS" \
++INC = 	-I "include" -I "win32" -I "include\x64" 
++FLG = 	-nologo	-W3 -Wp64 -EHsc -TC -Gm  -errorReport:prompt 
++DEF = 	-D "_MBCS" -D "_LIB" -D "WIN32" \
++	-D "_CRT_SECURE_NO_WARNINGS" -D _CRT_NONSTDC_NO_DEPRECATE \
+ 	-D "HAVE_CONFIG_H" \
+ 	-D "_FREETDS_LIBRARY_SOURCE" 
+ DBG = -MTd -Od -D "_DEBUG"  -ZI -RTC1	
+-REL = -MT  -O2 -D "_NDEBUG" -Zi	
++REL = -MT  -O2 -D "_NDEBUG" -Zi
++
++MSLIBS = Ws2_32.lib shell32.lib	
+ 
+ CC = cl $(FLG) $(DEF) $(INC)
+-CC32 = $(CC) -D "WIN32"	
+-CC64 = $(CC) 
++CC32 = $(CC)
++CC64 = $(CC)
+ 
+ ## Rules ##
+ 
+@@ -179,68 +231,91 @@ CC64 = $(CC)
+ #
+ #c.{$(DBLIB_DIR)\win32\debug}.obj::
+ {$(DBLIB_DIR)}.c{$(DBLIB_DIR)\win32\debug}.obj::
+-	$(CC32) $(DBG) 	-Fo"$(DBLIB_OUT)\\" \
+-			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$(CC32) -c $(DBG) 	-Fo"$(DBLIB_OUT)\\" \
++				-Fd"$(DBLIB_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(DBLIB_DIR)\}.c{$(DBLIB_DIR)\win32\release}.obj::
+-	$(CC32) $(REL) 	-Fo"$(DBLIB_OUT)\\" \
+-			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$(CC32) -c $(REL) 	-Fo"$(DBLIB_OUT)\\" \
++				-Fd"$(DBLIB_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(DBLIB_DIR)}.c{$(DBLIB_DIR)\x64\debug}.obj::
+-	$(CC64) $(DBG) 	-Fo"$(DBLIB_OUT)\\" \
+-			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$(CC64) -c $(DBG) 	-Fo"$(DBLIB_OUT)\\" \
++				-Fd"$(DBLIB_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(DBLIB_DIR)}.c{$(DBLIB_DIR)\x64\release}.obj::
+-	$(CC64) $(REL) 	-Fo"$(DBLIB_OUT)\\" \
+-			-Fd"$(DBLIB_OUT)\vc80.pdb" \
++	$(CC64) -c $(REL) 	-Fo"$(DBLIB_OUT)\\" \
++				-Fd"$(DBLIB_OUT)\vc80.pdb" \
+ 	$<
+ 
+ #
+ # replacements
+ #
+ {$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\win32\debug}.obj::
+-	$(CC32) $(DBG) 	-Fo"$(REPLACEMENTS_OUT)\\" \
+-			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$(CC32) -c $(DBG) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++				-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\win32\release}.obj::
+-	$(CC32) $(REL) 	-Fo"$(REPLACEMENTS_OUT)\\" \
+-			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$(CC32) -c $(REL) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++				-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\x64\debug}.obj::
+-	$(CC64) $(DBG) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++	$(CC64) -c $(DBG) 	-Fo"$(REPLACEMENTS_OUT)\\" \
+ 			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
+-	$<
++	$<		
+ 
+ {$(REPLACEMENTS_DIR)}.c{$(REPLACEMENTS_DIR)\x64\release}.obj::
+-	$(CC64) $(REL) 	-Fo"$(REPLACEMENTS_OUT)\\" \
+-			-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
++	$(CC64) -c $(REL) 	-Fo"$(REPLACEMENTS_OUT)\\" \
++				-Fd"$(REPLACEMENTS_OUT)\vc80.pdb" \
+ 	$<
+ 
+ #
+ # tds
+ #
+ {$(TDS_DIR)}.c{$(TDS_DIR)\win32\debug}.obj::
+-	$(CC32) $(DBG) 	-Fo"$(TDS_OUT)\\" \
+-			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$(CC32) -c $(DBG) 	-Fo"$(TDS_OUT)\\" \
++				-Fd"$(TDS_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(TDS_DIR)}.c{$(TDS_DIR)\win32\release}.obj::
+-	$(CC32) $(REL) 	-Fo"$(TDS_OUT)\\" \
+-			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$(CC32) -c $(REL) 	-Fo"$(TDS_OUT)\\" \
++				-Fd"$(TDS_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(TDS_DIR)}.c{$(TDS_DIR)\x64\debug}.obj::
+-	$(CC64) $(DBG) 	-Fo"$(TDS_OUT)\\" \
+-			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$(CC64) -c $(DBG) 	-Fo"$(TDS_OUT)\\" \
++				-Fd"$(TDS_OUT)\vc80.pdb" \
+ 	$<
+ 
+ {$(TDS_DIR)}.c{$(TDS_DIR)\x64\release}.obj::
+-	$(CC64) $(REL) 	-Fo"$(TDS_OUT)\\" \
+-			-Fd"$(TDS_OUT)\vc80.pdb" \
++	$(CC64) -c $(REL) 	-Fo"$(TDS_OUT)\\" \
++				-Fd"$(TDS_OUT)\vc80.pdb" \
+ 	$<
+ 
++#
++# Utilities
++#
++{$(APPS_DIR)}.c{$(APPS_DIR)\win32\debug}.exe:
++	@if not exist $(APPS_OUT) $(MKDIR) $(APPS_OUT)
++	$(CC32) $(DBG) 	-Fd"$(APPS_OUT)\vc80.pdb" -Fe$@ \
++	$< -link -LIBPATH:$(DBLIB_OUT) db-lib.lib $(MSLIBS)
++	
++{$(APPS_DIR)\}.c{$(APPS_DIR)\win32\release}.exe:
++	@if not exist $(APPS_OUT) $(MKDIR) $(APPS_OUT)
++	$(CC32) $(REL) -Fe$@ -Fd"$(APPS_OUT)\vc80.pdb" \
++	$< -link -LIBPATH:$(DBLIB_OUT) db-lib.lib $(MSLIBS)
++
++{$(APPS_DIR)}.c{$(APPS_DIR)\x64\debug}.exe:
++	@if not exist $(APPS_OUT) $(MKDIR) $(APPS_OUT)
++	$(CC64) $(DBG) -Fe$@ -Fd"$(APPS_OUT)\vc80.pdb" \
++	$< -link -LIBPATH:$(DBLIB_OUT) db-lib.lib $(MSLIBS)
++
++{$(APPS_DIR)}.c{$(APPS_DIR)\x64\release}.exe:
++	@if not exist $(APPS_OUT) $(MKDIR) $(APPS_OUT)
++	$(CC64) $(REL) -Fe$@ -Fd"$(APPS_OUT)\vc80.pdb" \
++	$< -link -LIBPATH:$(DBLIB_OUT) db-lib.lib $(MSLIBS)
++
+diff --git a/include/replacements.h b/include/replacements.h
+index 62ea20c..25ec0d8 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.20 2009/01/16 20:27:56 jklowden Exp $ */
++/* $Id: replacements.h,v 1.21 2010/01/08 22:08:01 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -97,7 +97,13 @@ char *tds_basename(char *path);
+ #endif
+ 
+ #if defined(WIN32)
++# if !defined(strncasecmp) 
++#     define  strncasecmp(x,y,z) strnicmp((x),(y),(z))
++# endif
+ int gettimeofday (struct timeval *tv, void *tz);
++int getopt(int argc, char * const argv[], const char *optstring);
++extern const char *optarg;
++extern int optind, offset, opterr;
+ #endif
+ 
+ #ifdef __cplusplus
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 630bda4..6ffc89f 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -45,9 +45,15 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.35 2009/04/18 19:35:38 jklowden Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.36 2010/01/08 22:08:01 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++#ifdef WIN32
++#define NULL_DEVICE "NUL:"
++#else
++#define NULL_DEVICE "/dev/null"
++#endif
++
+ int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, 
+ 		char *srvname, char *procname, int line);
+@@ -148,7 +154,7 @@ main(int argc, char *argv[])
+ 	if (options.fverbose) {
+ 		options.verbose = stderr;
+ 	} else {
+-		static const char null_device[] = "/dev/null";
++		static const char null_device[] = NULL_DEVICE;
+ 		options.verbose = fopen(null_device, "w");
+ 		if (options.verbose == NULL) {
+ 			fprintf(stderr, "%s:%d unable to open %s for verbose operation: %s\n", 
+@@ -756,7 +762,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	int ch;
+ 	int got_password = 0;
+ 
+-	extern char *optarg;
++	extern const char *optarg;
+ 
+ 	assert(options && argv);
+ 	
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 0f462ec..6f8ece3 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -17,6 +17,39 @@
+  * Boston, MA 02111-1307, USA.
+  */
+ 
++#ifdef MicrosoftsDbLib
++#ifdef WIN32
++# pragma warning( disable : 4142 )
++# include "win32.microsoft/have.h"
++# include "../../include/replacements.win32.hacked.h"
++# define strcasecmp(A, B) stricmp((A), (B))
++int getopt(int argc, const char *argv[], char *optstring);
++
++# ifndef DBNTWIN32
++#  define DBNTWIN32
++
++// As of Visual Studio .NET 2003, define WIN32_LEAN_AND_MEAN to avoid redefining LPCBYTE in sqlfront.h
++// Unless it was already defined, undefine it after windows.h has been included.  
++// (windows.h includes a bunch of stuff needed by sqlfront.h.  Bleh.)
++#  ifndef WIN32_LEAN_AND_MEAN
++#   define WIN32_LEAN_AND_MEAN
++#   define WIN32_LEAN_AND_MEAN_DEFINED_HERE
++#  endif
++#  include <windows.h>
++#  include <winsock2.h>
++#  ifdef WIN32_LEAN_AND_MEAN_DEFINED_HERE
++#   undef WIN32_LEAN_AND_MEAN_DEFINED_HERE
++#   undef WIN32_LEAN_AND_MEAN
++#  endif
++#  include <process.h>
++#  include <sqlfront.h>
++#  include <sqldb.h>
++
++#endif // DBNTWIN32
++# include "win32.microsoft/syb2ms.h"
++#endif
++#endif /* MicrosoftsDbLib */
++
+ #if HAVE_CONFIG_H
+ #include <config.h>
+ #endif
+@@ -46,16 +79,33 @@
+ 
+ #include <sqlfront.h>
+ #include <sybdb.h>
++#ifndef MicrosoftsDbLib
+ #include "replacements.h"
++#else
++
++#ifndef WIN32
++# include "replacements.h"
++#endif
++#endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.13 2009/01/07 02:58:47 jklowden Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.14 2010/01/08 22:08:01 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
++#ifndef MicrosoftsDbLib
+ static int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr);
+ static int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, 
+ 		char *srvname, char *procname, int line);
++#else
++static int err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, const char dberrstr[], const char oserrstr[]);
++static int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, const char msgtext[], 
++		const char srvname[], const char procname[], unsigned short int line);
++#endif /* MicrosoftsDbLib */
+ 
++#ifndef MicrosoftsDbLib
+ struct METADATA { char *name, *source, *format_string; int type, size; };
++#else
++struct METADATA { const char *name, *source, *format_string; int type, size; };
++#endif /* MicrosoftsDbLib */
+ 
+ typedef struct _options 
+ { 
+@@ -83,6 +133,7 @@ static void usage(const char invoked_as[]);
+ 
+ /* global variables */
+ OPTIONS options;
++char use_statement[512];
+ /* end global variables */
+ 
+ 
+@@ -101,8 +152,13 @@ main(int argc, char *argv[])
+ 	int i, nrows;
+ 
+ 	/* Initialize db-lib */
++#if WIN32 && defined(MicrosoftsDbLib)
++	LPCSTR msg = dbinit();	
++	if (msg == NULL) {
++#else 
+ 	erc = dbinit();	
+ 	if (erc == FAIL) {
++#endif /* MicrosoftsDbLib */
+ 		fprintf(stderr, "%s:%d: dbinit() failed\n", options.appname, __LINE__);
+ 		exit(1);
+ 	}
+@@ -120,14 +176,14 @@ main(int argc, char *argv[])
+ 	 * Override stdin, stdout, and stderr, as required 
+ 	 */
+ 	if (options.input_filename) {
+-		if (freopen(options.input_filename, "r", stdin) == NULL) {
++		if (freopen(options.input_filename, "rb", stdin) == NULL) {
+ 			fprintf(stderr, "%s: unable to open %s: %s\n", options.appname, options.input_filename, strerror(errno));
+ 			exit(1);
+ 		}
+ 	}
+ 
+ 	if (options.output_filename) {
+-		if (freopen(options.output_filename, "w", stdout) == NULL) {
++		if (freopen(options.output_filename, "wb", stdout) == NULL) {
+ 			fprintf(stderr, "%s: unable to open %s: %s\n", options.appname, options.output_filename, strerror(errno));
+ 			exit(1);
+ 		}
+@@ -147,14 +203,19 @@ main(int argc, char *argv[])
+ 	 * Read the procedure names and move their texts.  
+ 	 */
+ 	for (i=options.optind; i < argc; i++) {
++#ifndef MicrosoftsDbLib
+ 		static const char query[] = " select	c.text"
++#else
++		static const char query[] = " select	cast(c.text as text)"
++#endif /* MicrosoftsDbLib */
++					 ", number "
+ 					 " from	syscomments  as c"
+ 					 " join 	sysobjects as o"
+ 					 " on 		o.id = c.id"
+ 					 " where	o.name = '%s'"
+ 					 " and 	o.uid = user_id('%s')"
+ 					 " and		o.type not in ('U', 'S')" /* no user or system tables */
+-					 " order by 	c.colid"
++					 " order by 	c.number, c.colid"
+ 					;
+ 		static const char query_table[] = " execute sp_help '%s.%s' ";
+ 
+@@ -181,6 +242,7 @@ main(int argc, char *argv[])
+ 		
+ 		if (0 == nrows) {
+ 			erc = dbfcmd(dbproc, query_table, procedure.owner, procedure.name);
++			assert(SUCCEED == erc);
+ 			erc = dbsqlexec(dbproc);
+ 			if (erc == FAIL) {
+ 				fprintf(stderr, "%s:%d: dbsqlexec() failed\n", options.appname, __LINE__);
+@@ -315,18 +377,26 @@ print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure)
+ 				if (p) {
+ 					*p = '\0'; /* we don't care where it's located */
+ 				}
+-				/* Microsoft version: clustered, unique, primary key located on PRIMARY */
++				/* Microsoft version: [non]clustered[, unique][, primary key] located on PRIMARY */
+ 				p = strstr(index_description, "primary key");
+ 				if (p) {
+ 					fprimary = 1;
+ 					*p = '\0'; /* we don't care where it's located */
+ 					if ((p = strchr(index_description, ',')) != NULL) 
+ 						*p = '\0'; /* we use only the first term (clustered/nonclustered) */
++				} else {
++					/* reorder "unique" and "clustered" */
++					char nonclustered[] = "nonclustered", unique[] = "unique";
++					char *pclustering = nonclustered;
++					if (NULL == strstr(index_description, pclustering)) {
++						pclustering += 3;
++						if (NULL == strstr(index_description, pclustering)) 
++							*pclustering = '\0';
++					}
++					if (NULL == strstr(index_description, unique))
++						unique[0] = '\0';
++					sprintf(index_description, "%s %s", unique, pclustering);
+ 				}
+-				while ((p = strchr(index_description, ',')) != NULL) {
+-					*p = ' ';	/* and we don't need the comma */
+-				}
+-
+ 				/* Put it to a temporary file; we'll print it after the CREATE TABLE statement. */
+ 				if (fprimary) {
+ 					fprintf(create_index, "ALTER TABLE %s.%s ADD CONSTRAINT %s PRIMARY KEY %s (%s)\nGO\n\n", 
+@@ -399,7 +469,11 @@ print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure)
+ 	 * We've collected the description for the columns in the 'ddl' array.  
+ 	 * Now we'll print the CREATE TABLE statement in jkl's preferred format.  
+ 	 */
+-	printf("CREATE TABLE %s.%s\n", procedure->owner, procedure->name);
++	if (nrows == 0) {
++		fclose(create_index);
++		return nrows;
++	}
++	printf("%sCREATE TABLE %s.%s\n", use_statement, procedure->owner, procedure->name);
+ 	for (i=0; i < nrows; i++) {
+ 		static const char *varytypenames[] =    { "char"  		
+ 							, "nchar"  		
+@@ -460,15 +534,18 @@ print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure)
+ int /* return count of SQL text rows */
+ print_results(DBPROCESS *dbproc) 
+ {
+-	static const char empty_string[] = "";
+-	struct METADATA *metadata = NULL;
+-	struct DATA { char *buffer; int status; } *data = NULL;
+-	
+ 	RETCODE erc;
+ 	int row_code;
+-	int c, ret;
+ 	int iresultset;
+-	int nrows=0, ncols=0, ncomputeids;
++	int nrows=0;
++	int prior_procedure_number=1;
++	
++	/* bound variables */
++	enum column_id { ctext=1, number=2 };
++	char sql_text[8000];
++	int	 sql_text_status;
++	int	 procedure_number; /* for create proc abc;2 */
++	int	 procedure_number_status;
+ 	
+ 	/* 
+ 	 * Set up each result set with dbresults()
+@@ -479,120 +556,54 @@ print_results(DBPROCESS *dbproc)
+ 			return -1;
+ 		}
+ 
+-		if (SUCCEED != dbrows(dbproc)) {
++		if (SUCCEED != DBROWS(dbproc)) {
+ 			return 0;
+ 		}
+ 
+-		/* Free prior allocations, if any. */
+-		for (c=0; c < ncols; c++) {
+-			free(metadata[c].format_string);
+-			free(data[c].buffer);
+-		}
+-		free(metadata);
+-		metadata = NULL;
+-		free(data);
+-		data = NULL;
+-		ncols = 0;
+-		
+ 		/* 
+-		 * Allocate memory for metadata and bound columns 
++		 * Bind the columns to our variables.  
+ 		 */
+-		ncols = dbnumcols(dbproc);	
+-
+-		metadata = (struct METADATA*) calloc(ncols, sizeof(struct METADATA));
+-		assert(metadata);
+-
+-		data = (struct DATA*) calloc(ncols, sizeof(struct DATA));
+-		assert(data);
+-		
+-		/* The hard-coded queries don't generate compute rows. */
+-		ncomputeids = dbnumcompute(dbproc);
+-		assert(0 == ncomputeids);
+-
+-		/* 
+-		 * For each column, get its name, type, and size. 
+-		 * Allocate a buffer to hold the data, and bind the buffer to the column.
+-		 * "bind" here means to give db-lib the address of the buffer we want filled as each row is fetched.
+-		 */
+-
+-		for (c=0; c < ncols; c++) {
+-			int width;
+-			/* Get and print the metadata.  Optional: get only what you need. */
+-			char *name = dbcolname(dbproc, c+1);
+-			metadata[c].name = (name)? name : (char*) empty_string;
+-
+-			name = dbcolsource(dbproc, c+1);
+-			metadata[c].source = (name)? name : (char*) empty_string;
+-
+-			metadata[c].type = dbcoltype(dbproc, c+1);
+-			metadata[c].size = dbcollen(dbproc, c+1);
+-			assert(metadata[c].size != -1); /* -1 means indicates an out-of-range request*/
+-
+-#if 0
+-			fprintf(stderr, "%6d  %30s  %30s  %15s  %6d  %6d  \n", 
+-				c+1, metadata[c].name, metadata[c].source, dbprtype(metadata[c].type), 
+-				metadata[c].size,  dbvarylen(dbproc, c+1));
+-#endif 
+-			/* 
+-			 * Build the column header format string, based on the column width. 
+-			 * This is just one solution to the question, "How wide should my columns be when I print them out?"
+-			 */
+-			width = get_printable_size(metadata[c].type, metadata[c].size);
+-			if (width < strlen(metadata[c].name))
+-				width = strlen(metadata[c].name);
+-				
+-			ret = set_format_string(&metadata[c], (c+1 < ncols)? "  " : "\n");
+-			if (ret <= 0) {
+-				fprintf(stderr, "%s:%d: asprintf(), column %d failed\n", options.appname, __LINE__, c+1);
+-				return -1;
+-			}
+-
+-			/* 
+-			 * Bind the column to our variable.
+-			 * We bind everything to strings, because we want db-lib to convert everything to strings for us.
+-			 * If you're performing calculations on the data in your application, you'd bind the numeric data
+-			 * to C integers and floats, etc. instead. 
+-			 * 
+-			 * It is not necessary to bind to every column returned by the query.  
+-			 * Data in unbound columns are simply never copied to the user's buffers and are thus 
+-			 * inaccesible to the application.  
+-			 */
+-
+-			data[c].buffer = calloc(1, metadata[c].size);
+-			assert(data[c].buffer);
+-
+-			erc = dbbind(dbproc, c+1, STRINGBIND, -1, (BYTE *) data[c].buffer);
+-			if (erc == FAIL) {
+-				fprintf(stderr, "%s:%d: dbbind(), column %d failed\n", options.appname, __LINE__, c+1);
+-				return -1;
+-			}
++		if (sizeof(sql_text) < dbcollen(dbproc, ctext) ) {
++			assert(sizeof(sql_text) >= dbcollen(dbproc, ctext));
++			return 0;
++		}
++		erc = dbbind(dbproc, ctext, NTBSTRINGBIND, sizeof(sql_text), (BYTE *) sql_text);
++		if (erc == FAIL) {
++			fprintf(stderr, "%s:%d: dbbind(), column %d failed\n", options.appname, __LINE__, ctext);
++			return -1;
++		}
++		erc = dbnullbind(dbproc, ctext, &sql_text_status);
++		if (erc == FAIL) {
++			fprintf(stderr, "%s:%d: dbnullbind(), column %d failed\n", options.appname, __LINE__, ctext);
++			return -1;
++		}
+ 
+-			erc = dbnullbind(dbproc, c+1, &data[c].status);
+-			if (erc == FAIL) {
+-				fprintf(stderr, "%s:%d: dbnullbind(), column %d failed\n", options.appname, __LINE__, c+1);
+-				return -1;
+-			}
++		erc = dbbind(dbproc, number, INTBIND, -1, (BYTE *) &procedure_number);
++		if (erc == FAIL) {
++			fprintf(stderr, "%s:%d: dbbind(), column %d failed\n", options.appname, __LINE__, number);
++			return -1;
++		}
++		erc = dbnullbind(dbproc, number, &procedure_number_status);
++		if (erc == FAIL) {
++			fprintf(stderr, "%s:%d: dbnullbind(), column %d failed\n", options.appname, __LINE__, number);
++			return -1;
+ 		}
+ 
+ 		/* 
+ 		 * Print the data to stdout.  
+ 		 */
+-		for (;(row_code = dbnextrow(dbproc)) != NO_MORE_ROWS; nrows++) {
++		fprintf(stdout, "%s", use_statement);
++		for (;(row_code = dbnextrow(dbproc)) != NO_MORE_ROWS; nrows++, prior_procedure_number = procedure_number) {
+ 			switch (row_code) {
+ 			case REG_ROW:
+-				for (c=0; c < ncols; c++) {
+-					switch (data[c].status) { /* handle nulls */
+-					case -1: 	/* is null */
+-						fprintf(stderr, "defncopy: error: unexpected NULL row in SQL text\n");
+-						break;
+-					case 0:	/* OK */
+-					default:	/* >1 is datlen when buffer is too small */
+-						fprintf(stdout, "%s", data[c].buffer);
+-						break;
+-					}
++				if ( -1 == sql_text_status) { 
++					fprintf(stderr, "defncopy: error: unexpected NULL row in SQL text\n");
++				} else {
++					if (prior_procedure_number != procedure_number)
++						fprintf(stdout, "\nGO\n");
++					fprintf(stdout, "%s", sql_text);
+ 				}
+ 				break;
+-				
+ 			case BUF_FULL:
+ 			default:
+ 				fprintf(stderr, "defncopy: error: expected REG_ROW (%d), got %d instead\n", REG_ROW, row_code);
+@@ -601,13 +612,17 @@ print_results(DBPROCESS *dbproc)
+ 			} /* row_code */
+ 
+ 		} /* wend dbnextrow */
+-		fprintf(stdout, "\n");
++		fprintf(stdout, "\nGO\n");
+ 
+ 	} /* wend dbresults */
+ 	return nrows;
+ }
+ 
++#ifndef MicrosoftsDbLib
+ static int
++#else
++static size_t
++#endif /* MicrosoftsDbLib */
+ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+ {
+ 	switch (type) {
+@@ -665,7 +680,12 @@ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+ static int
+ set_format_string(struct METADATA * meta, const char separator[])
+ {
++#ifndef MicrosoftsDbLib
+ 	int width, ret;
++#else
++	size_t width;
++	int ret;
++#endif /* MicrosoftsDbLib */
+ 	const char *size_and_width;
+ 	assert(meta);
+ 
+@@ -717,6 +737,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ {
+ 	LOGINREC *login;
+ 	int ch;
++	int fdomain = TRUE;
+ 
+ 	extern char *optarg;
+ 	extern int optind;
+@@ -734,9 +755,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	
+ 	DBSETLAPP(login, options->appname);
+ 	
+-	if (-1 == gethostname(options->hostname, sizeof(options->hostname))) {
+-		perror("unable to get hostname");
+-	} else {
++	if (-1 != gethostname(options->hostname, sizeof(options->hostname))) {
+ 		DBSETLHOST(login, options->hostname);
+ 	}
+ 
+@@ -744,9 +763,11 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 		switch (ch) {
+ 		case 'U':
+ 			DBSETLUSER(login, optarg);
++			fdomain = FALSE;
+ 			break;
+ 		case 'P':
+ 			DBSETLPWD(login, optarg);
++			fdomain = FALSE;
+ 			break;
+ 		case 'S':
+ 			options->servername = strdup(optarg);
+@@ -776,6 +797,12 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 		}
+ 	}
+ 
++#ifdef MicrosoftsDbLib
++#if WIN32
++	if (fdomain) 
++		DBSETLSECURE(login);
++#endif
++#endif /* MicrosoftsDbLib */
+ 	if (!options->servername) {
+ 		usage(options->appname);
+ 		exit(1);
+@@ -787,7 +814,11 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ }
+ 
+ static int
++#ifndef MicrosoftsDbLib
+ err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrstr, char *oserrstr)
++#else
++err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, const char dberrstr[], const char oserrstr[])
++#endif /* MicrosoftsDbLib */
+ {
+ 
+ 	if (dberr) {
+@@ -804,7 +835,12 @@ err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr, char *dberrs
+ }
+ 
+ static int
++#ifndef MicrosoftsDbLib
+ msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *msgtext, char *srvname, char *procname, int line)
++#else
++msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, const char msgtext[], 
++		const char srvname[], const char procname[], unsigned short int line)
++#endif /* MicrosoftsDbLib */
+ {
+ 	char *dbname, *endquote; 
+ 
+@@ -817,7 +853,7 @@ msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, char *m
+ 		if (!endquote)
+ 			break;
+ 		*endquote = '\0';
+-		fprintf(stdout, "USE %s\nGO\n\n", dbname);
++		sprintf(use_statement, "USE %s\nGO\n\n", dbname);
+ 		return 0;		
+ 
+ 	case 0:	/* Ignore print messages */
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index e337b62..309879c 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -85,7 +85,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.130 2009/12/05 20:25:31 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.131 2010/01/08 22:08:01 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -385,6 +385,10 @@ get_default_instance_port(const char hostname[])
+ 	return tds7_get_instance_port(ip, "MSSQLSERVER");
+ }
+ 
++#if !defined(LC_ALL)
++# define LC_ALL 0
++#endif
++
+ static void
+ populate_login(TDSLOGIN * login, int argc, char **argv)
+ {
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 6610c5f..0d8b661 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.151 2009/11/26 09:47:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.152 2010/01/08 22:08:01 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -271,18 +271,22 @@ tds_try_conf_file(const char *path, const char *how, const char *server, TDSCONN
+ 	int found = 0;
+ 	FILE *in;
+ 
+-	if ((in = fopen(path, "r")) != NULL) {
+-		tdsdump_log(TDS_DBG_INFO1, "Found conf file '%s' %s.\n", path, how);
+-		found = tds_read_conf_sections(in, server, connection);
++	if ((in = fopen(path, "r")) == NULL) {
++		tdsdump_log(TDS_DBG_INFO1, "Could not open '%s' (%s).\n", path, how);
++		return found;
++	}
+ 
+-		if (found) {
+-			tdsdump_log(TDS_DBG_INFO1, "Success: [%s] defined in %s.\n", server, path);
+-		} else {
+-			tdsdump_log(TDS_DBG_INFO2, "[%s] not found.\n", server);
+-		}
++	tdsdump_log(TDS_DBG_INFO1, "Found conf file '%s' %s.\n", path, how);
++	found = tds_read_conf_sections(in, server, connection);
+ 
+-		fclose(in);
++	if (found) {
++		tdsdump_log(TDS_DBG_INFO1, "Success: [%s] defined in %s.\n", server, path);
++	} else {
++		tdsdump_log(TDS_DBG_INFO2, "[%s] not found.\n", server);
+ 	}
++
++	fclose(in);
++
+ 	return found;
+ }
+ 
+diff --git a/src/tds/hmac_md5.c b/src/tds/hmac_md5.c
+index f6e86e5..a08929f 100644
+--- a/src/tds/hmac_md5.c
++++ b/src/tds/hmac_md5.c
+@@ -17,7 +17,11 @@
+  * Boston, MA 02111-1307, USA.
+  */
+ 
+-/* $Id: hmac_md5.c,v 1.1 2008/07/30 08:02:55 freddy77 Exp $ */
++/* $Id: hmac_md5.c,v 1.2 2010/01/08 22:08:01 jklowden Exp $ */
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif /* HAVE_CONFIG_H */
+ 
+ #include "tds.h"
+ #include "md5.h"
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 43987a4..682816b 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.193 2009/11/26 09:47:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.194 2010/01/08 22:08:01 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -630,12 +630,12 @@ winsock_initialized(void)
+ 		return 1;
+ 
+ 	if (WSANOTINITIALISED != (erc = WSAGetLastError())) {
+-		fprintf(stderr, "tds_init_winsock: WSAEnumProtocols failed with %d(%s)\n", erc, tds_prwsaerror(erc) ); 
++		fprintf(stderr, "tds_init_winsock: WSAEnumProtocols failed with %d (%s)\n", erc, tds_prwsaerror(erc) ); 
+ 		return 0;
+ 	}
+ 	
+ 	if (SOCKET_ERROR == (erc = WSAStartup(requested_version, &wsa_data))) {
+-		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d(%s)\n", erc, tds_prwsaerror(erc) ); 
++		fprintf(stderr, "tds_init_winsock: WSAStartup failed with %d (%s)\n", erc, tds_prwsaerror(erc) ); 
+ 		return 0;
+ 	}
+ #endif
+diff --git a/src/tds/net.c b/src/tds/net.c
+index f93cdff..57040fc 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.95 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.96 2010/01/08 22:08:01 jklowden Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -133,6 +133,8 @@ static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned i
+  */
+ 
+ #ifdef WIN32
++const char * tds_prwsaerror( int erc );
++#define strerror(x) tds_prwsaerror((x))
+ int
+ _tds_socket_init(void)
+ {
+@@ -309,7 +311,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 		goto not_available;
+ 	}
+ 	if (len != 0) {
+-		tds->oserr = sock_errno;
++		tds->oserr = len;
+ 		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) reported: %s\n", strerror(len));
+ 		goto not_available;
+ 	}
+diff --git a/src/tds/numeric.c b/src/tds/numeric.c
+index 148a0a8..5dec69e 100644
+--- a/src/tds/numeric.c
++++ b/src/tds/numeric.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: numeric.c,v 1.45 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: numeric.c,v 1.46 2010/01/08 22:08:01 jklowden Exp $");
+ 
+ /* 
+  * these routines use arrays of unsigned char to handle arbitrary
+@@ -366,6 +366,7 @@ tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s)
+ #endif
+ 
+ /* include to check limits */
++
+ #include "num_limits.h"
+ 
+ static int
+diff --git a/src/tds/token.c b/src/tds/token.c
+index fa9ae14..8ee7d90 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -38,11 +38,18 @@
+ #include "tdsiconv.h"
+ #include "tds_checks.h"
+ #include "replacements.h"
++
++/* Microsoft's linker complains about missing tds_get_varint_size */
++#ifdef WIN32
++# define TDS_GET_VARINT_SIZE_ONLY
++# include "types.h"
++#endif
++
+ #ifdef DMALLOC
+-#include <dmalloc.h>
++ <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.376 2009/11/26 09:07:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.377 2010/01/08 22:08:01 jklowden Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+diff --git a/win32/config.h b/win32/config.h
+index cc63345..34ade6a 100644
+--- a/win32/config.h
++++ b/win32/config.h
+@@ -219,7 +219,7 @@
+ #define TDS_I64_FORMAT "I64d"
+ 
+ /* Version number of package */
+-#define VERSION "0.65"
++#define VERSION "0.83.dev"
+ 
+ /* Define to 1 if your processor stores words with the most significant byte
+    first (like Motorola and SPARC, unlike Intel and VAX). */
+@@ -241,3 +241,9 @@
+ #define inline __inline
+ #endif
+ 
++#include <winsock2.h>
++#include <BaseTsd.h>
++
++typedef SSIZE_T ssize_t;
++
++
+
+commit 42df381716df66b01e114a270976441b7a378a0a
+Author: jklowden <jklowden>
+Date:   Fri Jan 8 22:41:34 2010 +0000
+
+    tsql works in win32, optarg is not const
+
+diff --git a/ChangeLog b/ChangeLog
+index 9429ddf..70f4381 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jan  8 17:38:50 EST 2010	JK Lowden <jklowden@freetds.org>
++	* include/replacements.h src/apps/bsqldb.c src/tds/mem.c
++	- tsql works in win32, optarg is not const
++
+ Fri Jan  8 17:05:24 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* Nmakefile include/replacements.h win32/config.h
+ 	* src/apps/bsqldb.c src/apps/defncopy.c src/apps/tsql.c
+@@ -2043,4 +2047,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2920 2010/01/08 22:07:59 jklowden Exp $
++$Id: ChangeLog,v 1.2921 2010/01/08 22:41:34 jklowden Exp $
+diff --git a/include/replacements.h b/include/replacements.h
+index 25ec0d8..5a95294 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.21 2010/01/08 22:08:01 jklowden Exp $ */
++/* $Id: replacements.h,v 1.22 2010/01/08 22:41:35 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -102,7 +102,7 @@ char *tds_basename(char *path);
+ # endif
+ int gettimeofday (struct timeval *tv, void *tz);
+ int getopt(int argc, char * const argv[], const char *optstring);
+-extern const char *optarg;
++extern char *optarg;
+ extern int optind, offset, opterr;
+ #endif
+ 
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 6ffc89f..3532c8b 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -45,7 +45,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.36 2010/01/08 22:08:01 jklowden Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.37 2010/01/08 22:41:35 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef WIN32
+@@ -762,7 +762,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	int ch;
+ 	int got_password = 0;
+ 
+-	extern const char *optarg;
++	extern char *optarg;
+ 
+ 	assert(options && argv);
+ 	
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 682816b..588c8b6 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.194 2010/01/08 22:08:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.195 2010/01/08 22:41:35 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -622,7 +622,7 @@ winsock_initialized(void)
+ #if defined(_WIN32) || defined(_WIN64)
+ 	WSADATA wsa_data;
+ 	int erc;
+-	WSAPROTOCOL_INFO protocols[8];
++	WSAPROTOCOL_INFO protocols[64];
+ 	DWORD how_much = sizeof(protocols);
+ 	WORD requested_version = MAKEWORD(2, 2);
+ 	 
+
+commit ff5b3f85397394c86cefd204b728d932cb356104
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 09:17:46 2010 +0000
+
+    Fix possible wrong error report if malloc does not set errno
+
+diff --git a/ChangeLog b/ChangeLog
+index 70f4381..e460567 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jan  9 10:17:41 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/vasprintf.c:
++	- Fix possible wrong error report if malloc does not set errno
++
+ Fri Jan  8 17:38:50 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* include/replacements.h src/apps/bsqldb.c src/tds/mem.c
+ 	- tsql works in win32, optarg is not const
+@@ -2047,4 +2051,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2921 2010/01/08 22:41:34 jklowden Exp $
++$Id: ChangeLog,v 1.2922 2010/01/09 09:17:46 freddy77 Exp $
+diff --git a/src/replacements/vasprintf.c b/src/replacements/vasprintf.c
+index 9183903..7312519 100644
+--- a/src/replacements/vasprintf.c
++++ b/src/replacements/vasprintf.c
+@@ -15,6 +15,10 @@
+ #include <stdlib.h>
+ #endif /* HAVE_STDLIB_H */
+ 
++#if HAVE_ERRNO_H
++#include <errno.h>
++#endif /* HAVE_ERRNO_H */
++
+ #if HAVE_STRING_H
+ #include <string.h>
+ #endif /* HAVE_STRING_H */
+@@ -30,7 +34,7 @@
+ #include "tds_sysdep_private.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: vasprintf.c,v 1.20 2009/01/21 08:34:01 freddy77 Exp $");
++TDS_RCSID(var, "$Id: vasprintf.c,v 1.21 2010/01/09 09:17:47 freddy77 Exp $");
+ 
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef HAVE_VSNPRINTF
+@@ -57,6 +61,7 @@ vasprintf(char **ret, const char *fmt, va_list ap)
+ 	buflen = chunks * CHUNKSIZE;
+ 	for (;;) {
+ 		if ((buf = malloc(buflen)) == NULL) {
++			errno = ENOMEM;
+ 			*ret = NULL;
+ 			return -1;
+ 		}
+@@ -109,8 +114,10 @@ vasprintf(char **ret, const char *fmt, va_list ap)
+ 
+ 	if (len < 0)
+ 		return len;
+-	if ((buf = malloc(len + 1)) == NULL)
++	if ((buf = malloc(len + 1)) == NULL) {
++		errno = ENOMEM;
+ 		return -1;
++	}
+ 	if (vsprintf(buf, fmt, ap) != len)
+ 		return -1;
+ 	*ret = buf;
+
+commit ee12d1a80af49b94767fa1e22eae83baf6740a82
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 09:33:17 2010 +0000
+
+    Avoid double definition
+
+diff --git a/ChangeLog b/ChangeLog
+index e460567..5368f07 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan  9 10:33:10 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: Avoid double definition
++
+ Sat Jan  9 10:17:41 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/vasprintf.c:
+ 	- Fix possible wrong error report if malloc does not set errno
+@@ -2051,4 +2054,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2922 2010/01/09 09:17:46 freddy77 Exp $
++$Id: ChangeLog,v 1.2923 2010/01/09 09:33:17 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 57040fc..6994c37 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003  Brian Bruns
+- * Copyright (C) 2004, 2005, 2006, 2007, 2008  Ziglio Frediano
++ * Copyright (C) 2004-2010  Ziglio Frediano
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.96 2010/01/08 22:08:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.97 2010/01/09 09:33:17 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -133,7 +133,6 @@ static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned i
+  */
+ 
+ #ifdef WIN32
+-const char * tds_prwsaerror( int erc );
+ #define strerror(x) tds_prwsaerror((x))
+ int
+ _tds_socket_init(void)
+
+commit 9fd342f065796bd75bbe97147cd1e795c799c8f8
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 09:50:16 2010 +0000
+
+    Defined and use a sock_strerror
+
+diff --git a/ChangeLog b/ChangeLog
+index 5368f07..2d23c54 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jan  9 10:50:09 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/tds/net.c:
++	- Defined and use a sock_strerror
++
+ Sat Jan  9 10:33:10 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: Avoid double definition
+ 
+@@ -2054,4 +2058,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2923 2010/01/09 09:33:17 freddy77 Exp $
++$Id: ChangeLog,v 1.2924 2010/01/09 09:50:16 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 0b63187..d0eb302 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -1,5 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
++ * Copyright (C) 2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -20,7 +21,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.29 2009/02/27 10:46:24 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.30 2010/01/09 09:50:16 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -84,6 +85,7 @@ void _tds_socket_done(void);
+ #define TDSSOCK_EINTR WSAEINTR
+ #define TDSSOCK_EINPROGRESS WSAEWOULDBLOCK
+ #define sock_errno WSAGetLastError()
++#define sock_strerror(n) tds_prwsaerror(n)
+ #ifndef __MINGW32__
+ typedef DWORD pid_t;
+ #endif
+@@ -116,6 +118,10 @@ typedef DWORD pid_t;
+ #define sock_errno errno
+ #endif
+ 
++#ifndef sock_strerror
++#define sock_strerror(n) strerror(n)
++#endif
++
+ #ifndef TDSSOCK_EINTR
+ #define TDSSOCK_EINTR EINTR
+ #endif
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 6994c37..b664db2 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.97 2010/01/09 09:33:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.98 2010/01/09 09:50:16 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -133,7 +133,6 @@ static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned i
+  */
+ 
+ #ifdef WIN32
+-#define strerror(x) tds_prwsaerror((x))
+ int
+ _tds_socket_init(void)
+ {
+@@ -225,7 +224,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 
+ 	if (TDS_IS_SOCKET_INVALID(tds->s = socket(AF_INET, SOCK_STREAM, 0))) {
+ 		tds->oserr = sock_errno;
+-		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", strerror(sock_errno));
++		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", sock_strerror(sock_errno));
+ 		return TDSESOCK;
+ 	}
+ 
+@@ -275,7 +274,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
+ 	} else {
+ 		tds->oserr = sock_errno;
+-		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", strerror(sock_errno));
++		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", sock_strerror(sock_errno));
+ #if DEBUGGING_CONNECTING_PROBLEM
+ 		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != EINPROGRESS) {
+ 			tdsdump_dump_buf(TDS_DBG_ERROR, "Contents of sockaddr_in", &sin, sizeof(sin));
+@@ -306,12 +305,12 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	len = 0;
+ 	if (tds_getsockopt(tds->s, SOL_SOCKET, SO_ERROR, (char *) &len, &optlen) != 0) {
+ 		tds->oserr = sock_errno;
+-		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) failed: %s\n", strerror(sock_errno));
++		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) failed: %s\n", sock_strerror(sock_errno));
+ 		goto not_available;
+ 	}
+ 	if (len != 0) {
+ 		tds->oserr = len;
+-		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) reported: %s\n", strerror(len));
++		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) reported: %s\n", sock_strerror(len));
+ 		goto not_available;
+ 	}
+ 
+@@ -435,7 +434,7 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 				break;	/* let interrupt handler be called */
+ 			default: /* documented: EFAULT, EBADF, EINVAL */
+ 				tdsdump_log(TDS_DBG_ERROR, "error: %s returned %d, \"%s\"\n", 
+-						method, sock_errno, strerror(sock_errno));
++						method, sock_errno, sock_strerror(sock_errno));
+ 				return rc;
+ 			}
+ 		}
+@@ -711,7 +710,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 
+ 			assert(nput < 0);
+ 			
+-			tdsdump_log(TDS_DBG_NETWORK, "send(2) failed: %d (%s)\n", sock_errno, strerror(sock_errno));
++			tdsdump_log(TDS_DBG_NETWORK, "send(2) failed: %d (%s)\n", sock_errno, sock_strerror(sock_errno));
+ 			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
+ 			tds_close_socket(tds);
+ 			return -1;
+@@ -719,7 +718,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 		} else if (rc < 0) {
+ 			if (sock_errno == EAGAIN) /* shouldn't happen, but OK, retry */
+ 				continue;
+-			tdsdump_log(TDS_DBG_NETWORK, "select(2) failed: %d (%s)\n", sock_errno, strerror(sock_errno));
++			tdsdump_log(TDS_DBG_NETWORK, "select(2) failed: %d (%s)\n", sock_errno, sock_strerror(sock_errno));
+ 			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
+ 			tds_close_socket(tds);
+ 			return -1;
+@@ -855,7 +854,7 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 
+ 	/* create an UDP socket */
+ 	if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_DGRAM, 0))) {
+-		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", strerror(sock_errno));
++		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", sock_strerror(sock_errno));
+ 		return 0;
+ 	}
+ 
+@@ -1018,7 +1017,7 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 
+ 	/* create an UDP socket */
+ 	if (TDS_IS_SOCKET_INVALID(s = socket(AF_INET, SOCK_DGRAM, 0))) {
+-		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", strerror(sock_errno));
++		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", sock_strerror(sock_errno));
+ 		return 0;
+ 	}
+ 
+
+commit 019faad9306d118ea3fa6fe84792289ad30d4fc5
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 10:55:44 2010 +0000
+
+    cleanup defncopy
+
+diff --git a/ChangeLog b/ChangeLog
+index 2d23c54..6b13925 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan  9 11:55:34 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/defncopy.c: cleanup defncopy
++
+ Sat Jan  9 10:50:09 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h src/tds/net.c:
+ 	- Defined and use a sock_strerror
+@@ -2058,4 +2061,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2924 2010/01/09 09:50:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2925 2010/01/09 10:55:44 freddy77 Exp $
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 6f8ece3..74fb31e 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -1,5 +1,5 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 2004  James K. Lowden
++ * Copyright (C) 2004-2010  James K. Lowden
+  *
+  * This program  is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU General Public
+@@ -88,7 +88,7 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.14 2010/01/08 22:08:01 jklowden Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.15 2010/01/09 10:55:44 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -102,9 +102,9 @@ static int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severi
+ #endif /* MicrosoftsDbLib */
+ 
+ #ifndef MicrosoftsDbLib
+-struct METADATA { char *name, *source, *format_string; int type, size; };
++struct METADATA { char *name, *source; int type, size; };
+ #else
+-struct METADATA { const char *name, *source, *format_string; int type, size; };
++struct METADATA { const char *name, *source; int type, size; };
+ #endif /* MicrosoftsDbLib */
+ 
+ typedef struct _options 
+@@ -127,8 +127,6 @@ static int print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure);
+ static int print_results(DBPROCESS *dbproc);
+ static LOGINREC* get_login(int argc, char *argv[], OPTIONS *poptions);
+ static void parse_argument(const char argument[], PROCEDURE* procedure);
+-static int set_format_string(struct METADATA * meta, const char separator[]);
+-static int get_printable_size(int type, int size);
+ static void usage(const char invoked_as[]);
+ 
+ /* global variables */
+@@ -618,89 +616,6 @@ print_results(DBPROCESS *dbproc)
+ 	return nrows;
+ }
+ 
+-#ifndef MicrosoftsDbLib
+-static int
+-#else
+-static size_t
+-#endif /* MicrosoftsDbLib */
+-get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+-{
+-	switch (type) {
+-	case SYBINTN:
+-		switch (size) {
+-		case 1:
+-			return 3;
+-		case 2:
+-			return 6;
+-		case 4:
+-			return 11;
+-		case 8:
+-			return 21;
+-		}
+-	case SYBINT1:
+-		return 3;
+-	case SYBINT2:
+-		return 6;
+-	case SYBINT4:
+-		return 11;
+-	case SYBINT8:
+-		return 21;
+-	case SYBVARCHAR:
+-	case SYBCHAR:
+-		return size;
+-	case SYBFLT8:
+-		return 11;	/* FIX ME -- we do not track precision */
+-	case SYBREAL:
+-		return 11;	/* FIX ME -- we do not track precision */
+-	case SYBMONEY:
+-		return 12;	/* FIX ME */
+-	case SYBMONEY4:
+-		return 12;	/* FIX ME */
+-	case SYBDATETIME:
+-		return 26;	/* FIX ME */
+-	case SYBDATETIME4:
+-		return 26;	/* FIX ME */
+-#if 0	/* seems not to be exported to sybdb.h */
+-	case SYBBITN:
+-#endif
+-	case SYBBIT:
+-		return 1;
+-		/* FIX ME -- not all types present */
+-	default:
+-		return 0;
+-	}
+-
+-}
+-
+-/** 
+- * Build the column header format string, based on the column width. 
+- * This is just one solution to the question, "How wide should my columns be when I print them out?"
+- */
+-#define is_character_data(x)   (x==SYBTEXT || x==SYBCHAR || x==SYBVARCHAR)
+-static int
+-set_format_string(struct METADATA * meta, const char separator[])
+-{
+-#ifndef MicrosoftsDbLib
+-	int width, ret;
+-#else
+-	size_t width;
+-	int ret;
+-#endif /* MicrosoftsDbLib */
+-	const char *size_and_width;
+-	assert(meta);
+-
+-	/* right justify numbers, left justify strings */
+-	size_and_width = is_character_data(meta->type)? "%%-%d.%ds%s" : "%%%d.%ds%s";
+-	
+-	width = get_printable_size(meta->type, meta->size);
+-	if (width < strlen(meta->name))
+-		width = strlen(meta->name);
+-
+-	ret = asprintf(&meta->format_string, size_and_width, width, width, separator);
+-		       
+-	return ret;
+-}
+-
+ static void
+ usage(const char invoked_as[])
+ {
+
+commit 1eb19dddbf2b7b7fdc572ee53be312082eb9301f
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 13:10:30 2010 +0000
+
+    Cleanup, statify
+
+diff --git a/ChangeLog b/ChangeLog
+index 6b13925..40ec57d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan  9 14:10:18 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/defncopy.c: Cleanup, statify
++
+ Sat Jan  9 11:55:34 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/defncopy.c: cleanup defncopy
+ 
+@@ -2061,4 +2064,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2925 2010/01/09 10:55:44 freddy77 Exp $
++$Id: ChangeLog,v 1.2926 2010/01/09 13:10:30 freddy77 Exp $
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 74fb31e..bcb810f 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -88,7 +88,7 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.15 2010/01/09 10:55:44 freddy77 Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.16 2010/01/09 13:10:30 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -101,12 +101,6 @@ static int msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severi
+ 		const char srvname[], const char procname[], unsigned short int line);
+ #endif /* MicrosoftsDbLib */
+ 
+-#ifndef MicrosoftsDbLib
+-struct METADATA { char *name, *source; int type, size; };
+-#else
+-struct METADATA { const char *name, *source; int type, size; };
+-#endif /* MicrosoftsDbLib */
+-
+ typedef struct _options 
+ { 
+ 	int 	optind;
+@@ -128,10 +122,11 @@ static int print_results(DBPROCESS *dbproc);
+ static LOGINREC* get_login(int argc, char *argv[], OPTIONS *poptions);
+ static void parse_argument(const char argument[], PROCEDURE* procedure);
+ static void usage(const char invoked_as[]);
++static char * rtrim(char * s);
+ 
+ /* global variables */
+-OPTIONS options;
+-char use_statement[512];
++static OPTIONS options;
++static char use_statement[512];
+ /* end global variables */
+ 
+ 
+@@ -283,9 +278,7 @@ parse_argument(const char argument[], PROCEDURE* procedure)
+ 	}
+ }
+ 
+-char * rtrim(char * s);
+-
+-char *
++static char *
+ rtrim(char * s)
+ {
+ 	char *p = strchr(s, ' ');
+@@ -312,7 +305,7 @@ rtrim(char * s)
+  *	10. Access_Rule_name       Collation
+  *	11. Identity	
+  */
+-int
++static int
+ print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure) 
+ {
+  	struct DDL { char *name, *type, *length, *precision, *scale, *nullable; } *ddl = NULL;
+@@ -529,7 +522,7 @@ print_ddl(DBPROCESS *dbproc, PROCEDURE *procedure)
+ 	return nrows;
+ }
+ 
+-int /* return count of SQL text rows */
++static int /* return count of SQL text rows */
+ print_results(DBPROCESS *dbproc) 
+ {
+ 	RETCODE erc;
+
+commit 91ba3d659ee444871ac6ebbc0cb8adcede277588
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 14:32:12 2010 +0000
+
+    Ignore terminator pointer if terminator len <= 0
+
+diff --git a/ChangeLog b/ChangeLog
+index 40ec57d..9509afe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan  9 15:31:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: Ignore terminator pointer if terminator len <= 0
++
+ Sat Jan  9 14:10:18 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/defncopy.c: Cleanup, statify
+ 
+@@ -2064,4 +2067,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2926 2010/01/09 13:10:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2927 2010/01/09 14:32:12 freddy77 Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index f9fa780..1aa97c7 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -1,5 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
++ * Copyright (C) 2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -61,7 +62,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.189 2009/11/23 08:50:28 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.190 2010/01/09 14:32:12 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -390,8 +391,8 @@ bcp_colfmt(DBPROCESS * dbproc, int host_colnum, int host_type, int host_prefixle
+ 	BCP_HOSTCOLINFO *hostcol;
+ 	BYTE *terminator = NULL;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "bcp_colfmt(%p, %d, %d, %d, %d, %p)\n", 
+-		    dbproc, host_colnum, host_type, host_prefixlen, (int) host_collen, host_term);
++	tdsdump_log(TDS_DBG_FUNC, "bcp_colfmt(%p, %d, %d, %d, %d, %p, %d, %d)\n", 
++		    dbproc, host_colnum, host_type, host_prefixlen, (int) host_collen, host_term, host_termlen, table_colnum);
+ 	CHECK_DBPROC();
+ 	DBPERROR_RETURN(IS_TDSDEAD(dbproc->tds_socket), SYBEDDNE);
+ 	CHECK_PARAMETER(dbproc->bcpinfo, SYBEBCPI, FAIL);
+@@ -401,6 +402,9 @@ bcp_colfmt(DBPROCESS * dbproc, int host_colnum, int host_type, int host_prefixle
+ 	if (dbproc->msdblib && host_termlen == 0)
+ 		host_termlen = -1;
+ 
++	if (host_termlen < 0)
++		host_termlen = -1;
++
+ 	if (dbproc->hostfileinfo->host_colcount == 0) {
+ 		dbperror(dbproc, SYBEBCBC, 0);
+ 		return FAIL;
+@@ -448,7 +452,7 @@ bcp_colfmt(DBPROCESS * dbproc, int host_colnum, int host_type, int host_prefixle
+ 	 * If there's a positive terminator length, we need a valid terminator pointer.
+ 	 * If the terminator length is 0 or -1, then there's no terminator.
+ 	 */
+-	if (host_term == NULL && host_termlen > 0 || host_term != NULL && host_termlen == 0) {
++	if (host_term == NULL && host_termlen > 0) {
+ 		dbperror(dbproc, SYBEVDPT, 0);	/* "all variable-length data must have either a length-prefix ..." */
+ 		return FAIL;
+ 	}
+
+commit c74ebc5bae38786f1b1e10780b89e2cbac053fc5
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 19:05:07 2010 +0000
+
+    More verbose
+
+diff --git a/ChangeLog b/ChangeLog
+index 9509afe..27352ac 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan  9 20:04:51 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/test64.c: More verbose
++
+ Sat Jan  9 15:31:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/bcp.c: Ignore terminator pointer if terminator len <= 0
+ 
+@@ -2067,4 +2070,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2927 2010/01/09 14:32:12 freddy77 Exp $
++$Id: ChangeLog,v 1.2928 2010/01/09 19:05:07 freddy77 Exp $
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index a7fdcb4..89b4623 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.8 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.9 2010/01/09 19:05:07 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -196,6 +196,8 @@ test_rows(void)
+ 
+ 	/* now see results */
+ 	for (p = row_set; ; ++p) {
++		const char *test_name = NULL;
++
+ 		ResetStatement();
+ 		len = 0xdeadbeef;
+ 		len <<= 16;
+@@ -214,10 +216,12 @@ test_rows(void)
+ 
+ 			Command("SELECT DISTINCT i FROM #tmp1");
+ 			SQLFetch(Statement);
++			test_name = "SQLSetStmtAttr";
+ 		} else {
+ 			CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 			Command("SELECT DISTINCT i FROM #tmp1");
+ 			CHKExtendedFetch(SQL_FETCH_NEXT, 0, &len, NULL, "S");
++			test_name = "SQLExtendedFetch";
+ 		}
+ 		SQLMoreResults(Statement);
+ 
+@@ -226,7 +230,7 @@ test_rows(void)
+ 		h = len >> 16;
+ 		l &= 0xfffffffflu;
+ 		if (h != 0 || l != 2) {
+-			fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx)\n", h, h, l, l);
++			fprintf(stderr, "Wrong number returned in rows high %lu(0x%lx) low %lu(0x%lx) test %s\n", h, h, l, l, test_name);
+ 			exit(1);
+ 		}
+ 
+@@ -241,6 +245,11 @@ test_rows(void)
+ int
+ main(void)
+ {
++	if (sizeof(SQLLEN) != 8) {
++		printf("Not possible for this platform.\n");
++		return 0;
++	}
++
+ 	use_odbc_version3 = 1;
+ 	Connect();
+ 
+
+commit 3998d2178d034bcf178281820920b9565108d288
+Author: freddy77 <freddy77>
+Date:   Sat Jan 9 23:41:52 2010 +0000
+
+    Fix socket error testing for EAGAIN
+
+diff --git a/ChangeLog b/ChangeLog
+index 27352ac..b5ead59 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Jan 10 00:41:36 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/tds/net.c:
++	- Fix socket error testing for EAGAIN
++
+ Sat Jan  9 20:04:51 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/test64.c: More verbose
+ 
+@@ -2070,4 +2074,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2928 2010/01/09 19:05:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2929 2010/01/09 23:41:52 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index d0eb302..b711448 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.30 2010/01/09 09:50:16 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.31 2010/01/09 23:41:52 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -84,6 +84,7 @@ void _tds_socket_done(void);
+ 
+ #define TDSSOCK_EINTR WSAEINTR
+ #define TDSSOCK_EINPROGRESS WSAEWOULDBLOCK
++#define TDSSOCK_WOULDBLOCK(e) ((e)==WSAEWOULDBLOCK)
+ #define sock_errno WSAGetLastError()
+ #define sock_strerror(n) tds_prwsaerror(n)
+ #ifndef __MINGW32__
+@@ -130,6 +131,14 @@ typedef DWORD pid_t;
+ #define TDSSOCK_EINPROGRESS EINPROGRESS
+ #endif
+ 
++#ifndef TDSSOCK_WOULDBLOCK
++# if defined(EWOULDBLOCK) && EAGAIN != EWOULDBLOCK
++#  define TDSSOCK_WOULDBLOCK(e) ((e)==EAGAIN||(e)==EWOULDBLOCK)
++# else
++#  define TDSSOCK_WOULDBLOCK(e) ((e)==EAGAIN)
++# endif
++#endif
++
+ #ifndef INITSOCKET
+ #define INITSOCKET()	0
+ #endif /* !INITSOCKET */
+diff --git a/src/tds/net.c b/src/tds/net.c
+index b664db2..dfc686d 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.98 2010/01/09 09:50:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.99 2010/01/09 23:41:52 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -276,7 +276,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 		tds->oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", sock_strerror(sock_errno));
+ #if DEBUGGING_CONNECTING_PROBLEM
+-		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != EINPROGRESS) {
++		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != TDSSOCK_EINPROGRESS) {
+ 			tdsdump_dump_buf(TDS_DBG_ERROR, "Contents of sockaddr_in", &sin, sizeof(sin));
+ 			tdsdump_log(TDS_DBG_ERROR, 	" sockaddr_in:\t"
+ 							      "%s = %x\n" 
+@@ -500,7 +500,7 @@ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfi
+ 
+ 			len = READSOCKET(tds->s, buf + got, buflen);
+ 
+-			if (len < 0 && sock_errno == EAGAIN)
++			if (len < 0 && TDSSOCK_WOULDBLOCK(sock_errno))
+ 				continue;
+ 			/* detect connection close */
+ 			if (len <= 0) {
+@@ -509,7 +509,7 @@ tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen, unsigned char unfi
+ 				return -1;
+ 			}
+ 		} else if (len < 0) {
+-			if (sock_errno == EAGAIN) /* shouldn't happen, but OK */
++			if (TDSSOCK_WOULDBLOCK(sock_errno)) /* shouldn't happen, but OK */
+ 				continue;
+ 			tdserror(tds->tds_ctx, tds, TDSEREAD, sock_errno);
+ 			tds_close_socket(tds);
+@@ -705,7 +705,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 				continue;
+ 			}
+ 			
+-			if (0 == nput || sock_errno == EAGAIN)
++			if (0 == nput || TDSSOCK_WOULDBLOCK(sock_errno))
+ 				continue;
+ 
+ 			assert(nput < 0);
+@@ -716,7 +716,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 			return -1;
+ 
+ 		} else if (rc < 0) {
+-			if (sock_errno == EAGAIN) /* shouldn't happen, but OK, retry */
++			if (TDSSOCK_WOULDBLOCK(sock_errno)) /* shouldn't happen, but OK, retry */
+ 				continue;
+ 			tdsdump_log(TDS_DBG_NETWORK, "select(2) failed: %d (%s)\n", sock_errno, sock_strerror(sock_errno));
+ 			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
+
+commit cef9b133f8a289ab682946292ede9c1919228df8
+Author: freddy77 <freddy77>
+Date:   Sun Jan 10 13:50:31 2010 +0000
+
+    Be consistent about WIN32/WIN64 defines
+
+diff --git a/ChangeLog b/ChangeLog
+index b5ead59..135a790 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Jan 10 14:49:39 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/db-lib.vcproj src/replacements/replacements.vcproj:
++	- Be consistent about WIN32/WIN64 defines
++
+ Sun Jan 10 00:41:36 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h src/tds/net.c:
+ 	- Fix socket error testing for EAGAIN
+@@ -2074,4 +2078,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2929 2010/01/09 23:41:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2930 2010/01/10 13:50:31 freddy77 Exp $
+diff --git a/src/dblib/db-lib.vcproj b/src/dblib/db-lib.vcproj
+index b42af8a..1c632d9 100755
+--- a/src/dblib/db-lib.vcproj
++++ b/src/dblib/db-lib.vcproj
+@@ -43,7 +43,7 @@
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+ 				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				ExceptionHandling="0"
+ 				BasicRuntimeChecks="3"
+@@ -179,7 +179,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				WarningLevel="3"
+ 				Detect64BitPortabilityProblems="true"
+diff --git a/src/replacements/replacements.vcproj b/src/replacements/replacements.vcproj
+index d38ed72..9665e45 100755
+--- a/src/replacements/replacements.vcproj
++++ b/src/replacements/replacements.vcproj
+@@ -106,7 +106,7 @@
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+ 				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				BasicRuntimeChecks="3"
+ 				RuntimeLibrary="1"
+@@ -229,7 +229,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				WarningLevel="3"
+ 				Detect64BitPortabilityProblems="true"
+
+commit 9d41e6c0f626003ddcdeaca5e5811fa8275c7b11
+Author: freddy77 <freddy77>
+Date:   Sun Jan 10 14:43:11 2010 +0000
+
+    Use _WIN32 and _WIN64 instead of WIN32 and WIN64
+
+diff --git a/ChangeLog b/ChangeLog
+index 135a790..766fcfb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,18 @@
++Sun Jan 10 15:42:50 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/fakepoll.h include/replacements.h include/tdsodbc.h:
++	* src/apps/bsqldb.c src/apps/defncopy.c src/dblib/bcp.c:
++	* src/dblib/dblib.c src/dblib/unittests/common.c:
++	* src/odbc/connectparams.c src/odbc/odbc.c:
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/tables.c src/odbc/unittests/timeout2.c:
++	* src/replacements/basename.c src/replacements/fakepoll.c:
++	* src/replacements/gettimeofday.c:
++	* src/replacements/readpassphrase.c src/replacements/vasprintf.c:
++	* src/tds/config.c src/tds/convert.c src/tds/log.c src/tds/login.c:
++	* src/tds/net.c src/tds/threadsafe.c src/tds/util.c:
++	* win32/winlogin.c win32/winsetup.c:
++	- Use _WIN32 and _WIN64 instead of WIN32 and WIN64
++
+ Sun Jan 10 14:49:39 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/db-lib.vcproj src/replacements/replacements.vcproj:
+ 	- Be consistent about WIN32/WIN64 defines
+@@ -2078,4 +2093,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2930 2010/01/10 13:50:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2931 2010/01/10 14:43:11 freddy77 Exp $
+diff --git a/include/fakepoll.h b/include/fakepoll.h
+index 7315555..74cd7d4 100644
+--- a/include/fakepoll.h
++++ b/include/fakepoll.h
+@@ -1,4 +1,4 @@
+-/* $Id: fakepoll.h,v 1.2 2009/04/09 01:40:25 jklowden Exp $ */
++/* $Id: fakepoll.h,v 1.3 2010/01/10 14:43:11 freddy77 Exp $ */
+ #if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
+ #define _FAKE_POLL_H
+ 
+@@ -15,7 +15,7 @@
+ #include <sys/select.h>
+ #endif 
+ 
+-#if defined(WIN32)
++#if defined(_WIN32)
+ #include <winsock2.h>
+ #endif
+ 
+diff --git a/include/replacements.h b/include/replacements.h
+index 5a95294..ebdd02b 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.22 2010/01/08 22:41:35 jklowden Exp $ */
++/* $Id: replacements.h,v 1.23 2010/01/10 14:43:11 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -96,7 +96,7 @@ size_t tds_strlcat(char *dest, const char *src, size_t len);
+ char *tds_basename(char *path);
+ #endif
+ 
+-#if defined(WIN32)
++#if defined(_WIN32)
+ # if !defined(strncasecmp) 
+ #     define  strncasecmp(x,y,z) strnicmp((x),(y),(z))
+ # endif
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index ce4b566..93416ed 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.116 2009/12/17 10:33:59 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.117 2010/01/10 14:43:11 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4
+ #pragma GCC visibility push(hidden)
+@@ -430,7 +430,7 @@ typedef struct _hchk TDS_CHK;
+ #endif
+ #endif
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ BOOL get_login_info(HWND hwndParent, TDSCONNECTION * connection);
+ #endif
+ 
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 3532c8b..f0fc136 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -45,10 +45,10 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.37 2010/01/08 22:41:35 jklowden Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.38 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #define NULL_DEVICE "NUL:"
+ #else
+ #define NULL_DEVICE "/dev/null"
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index bcb810f..4f2ccc2 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -18,7 +18,7 @@
+  */
+ 
+ #ifdef MicrosoftsDbLib
+-#ifdef WIN32
++#ifdef _WIN32
+ # pragma warning( disable : 4142 )
+ # include "win32.microsoft/have.h"
+ # include "../../include/replacements.win32.hacked.h"
+@@ -83,12 +83,12 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #include "replacements.h"
+ #else
+ 
+-#ifndef WIN32
++#ifndef _WIN32
+ # include "replacements.h"
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.16 2010/01/09 13:10:30 freddy77 Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.17 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -145,7 +145,7 @@ main(int argc, char *argv[])
+ 	int i, nrows;
+ 
+ 	/* Initialize db-lib */
+-#if WIN32 && defined(MicrosoftsDbLib)
++#if _WIN32 && defined(MicrosoftsDbLib)
+ 	LPCSTR msg = dbinit();	
+ 	if (msg == NULL) {
+ #else 
+@@ -706,7 +706,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	}
+ 
+ #ifdef MicrosoftsDbLib
+-#if WIN32
++#if _WIN32
+ 	if (fdomain) 
+ 		DBSETLSECURE(login);
+ #endif
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 1aa97c7..db4bac0 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -38,7 +38,7 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #include <io.h>
+ #endif
+ 
+@@ -62,11 +62,11 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.190 2010/01/09 14:32:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.191 2010/01/10 14:43:11 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+-#elif defined(WIN32) || defined(WIN64)
++#elif defined(_WIN32) || defined(_WIN64)
+ /* win32 version */
+ typedef __int64 offset_type;
+ # if defined(HAVE__FSEEKI64) && defined(HAVE__FTELLI64)
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index ef7239e..e1a9d04 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.358 2009/12/16 08:22:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.359 2010/01/10 14:43:11 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -287,7 +287,7 @@ dblib_get_tds_ctx(void)
+ 		if (g_dblib_ctx.tds_ctx->locale && !g_dblib_ctx.tds_ctx->locale->date_fmt) {
+ 			/* set default in case there's no locale file */
+ 			const static char date_format[] = 
+-#ifndef WIN32
++#ifndef _WIN32
+ 							   "%b %e %Y %I:%M:%S:%z%p";
+ #else
+ 							   "%b %d %Y %I:%M:%S:%z%p";
+@@ -7817,7 +7817,7 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbperror(%p, %d, %ld)\n", dbproc, msgno, errnum);	/* dbproc can be NULL */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ 	/*
+ 	 * Unfortunately MingW uses the "old" msvcrt.dll (Visual C++ 2005 uses
+ 	 * a newer version) which does not set errno when allocation functions
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 93ab234..45d4534 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -22,7 +22,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.39 2009/09/14 10:02:13 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.40 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -157,7 +157,7 @@ read_login_info(int argc, char **argv)
+ #endif
+ 	
+ 	BASENAME = tds_basename(ARGV0);
+-#if defined(WIN32) || defined(__VMS)
++#if defined(_WIN32) || defined(__VMS)
+ 	s1 = strrchr(BASENAME, '.');
+ 	if (s1) *s1 = 0;
+ #endif
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 631d379..333ed1d 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.81 2009/12/16 13:06:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.82 2010/01/10 14:43:11 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -384,7 +384,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 
+ #if !HAVE_SQLGETPRIVATEPROFILESTRING
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #  error There is something wrong  in configuration...
+ #endif
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index b0d2654..722548f 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.524 2009/12/28 13:30:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.525 2010/01/10 14:43:11 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -451,7 +451,7 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 
+ 	/* add login info */
+ 	if (hwnd) {
+-#ifdef WIN32
++#ifdef _WIN32
+ 		/* prompt for login information */
+ 		if (!get_login_info(hwnd, connection)) {
+ 			tds_free_connection(connection);
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 998301d..cb75715 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -6,13 +6,13 @@
+ 
+ #include <ctype.h>
+ 
+-#ifndef WIN32
++#ifndef _WIN32
+ #include "tds_sysdep_private.h"
+ #else
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.55 2009/12/22 18:56:22 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.56 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -27,7 +27,7 @@ char PASSWORD[512];
+ char DATABASE[512];
+ char DRIVER[1024];
+ 
+-#ifndef WIN32
++#ifndef _WIN32
+ static int
+ check_lib(char *path, const char *file)
+ {
+@@ -66,7 +66,7 @@ read_login_info(void)
+ 	FILE *in = NULL;
+ 	char line[512];
+ 	char *s1, *s2;
+-#ifndef WIN32
++#ifndef _WIN32
+ 	char path[1024];
+ 	int len;
+ #endif
+@@ -103,7 +103,7 @@ read_login_info(void)
+ 	}
+ 	fclose(in);
+ 
+-#ifndef WIN32
++#ifndef _WIN32
+ 	/* find our driver */
+ 	if (!getcwd(path, sizeof(path)))
+ 		return 0;
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index cbf0104..22382b7 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -1,4 +1,4 @@
+-#ifdef WIN32
++#ifdef _WIN32
+ #include <windows.h>
+ #include <direct.h>
+ #endif
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.29 2009/12/15 11:23:47 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.30 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c
+index 4c85dca..47c7251 100644
+--- a/src/odbc/unittests/tables.c
++++ b/src/odbc/unittests/tables.c
+@@ -1,9 +1,9 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: tables.c,v 1.17 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: tables.c,v 1.18 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #undef strcasecmp
+ #define strcasecmp stricmp
+ #endif
+diff --git a/src/odbc/unittests/timeout2.c b/src/odbc/unittests/timeout2.c
+index a5f8f26..13d751d 100644
+--- a/src/odbc/unittests/timeout2.c
++++ b/src/odbc/unittests/timeout2.c
+@@ -14,10 +14,10 @@
+  * Test from Ou Liu, cf "Query Time Out", 2006-08-08
+  */
+ 
+-static char software_version[] = "$Id: timeout2.c,v 1.7 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: timeout2.c,v 1.8 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#if defined(__MINGW32__) || defined(WIN32)
++#if defined(__MINGW32__) || defined(_WIN32)
+ #define sleep(s) Sleep((s)*1000)
+ #endif
+ 
+diff --git a/src/replacements/basename.c b/src/replacements/basename.c
+index 3dfe522..aba92a4 100644
+--- a/src/replacements/basename.c
++++ b/src/replacements/basename.c
+@@ -30,9 +30,9 @@
+ 
+ #if ! HAVE_BASENAME
+ 
+-TDS_RCSID(var, "$Id: basename.c,v 1.4 2009/03/19 15:09:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: basename.c,v 1.5 2010/01/10 14:43:11 freddy77 Exp $");
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #define TDS_ISDIR_SEPARATOR(c) ((c) == '/' || (c) == '\\')
+ #else
+ #define TDS_ISDIR_SEPARATOR(c) ((c) == '/')
+@@ -52,7 +52,7 @@ char *tds_basename(char *path)
+ 	p = strrchr(path, '/');
+ 	if (p)
+ 		path = p + 1;
+-#ifdef WIN32
++#ifdef _WIN32
+ 	p = strrchr(path, '\\');
+ 	if (p)
+ 		path = p + 1;
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index 753153e..3899c2b 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -23,7 +23,7 @@
+ 
+ #ifndef HAVE_POLL
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.7 2009/01/21 08:43:54 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.8 2010/01/10 14:43:11 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include <stdarg.h>
+@@ -87,7 +87,7 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 			continue;
+ 		} 
+ 
+-#if defined(WIN32)
++#if defined(_WIN32)
+ 		/* Win32 cares about the number of descriptors, not the highest one. */
+ 		++maxfd;
+ #else
+diff --git a/src/replacements/gettimeofday.c b/src/replacements/gettimeofday.c
+index 4a06ea9..f10541b 100644
+--- a/src/replacements/gettimeofday.c
++++ b/src/replacements/gettimeofday.c
+@@ -21,7 +21,7 @@
+ #include <config.h>
+ #endif
+ 
+-#if defined(WIN32)
++#if defined(_WIN32)
+ 
+ #if HAVE_ERRNO_H
+ #include <errno.h>
+@@ -30,7 +30,7 @@
+ #include "tds.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: gettimeofday.c,v 1.4 2008/10/02 08:08:00 freddy77 Exp $");
++TDS_RCSID(var, "$Id: gettimeofday.c,v 1.5 2010/01/10 14:43:11 freddy77 Exp $");
+ /*
+  * Number of micro-seconds between the beginning of the Windows epoch
+  * (Jan. 1, 1601) and the Unix epoch (Jan. 1, 1970).
+diff --git a/src/replacements/readpassphrase.c b/src/replacements/readpassphrase.c
+index 666f33a..e86573f 100644
+--- a/src/replacements/readpassphrase.c
++++ b/src/replacements/readpassphrase.c
+@@ -231,7 +231,7 @@ static void handler(int s)
+ 	signo = s;
+ }
+ 
+-#else /* WIN32 */
++#else /* _WIN32 */
+ 
+ char *
+ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
+@@ -269,6 +269,6 @@ readpassphrase(const char *prompt, char *buf, size_t bufsiz, int flags)
+ 	return (ch == EOF ? NULL : buf);
+ }
+  
+-#endif /* WIN32 */
++#endif /* _WIN32 */
+ 
+ #endif /* HAVE_READPASSPHRASE */
+diff --git a/src/replacements/vasprintf.c b/src/replacements/vasprintf.c
+index 7312519..32b7682 100644
+--- a/src/replacements/vasprintf.c
++++ b/src/replacements/vasprintf.c
+@@ -34,7 +34,7 @@
+ #include "tds_sysdep_private.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: vasprintf.c,v 1.21 2010/01/09 09:17:47 freddy77 Exp $");
++TDS_RCSID(var, "$Id: vasprintf.c,v 1.22 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ #if defined(HAVE__VSNPRINTF) && !defined(HAVE_VSNPRINTF)
+ #undef HAVE_VSNPRINTF
+@@ -94,7 +94,7 @@ vasprintf(char **ret, const char *fmt, va_list ap)
+ 
+ #ifdef _REENTRANT
+ 
+-# ifdef WIN32
++# ifdef _WIN32
+ #  error Win32 do not have /dev/null, should use vsnprintf version
+ # endif
+ 
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 0d8b661..3111878 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -64,7 +64,7 @@
+ #include <arpa/inet.h>
+ #endif /* HAVE_ARPA_INET_H */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #include <process.h>
+ #endif
+ 
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.152 2010/01/08 22:08:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.153 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -94,7 +94,7 @@ static char *interf_file = NULL;
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char ) (c))
+ 
+-#if !defined(WIN32) && !defined(DOS32X)
++#if !defined(_WIN32) && !defined(DOS32X)
+        const char STD_DATETIME_FMT[] = "%b %e %Y %I:%M%p";
+ static const char pid_config_logpath[] = "/tmp/tdsconfig.log.%d";
+ static const char freetds_conf[] = "%s/etc/freetds.conf";
+diff --git a/src/tds/convert.c b/src/tds/convert.c
+index adc9967..02ab940 100644
+--- a/src/tds/convert.c
++++ b/src/tds/convert.c
+@@ -64,7 +64,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert.c,v 1.194 2009/12/07 16:22:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert.c,v 1.195 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ typedef unsigned short utf16_t;
+ 
+@@ -862,7 +862,7 @@ tds_convert_int8(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
+ 	case TDS_CONVERT_CHAR:
+ 	case CASE_ALL_CHAR:
+ 		/* TODO: fix for all platform. Search for lltoa/_i64toa */
+-#if defined(WIN32) 
++#if defined(_WIN32)
+ 		_i64toa(buf, tmp_str, 10);
+ #elif SIZEOF_LONG < 8
+ 		sprintf(tmp_str, "%" TDS_I64_FORMAT, buf);
+@@ -924,7 +924,7 @@ tds_convert_int8(int srctype, const TDS_CHAR * src, int desttype, CONV_RESULT *
+ 	case SYBNUMERIC:
+ 	case SYBDECIMAL:
+ 		/* TODO portability problem. See above */
+-#if defined(WIN32) 
++#if defined(_WIN32)
+ 		_i64toa(buf, tmp_str, 10);
+ #elif SIZEOF_LONG < 8
+ 		sprintf(tmp_str, "%" TDS_I64_FORMAT, buf);
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 6f02624..52a1328 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -54,7 +54,7 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #include <process.h>
+ #endif
+ 
+@@ -66,10 +66,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.13 2009/09/30 11:52:06 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.14 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+-int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
++int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE | TDS_DBGFLAG_PID | TDS_DBGFLAG_THREAD;
+ int tds_g_append_mode = 0;
+ static char *g_dump_filename = NULL;
+ static int write_dump = 0;	/* is TDS stream debug log turned on? */
+@@ -250,6 +250,14 @@ tdsdump_start(FILE *file, const char *fname, int line)
+ 		started = 1;
+ 	}
+ 
++	if (tds_debug_flags & TDS_DBGFLAG_THREAD) {
++		if (started)
++			*pbuf++ = ' ';
++		pbuf += sprintf(pbuf, "%d", (int) pthread_self());
++		started = 1;
++	}
++
++
+ 	if ((tds_debug_flags & TDS_DBGFLAG_SOURCE) && fname && line) {
+ 		const char *p;
+ 		p = strrchr(fname, '/');
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 0ff62f4..c16dcb7 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -39,7 +39,7 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #include <process.h>
+ #endif
+ 
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.191 2009/12/02 22:58:21 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.192 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+diff --git a/src/tds/net.c b/src/tds/net.c
+index dfc686d..2b2a226 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.99 2010/01/09 23:41:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.100 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -132,7 +132,7 @@ static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned i
+  * @{ 
+  */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ int
+ _tds_socket_init(void)
+ {
+@@ -178,7 +178,7 @@ _tds_socket_done(void)
+ #define USE_NODELAY 1
+ #endif
+ 
+-#if !defined(WIN32)
++#if !defined(_WIN32)
+ typedef unsigned int ioctl_nonblocking_t;
+ #else
+ typedef u_long ioctl_nonblocking_t;
+@@ -363,7 +363,7 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 	assert(timeout_seconds >= 0);
+ 
+ #if !USE_POLL
+-#if !defined(WIN32) && defined(FD_SETSIZE)
++#if !defined(_WIN32) && defined(FD_SETSIZE)
+ 	if (tds->s >= FD_SETSIZE) {
+ 		sock_errno = EINVAL;
+ 		return -1;
+@@ -765,7 +765,7 @@ tds_write_packet(TDSSOCKET * tds, unsigned char final)
+ 	int sent;
+ 	unsigned int left = 0;
+ 
+-#if !defined(WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X)
++#if !defined(_WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X)
+ 	void (*oldsig) (int);
+ #endif
+ 
+@@ -785,7 +785,7 @@ tds_write_packet(TDSSOCKET * tds, unsigned char final)
+ 
+ 	tdsdump_dump_buf(TDS_DBG_NETWORK, "Sending packet", tds->out_buf, tds->out_pos);
+ 
+-#if !defined(WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X)
++#if !defined(_WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X)
+ 	oldsig = signal(SIGPIPE, SIG_IGN);
+ 	if (oldsig == SIG_ERR) {
+ 		tdsdump_log(TDS_DBG_WARN, "TDS: Warning: Couldn't set SIGPIPE signal to be ignored\n");
+@@ -803,7 +803,7 @@ tds_write_packet(TDSSOCKET * tds, unsigned char final)
+ #endif
+ 		sent = tds_goodwrite(tds, tds->out_buf, tds->out_pos, final);
+ 
+-#if !defined(WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X)
++#if !defined(_WIN32) && !defined(MSG_NOSIGNAL) && !defined(DOS32X)
+ 	if (signal(SIGPIPE, oldsig) == SIG_ERR) {
+ 		tdsdump_log(TDS_DBG_WARN, "TDS: Warning: Couldn't reset SIGPIPE signal to previous value\n");
+ 	}
+@@ -859,7 +859,7 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 	}
+ 
+ #if !USE_POLL
+-#if !defined(WIN32) && defined(FD_SETSIZE)
++#if !defined(_WIN32) && defined(FD_SETSIZE)
+ 	if (s >= FD_SETSIZE) {
+ 		sock_errno = EINVAL;
+ 		return 0;
+@@ -1022,7 +1022,7 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 	}
+ 
+ #if !USE_POLL
+-#if !defined(WIN32) && defined(FD_SETSIZE)
++#if !defined(_WIN32) && defined(FD_SETSIZE)
+ 	if (s >= FD_SETSIZE) {
+ 		sock_errno = EINVAL;
+ 		return 0;
+diff --git a/src/tds/threadsafe.c b/src/tds/threadsafe.c
+index f392ab9..5b8e280 100644
+--- a/src/tds/threadsafe.c
++++ b/src/tds/threadsafe.c
+@@ -74,7 +74,7 @@
+ #include <arpa/inet.h>
+ #endif /* HAVE_ARPA_INET_H */
+ 
+-#if defined(WIN32) || defined(WIN64)
++#if defined(_WIN32) || defined(_WIN64)
+ #include <winsock2.h>
+ #include <shlobj.h>
+ #endif
+@@ -85,12 +85,12 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: threadsafe.c,v 1.47 2009/01/16 20:27:58 jklowden Exp $");
++TDS_RCSID(var, "$Id: threadsafe.c,v 1.48 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ char *
+ tds_timestamp_str(char *str, int maxlen)
+ {
+-#if !defined(WIN32) && !defined(WIN64)
++#if !defined(_WIN32) && !defined(_WIN64)
+ 	struct tm *tm;
+ 	time_t t;
+ 
+@@ -133,7 +133,7 @@ tds_timestamp_str(char *str, int maxlen)
+ 	strcat(str, usecs);
+ #endif
+ 
+-#else /* WIN32 */
++#else /* _WIN32 */
+ 	SYSTEMTIME st;
+ 
+ 	GetLocalTime(&st);
+@@ -513,7 +513,7 @@ tds_getservbyname_r(const char *name, const char *proto, struct servent *result,
+ char *
+ tds_get_homedir(void)
+ {
+-#ifndef WIN32
++#ifndef _WIN32
+ /* if is available getpwuid_r use it */
+ #if defined(HAVE_GETUID) && defined(HAVE_GETPWUID_R)
+ 	struct passwd *pw, bpw;
+@@ -550,7 +550,7 @@ tds_get_homedir(void)
+ 		return NULL;
+ 	return strdup(home);
+ #endif
+-#else /* WIN32 */
++#else /* _WIN32 */
+ 	/*
+ 	 * For win32 we return application data cause we use "HOME" 
+ 	 * only to store configuration files
+diff --git a/src/tds/util.c b/src/tds/util.c
+index c4034d8..15a6daa 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -53,7 +53,7 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+-#ifdef WIN32
++#ifdef _WIN32
+ #include <process.h>
+ #endif
+ 
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.87 2009/08/25 14:25:35 freddy77 Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.88 2010/01/10 14:43:12 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -207,7 +207,7 @@ tds_version(TDSSOCKET * tds_socket, char *pversion_string)
+ unsigned int
+ tds_gettime_ms(void)
+ {
+-#ifdef WIN32
++#ifdef _WIN32
+ 	return GetTickCount();
+ #elif defined(HAVE_GETHRTIME)
+ 	return (unsigned int) (gethrtime() / 1000000u);
+diff --git a/win32/winlogin.c b/win32/winlogin.c
+index 9e5969d..540a48a 100644
+--- a/win32/winlogin.c
++++ b/win32/winlogin.c
+@@ -88,7 +88,7 @@ get_desktop_file(const char *file)
+ 	return res;
+ }
+ 
+-#ifndef WIN64
++#ifndef _WIN64
+ #define GetWindowUserData(wnd)       GetWindowLong((wnd), GWL_USERDATA)
+ #define SetWindowUserData(wnd, data) SetWindowLong((wnd), GWL_USERDATA, (data))
+ #else
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index b361af7..ea233f1 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -192,7 +192,7 @@ validate(DSNINFO * di)
+ 	return NULL;
+ }
+ 
+-#ifndef WIN64
++#ifndef _WIN64
+ #define GetWindowUserData(wnd)       GetWindowLong((wnd), GWL_USERDATA)
+ #define SetWindowUserData(wnd, data) SetWindowLong((wnd), GWL_USERDATA, (data))
+ #else
+
+commit b606be4416448bfa0e4137ce8be7ab9f1cd28019
+Author: jklowden <jklowden>
+Date:   Mon Jan 11 13:42:22 2010 +0000
+
+    revert to previous version
+
+diff --git a/ChangeLog b/ChangeLog
+index 766fcfb..f1dd751 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 11 08:39:49 EST 2010	JK Lowden <jklowden@freetds.org>
++	* src/apps/defncopy.c revert to previous version
++
+ Sun Jan 10 15:42:50 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/fakepoll.h include/replacements.h include/tdsodbc.h:
+ 	* src/apps/bsqldb.c src/apps/defncopy.c src/dblib/bcp.c:
+@@ -2093,4 +2096,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2931 2010/01/10 14:43:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2932 2010/01/11 13:42:22 jklowden Exp $
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 4f2ccc2..42e1715 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -18,7 +18,7 @@
+  */
+ 
+ #ifdef MicrosoftsDbLib
+-#ifdef _WIN32
++#ifdef WIN32
+ # pragma warning( disable : 4142 )
+ # include "win32.microsoft/have.h"
+ # include "../../include/replacements.win32.hacked.h"
+@@ -83,12 +83,12 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #include "replacements.h"
+ #else
+ 
+-#ifndef _WIN32
++#ifndef WIN32
+ # include "replacements.h"
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.17 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.18 2010/01/11 13:42:22 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -145,7 +145,7 @@ main(int argc, char *argv[])
+ 	int i, nrows;
+ 
+ 	/* Initialize db-lib */
+-#if _WIN32 && defined(MicrosoftsDbLib)
++#if WIN32 && defined(MicrosoftsDbLib)
+ 	LPCSTR msg = dbinit();	
+ 	if (msg == NULL) {
+ #else 
+@@ -706,7 +706,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	}
+ 
+ #ifdef MicrosoftsDbLib
+-#if _WIN32
++#if WIN32
+ 	if (fdomain) 
+ 		DBSETLSECURE(login);
+ #endif
+
+commit 0f13f0c8b19572a0f4fb454f15df5445a2bba454
+Author: jklowden <jklowden>
+Date:   Mon Jan 11 14:03:17 2010 +0000
+
+    strcasecmp macro
+
+diff --git a/ChangeLog b/ChangeLog
+index f1dd751..8634cba 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Jan 11 09:00:59 EST 2010	JK Lowden <jklowden@freetds.org>
++	* include/replacements.h strcasecmp macro
++	* src/apps/defncopy.c unrevert to 1.17 again
++	* src/tds/log.c define pthread_self() as zero for win32
++
+ Mon Jan 11 08:39:49 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/defncopy.c revert to previous version
+ 
+@@ -2096,4 +2101,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2932 2010/01/11 13:42:22 jklowden Exp $
++$Id: ChangeLog,v 1.2933 2010/01/11 14:03:17 jklowden Exp $
+diff --git a/include/replacements.h b/include/replacements.h
+index ebdd02b..a24bb0b 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.23 2010/01/10 14:43:11 freddy77 Exp $ */
++/* $Id: replacements.h,v 1.24 2010/01/11 14:03:17 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -97,6 +97,9 @@ char *tds_basename(char *path);
+ #endif
+ 
+ #if defined(_WIN32)
++# if !defined(strcasecmp) 
++#     define  strcasecmp(A, B) stricmp((A), (B))
++# endif
+ # if !defined(strncasecmp) 
+ #     define  strncasecmp(x,y,z) strnicmp((x),(y),(z))
+ # endif
+
+commit 2bbf8195b7613625cae3cd52c9997ebd082d4d5c
+Author: jklowden <jklowden>
+Date:   Mon Jan 11 14:03:20 2010 +0000
+
+    unrevert to 1.17 again
+
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 42e1715..dd6b021 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -18,11 +18,10 @@
+  */
+ 
+ #ifdef MicrosoftsDbLib
+-#ifdef WIN32
++#ifdef _WIN32
+ # pragma warning( disable : 4142 )
+ # include "win32.microsoft/have.h"
+ # include "../../include/replacements.win32.hacked.h"
+-# define strcasecmp(A, B) stricmp((A), (B))
+ int getopt(int argc, const char *argv[], char *optstring);
+ 
+ # ifndef DBNTWIN32
+@@ -83,12 +82,12 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #include "replacements.h"
+ #else
+ 
+-#ifndef WIN32
++#ifndef _WIN32
+ # include "replacements.h"
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.18 2010/01/11 13:42:22 jklowden Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.19 2010/01/11 14:03:20 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -145,7 +144,7 @@ main(int argc, char *argv[])
+ 	int i, nrows;
+ 
+ 	/* Initialize db-lib */
+-#if WIN32 && defined(MicrosoftsDbLib)
++#if _WIN32 && defined(MicrosoftsDbLib)
+ 	LPCSTR msg = dbinit();	
+ 	if (msg == NULL) {
+ #else 
+@@ -706,7 +705,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 	}
+ 
+ #ifdef MicrosoftsDbLib
+-#if WIN32
++#if _WIN32
+ 	if (fdomain) 
+ 		DBSETLSECURE(login);
+ #endif
+
+commit 279b5c775cb32ba3b196ee4c703d0e5e739a9872
+Author: jklowden <jklowden>
+Date:   Mon Jan 11 14:03:23 2010 +0000
+
+    define pthread_self() as zero for win32
+
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 52a1328..7eaa428 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -55,7 +55,8 @@
+ #endif /* HAVE_UNISTD_H */
+ 
+ #ifdef _WIN32
+-#include <process.h>
++# include <process.h>
++# define pthread_self() 0
+ #endif
+ 
+ #include "tds.h"
+@@ -66,7 +67,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.14 2010/01/10 14:43:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.15 2010/01/11 14:03:23 jklowden Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE | TDS_DBGFLAG_PID | TDS_DBGFLAG_THREAD;
+
+commit b18a271f36ef3b06fb589e55d5ed5956c8ecb87f
+Author: freddy77 <freddy77>
+Date:   Mon Jan 11 17:53:00 2010 +0000
+
+    added help
+
+diff --git a/ChangeLog b/ChangeLog
+index 8634cba..fe74b3b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 11 18:52:52 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: added help
++
+ Mon Jan 11 09:00:59 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* include/replacements.h strcasecmp macro
+ 	* src/apps/defncopy.c unrevert to 1.17 again
+@@ -2101,4 +2104,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2933 2010/01/11 14:03:17 jklowden Exp $
++$Id: ChangeLog,v 1.2934 2010/01/11 17:53:00 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index cfaf7af..238a4fb 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -77,7 +77,7 @@ init_log()
+ 	ln -f logs/log.txt ../${WORKDIR}_log.txt
+ }
+ 
+-rm ~/freetds.log /tmp/sql.log
++rm -f ~/freetds.log /tmp/sql.log
+ 
+ ignore=
+ for param
+@@ -93,6 +93,10 @@ do
+ 		FTDSDIR=freetds$1
+ 		WORKDIR=ftds_comp$1
+ 		;;
++	--help)
++		echo "Syntax: freetds_autobuild [--version VERSION]"
++		exit 1
++		;;
+ 	*)
+ 		echo 'Option not supported!' 1>&2
+ 		exit 1
+
+commit f9d41d7b5572b35aeb4cd8e42e4c3877c02f3382
+Author: freddy77 <freddy77>
+Date:   Mon Jan 11 17:56:30 2010 +0000
+
+    unneeded with newer types.h
+
+diff --git a/ChangeLog b/ChangeLog
+index fe74b3b..75af141 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 11 18:56:17 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: unneeded with newer types.h
++
+ Mon Jan 11 18:52:52 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild: added help
+ 
+@@ -2104,4 +2107,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2934 2010/01/11 17:53:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2935 2010/01/11 17:56:30 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 8ee7d90..f8140b4 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -39,17 +39,11 @@
+ #include "tds_checks.h"
+ #include "replacements.h"
+ 
+-/* Microsoft's linker complains about missing tds_get_varint_size */
+-#ifdef WIN32
+-# define TDS_GET_VARINT_SIZE_ONLY
+-# include "types.h"
+-#endif
+-
+ #ifdef DMALLOC
+- <dmalloc.h>
++#include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.377 2010/01/08 22:08:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.378 2010/01/11 17:56:30 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+
+commit c7a731ee698e9c0924b185b609511639d1d7f575
+Author: freddy77 <freddy77>
+Date:   Mon Jan 11 18:00:16 2010 +0000
+
+    removed wrongly committed patch
+
+diff --git a/ChangeLog b/ChangeLog
+index 75af141..d2361b8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 11 19:00:10 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/log.c: removed wrongly committed patch
++
+ Mon Jan 11 18:56:17 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: unneeded with newer types.h
+ 
+@@ -2107,4 +2110,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2935 2010/01/11 17:56:30 freddy77 Exp $
++$Id: ChangeLog,v 1.2936 2010/01/11 18:00:16 freddy77 Exp $
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 7eaa428..c064963 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -56,7 +56,6 @@
+ 
+ #ifdef _WIN32
+ # include <process.h>
+-# define pthread_self() 0
+ #endif
+ 
+ #include "tds.h"
+@@ -67,10 +66,10 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.15 2010/01/11 14:03:23 jklowden Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.16 2010/01/11 18:00:16 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+-int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE | TDS_DBGFLAG_PID | TDS_DBGFLAG_THREAD;
++int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+ int tds_g_append_mode = 0;
+ static char *g_dump_filename = NULL;
+ static int write_dump = 0;	/* is TDS stream debug log turned on? */
+@@ -251,14 +250,6 @@ tdsdump_start(FILE *file, const char *fname, int line)
+ 		started = 1;
+ 	}
+ 
+-	if (tds_debug_flags & TDS_DBGFLAG_THREAD) {
+-		if (started)
+-			*pbuf++ = ' ';
+-		pbuf += sprintf(pbuf, "%d", (int) pthread_self());
+-		started = 1;
+-	}
+-
+-
+ 	if ((tds_debug_flags & TDS_DBGFLAG_SOURCE) && fname && line) {
+ 		const char *p;
+ 		p = strrchr(fname, '/');
+
+commit 5a27a6cd75d31502f7a36568c0055d191b285518
+Author: jklowden <jklowden>
+Date:   Mon Jan 11 18:04:04 2010 +0000
+
+    more care with strcasecmp macro
+
+diff --git a/ChangeLog b/ChangeLog
+index d2361b8..05573f6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 11 13:03:29 EST 2010	JK Lowden <jklowden@freetds.org>
++	* include/replacements.h more care with strcasecmp macro
++
+ Mon Jan 11 19:00:10 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/log.c: removed wrongly committed patch
+ 
+@@ -2110,4 +2113,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2936 2010/01/11 18:00:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2937 2010/01/11 18:04:04 jklowden Exp $
+diff --git a/include/replacements.h b/include/replacements.h
+index a24bb0b..bde9cff 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.24 2010/01/11 14:03:17 jklowden Exp $ */
++/* $Id: replacements.h,v 1.25 2010/01/11 18:04:04 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -96,11 +96,24 @@ size_t tds_strlcat(char *dest, const char *src, size_t len);
+ char *tds_basename(char *path);
+ #endif
+ 
++/* 
++ * Microsoft's C Runtime library is missing strcasecmp and strncasecmp. 
++ * Other Win32 C runtime libraries, notably minwg, may define it. 
++ * There is no symbol uniquely defined in Microsoft's header files that 
++ * can be used by the preprocessor to know whether we're compiling for
++ * Microsoft's library or not (or which version).  Thus there's no
++ * way to automatically decide whether or not to define strcasecmp
++ * in terms of stricmp.  
++ * 
++ * The Microsoft *compiler* defines _MSC_VER.  On the assumption that
++ * anyone using their compiler is also using their library, the below 
++ * tests check _MSC_VER as a proxy. 
++ */
+ #if defined(_WIN32)
+-# if !defined(strcasecmp) 
++# if !defined(strcasecmp) && defined(_MSC_VER) 
+ #     define  strcasecmp(A, B) stricmp((A), (B))
+ # endif
+-# if !defined(strncasecmp) 
++# if !defined(strncasecmp) && defined(_MSC_VER)
+ #     define  strncasecmp(x,y,z) strnicmp((x),(y),(z))
+ # endif
+ int gettimeofday (struct timeval *tv, void *tz);
+
+commit 737cea7b1e10c9465436f87c19cc065d17a6c47f
+Author: freddy77 <freddy77>
+Date:   Mon Jan 11 18:14:10 2010 +0000
+
+    do not allow bot port and instance to be specified
+
+diff --git a/ChangeLog b/ChangeLog
+index 05573f6..5713f2b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Jan 11 19:14:03 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/config.c src/tds/login.c src/tds/mem.c:
++	* src/tds/util.c:
++	- do not allow bot port and instance to be specified
++
+ Mon Jan 11 13:03:29 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* include/replacements.h more care with strcasecmp macro
+ 
+@@ -2113,4 +2118,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2937 2010/01/11 18:04:04 jklowden Exp $
++$Id: ChangeLog,v 1.2938 2010/01/11 18:14:10 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index e4c3d16..c278da4 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.324 2009/12/28 13:30:31 freddy77 Exp $ */
++/* $Id: tds.h,v 1.325 2010/01/11 18:14:10 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -287,7 +287,8 @@ typedef enum {	TDSEOK    = TDS_SUCCEED,
+ 		TDSEICONVAVAIL = 2401, 
+ 		TDSEICONVO     = 2402, 
+ 		TDSEICONVI     = 2403, 
+-		TDSEICONV2BIG  = 2404, 
++		TDSEICONV2BIG  = 2404,
++		TDSEPORTINSTANCE	= 2500,
+ 		TDSESYNC = 20001, 
+ 		TDSEFCON = 20002, 
+ 		TDSETIME = 20003, 
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 3111878..5857c88 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.153 2010/01/10 14:43:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.154 2010/01/11 18:14:10 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -630,10 +630,8 @@ tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login)
+ 	if (login->block_size) {
+ 		connection->block_size = login->block_size;
+ 	}
+-	if (login->port) {
++	if (login->port)
+ 		connection->port = login->port;
+-		tds_dstr_copy(&connection->instance_name, "");
+-	}
+ 	if (login->connect_timeout)
+ 		connection->connect_timeout = login->connect_timeout;
+ 
+@@ -1040,11 +1038,7 @@ tds_read_interfaces(const char *server, TDSCONNECTION * connection)
+ 			 * Not set in the [global] section of the
+ 			 * configure file, take a guess.
+ 			 */
+-#ifdef TDS50
+-			ip_port = 4000;
+-#else
+-			ip_port = 1433;
+-#endif
++			ip_port = TDS_DEF_PORT;
+ 		} else {
+ 			/*
+ 			 * Preserve setting from the [global] section
+@@ -1091,14 +1085,12 @@ parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login)
+ 	if (pSep && pSep != server) {	/* yes, i found it! */
+ 		/* modify connection-> && login->server_name & ->port */
+ 		login->port = connection->port = atoi(pSep + 1);
+-		tds_dstr_copy(&connection->instance_name, "");
+ 	} else {
+ 		/* handle instance name */
+ 		pSep = strrchr(server, '\\');
+ 		if (!pSep || pSep == server)
+ 			return 0;
+ 
+-		login->port = connection->port = 0;
+ 		tds_dstr_copy(&connection->instance_name, pSep + 1);
+ 	}
+ 
+diff --git a/src/tds/login.c b/src/tds/login.c
+index c16dcb7..6c33546 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.192 2010/01/10 14:43:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.193 2010/01/11 18:14:10 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -427,6 +427,11 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		return TDSECONN;
+ 	}
+ 
++	if (connection->port && !tds_dstr_isempty(&connection->instance_name)) {
++		tdserror(tds->tds_ctx, tds, TDSEPORTINSTANCE, 0);
++		return TDSECONN;
++	}
++
+ 	if (!IS_TDS50(tds) && !tds_dstr_isempty(&connection->instance_name))
+ 		connection->port = tds7_get_instance_port(tds_dstr_cstr(&connection->ip_addr), tds_dstr_cstr(&connection->instance_name));
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 588c8b6..c17209b 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.195 2010/01/08 22:41:35 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.196 2010/01/11 18:14:10 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -813,7 +813,6 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 	if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER))
+ 		goto Cleanup;
+ 	connection->tds_version = TDS_DEFAULT_VERSION;
+-	connection->port = TDS_DEF_PORT;
+ 	connection->block_size = 0;
+ 	/* TODO use system default ?? */
+ 	if (!tds_dstr_copy(&connection->client_charset, "ISO-8859-1"))
+diff --git a/src/tds/util.c b/src/tds/util.c
+index 15a6daa..45bdb7e 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.88 2010/01/10 14:43:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.89 2010/01/11 18:14:10 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -255,6 +255,7 @@ static const TDS_ERROR_MESSAGE tds_error_messages[] =
+ 	, { TDSEICONVI,      EXCONVERSION,	"Some character(s) could not be converted into client's character set.  "
+ 						"Unconverted bytes were changed to question marks ('?')" }
+ 	, { TDSEICONV2BIG,   EXCONVERSION,	"Some character(s) could not be converted into client's character set" }
++	, { TDSEPORTINSTANCE,      EXCOMM,      "Both port and instance specified" }
+ 	, { TDSERPND,           EXPROGRAM,	"Attempt to initiate a new Adaptive Server operation with results pending" }
+ 	, { TDSEBTOK,              EXCOMM,	"Bad token from the server: Datastream processing out of sync" }
+ 	, { TDSECAP,               EXCOMM,	"DB-Library capabilities not accepted by the Server" }
+
+commit 5d3fc5961f783ab9f9bbe6ecb6af03824c89c6a8
+Author: freddy77 <freddy77>
+Date:   Tue Jan 12 10:20:41 2010 +0000
+
+    Fix strtok_r function
+
+diff --git a/ChangeLog b/ChangeLog
+index 5713f2b..86f1486 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jan 12 11:20:04 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/strtok_r.c: Fix strtok_r function
++
+ Mon Jan 11 19:14:03 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/config.c src/tds/login.c src/tds/mem.c:
+ 	* src/tds/util.c:
+@@ -2118,4 +2121,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2938 2010/01/11 18:14:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2939 2010/01/12 10:20:41 freddy77 Exp $
+diff --git a/src/replacements/strtok_r.c b/src/replacements/strtok_r.c
+index ba44246..9e417cc 100644
+--- a/src/replacements/strtok_r.c
++++ b/src/replacements/strtok_r.c
+@@ -18,8 +18,9 @@
+ #include "tds_sysdep_private.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: strtok_r.c,v 1.6 2006/12/26 14:56:20 freddy77 Exp $");
++TDS_RCSID(var, "$Id: strtok_r.c,v 1.7 2010/01/12 10:20:41 freddy77 Exp $");
+ 
++#undef strtok_r
+ char *
+ strtok_r(char *str, const char *sep, char **lasts)
+ {
+@@ -31,12 +32,68 @@ strtok_r(char *str, const char *sep, char **lasts)
+ 	if (str == NULL) {
+ 		return NULL;
+ 	}
+-	str += strspn(str, sep);
++	str += strspn(str, sep);	/* skip any separators */
+ 	if ((p = strpbrk(str, sep)) != NULL) {
+ 		*lasts = p + 1;
+ 		*p = '\0';
+ 	} else {
++		if (!*str)
++			str = NULL;
+ 		*lasts = NULL;
+ 	}
+ 	return str;
+ }
++
++#ifdef TDS_INTERNAL_TEST
++
++/* gcc -O2 -Wall strtok_r.c -o strtok -DTDS_INTERNAL_TEST -I../../include -DHAVE_CONFIG_H */
++
++#include <stdlib.h>
++
++static void
++test(const char *s, const char *sep)
++{
++	size_t len = strlen(s);
++	char *c1 = (char*) malloc(len+1);
++	char *c2 = (char*) malloc(len+1);
++	char *last = NULL, *s1, *s2;
++	const char *p1, *p2;
++
++	printf("testint '%s' with '%s' separator(s)\n", s, sep);
++	strcpy(c1, s);
++	strcpy(c2, s);
++
++	s1 = c1;
++	s2 = c2;
++	for (;;) {
++		p1 = strtok(s1, sep);
++		p2 = strtok_r(s2, sep, &last);
++		s1 = s2 = NULL;
++		if ((p1 && !p2) || (!p1 && p2)) {
++			fprintf(stderr, "ptr mistmach %p %p\n", p1, p2);
++			exit(1);
++		}
++		if (!p1)
++			break;
++		if (strcmp(p1, p2) != 0) {
++			fprintf(stderr, "string mistmach '%s' '%s'\n", p1, p2);
++			exit(1);
++		}
++		printf("got string %s\n", p1);
++	}
++	printf("\n");
++}
++
++int
++main(void)
++{
++	test("a b\tc", "\t ");
++	test("    x  y \t  z", " \t");
++	test("a;b;c;", ";");
++	test("a;b;  c;;", ";");
++	test("", ";");
++	test(";;;", ";");
++	return 0;
++}
++#endif
++
+
+commit 268c6633dabdcf27f7146b33bead3532a71c27a4
+Author: jklowden <jklowden>
+Date:   Tue Jan 12 15:43:17 2010 +0000
+
+    Win32 support: Added getopt.c from NetBSD and made tsql  compile without warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index 86f1486..686adbe 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Tue Jan 12 10:38:18 EST 2010	JK Lowden <jklowden@freetds.org>
++	* Makefile.am src/apps/tsql.c src/replacements/getopt.c
++	* win32/config.h
++	- Win32 support: Added getopt.c from NetBSD and made tsql 
++	- compile without warnings
++
+ Tue Jan 12 11:20:04 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/strtok_r.c: Fix strtok_r function
+ 
+@@ -2121,4 +2127,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2939 2010/01/12 10:20:41 freddy77 Exp $
++$Id: ChangeLog,v 1.2940 2010/01/12 15:43:17 jklowden Exp $
+diff --git a/Makefile.am b/Makefile.am
+index 516be66..cb83226 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-# version $Id: Makefile.am,v 1.45 2008/11/12 20:58:45 freddy77 Exp $
++# version $Id: Makefile.am,v 1.46 2010/01/12 15:43:17 jklowden Exp $
+ 
+ ## SUBDIRS determines in which directories automake will generate a Makefile
+ ## See also AC_OUTPUT in configure.ac
+@@ -18,7 +18,7 @@ VMS	=	vms/config_h.vms \
+ EXTRA_DIST = 	$(VMS) interfaces PWD.in BUGS \
+ 		freetds.conf locales.conf \
+ 		autogen.sh freetds.spec.in freetds.spec tds.dox \
+-		config.rpath
++		config.rpath Nmakefile
+ 
+ 
+ ETC	=	$(DESTDIR)$(sysconfdir)
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 309879c..a1d716b 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -59,7 +59,9 @@
+ #endif /* HAVE_STRING_H */
+ 
+ #if HAVE_UNISTD_H
+-#include <unistd.h>
++# include <unistd.h>
++#elif defined(_WIN32)
++# include <io.h>
+ #endif /* HAVE_UNISTD_H */
+ 
+ /* HP-UX require some constants defined by limits.h */
+@@ -85,7 +87,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.131 2010/01/08 22:08:01 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.132 2010/01/12 15:43:17 jklowden Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -115,7 +117,7 @@ static void tsql_print_usage(const char *progname);
+ static int get_opt_flags(char *s, int *opt_flags);
+ static void populate_login(TDSLOGIN * login, int argc, char **argv);
+ static int tsql_handle_message(const TDSCONTEXT * context, TDSSOCKET * tds, TDSMESSAGE * msg);
+-static void slurp_input_file(char *fname, char **mybuf, int *bufsz, size_t *buflen, int *line);
++static void slurp_input_file(char *fname, char **mybuf, size_t *bufsz, size_t *buflen, int *line);
+ 
+ static char *
+ tsql_readline(char *prompt)
+@@ -138,7 +140,7 @@ tsql_readline(char *prompt)
+ 		printf("%s", prompt);
+ 	for (;;) {
+ 		/* read a piece */
+-		if (fgets(line + pos, sz - pos, stdin) == NULL) {
++		if (fgets(line + pos, (int)(sz - pos), stdin) == NULL) {
+ 			if (pos)
+ 				return line;
+ 			break;
+@@ -624,7 +626,7 @@ tsql_handle_message(const TDSCONTEXT * context, TDSSOCKET * tds, TDSMESSAGE * ms
+ }
+ 
+ static void
+-slurp_input_file(char *fname, char **mybuf, int *bufsz, size_t *buflen, int *line)
++slurp_input_file(char *fname, char **mybuf, size_t *bufsz, size_t *buflen, int *line)
+ {
+ 	FILE *fp = NULL;
+ 	register char *n;
+@@ -668,7 +670,7 @@ main(int argc, char **argv)
+ 	char prompt[20];
+ 	int line = 0;
+ 	char *mybuf;
+-	int bufsz = 4096;
++	size_t bufsz = 4096;
+ 	size_t buflen = 0;
+ 	TDSSOCKET *tds;
+ 	TDSLOGIN *login;
+diff --git a/src/replacements/getopt.c b/src/replacements/getopt.c
+new file mode 100644
+index 0000000..3a51ef6
+--- /dev/null
++++ b/src/replacements/getopt.c
+@@ -0,0 +1,164 @@
++/*	$NetBSD: getopt.c,v 1.27 2005/11/29 03:12:00 christos Exp $	*/
++
++/*
++ * Copyright (c) 1987, 1993, 1994
++ *	The Regents of the University of California.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#undef LIBC_SCCS
++
++#if !defined(_WIN32)
++# include <sys/cdefs.h>
++#else
++# define __UNCONST(x) ((char*)(x)) 
++# define getprogname() (nargv[0])
++# define _DIAGASSERT(x) assert((x))
++#endif
++
++#ifdef _FREETDS_LIBRARY_SOURCE
++# include "tds_sysdep_private.h"
++#endif /* _FREETDS_LIBRARY_SOURCE */
++
++#if defined(LIBC_SCCS) && !defined(lint)
++# if 0
++  static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
++# else
++  __RCSID("$NetBSD: getopt.c,v 1.27 2005/11/29 03:12:00 christos Exp $");
++# endif
++#else 
++ TDS_RCSID(var, "$Id: getopt.c,v 1.1 2010/01/12 15:43:17 jklowden Exp $");
++#endif /* LIBC_SCCS and not lint */
++
++#if !defined(_WIN32)
++# include "namespace.h"
++#endif
++
++#include <assert.h>
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#if !defined(_WIN32)
++# include <unistd.h>
++#endif
++
++#ifdef __weak_alias
++__weak_alias(getopt,_getopt)
++#endif
++
++int	opterr = 1,		/* if error message should be printed */
++	optind = 1,		/* index into parent argv vector */
++	optopt,			/* character checked for validity */
++	optreset;		/* reset getopt */
++char	*optarg;		/* argument associated with option */
++
++#define	BADCH	(int)'?'
++#define	BADARG	(int)':'
++#define	EMSG	""
++
++/*
++ * getopt --
++ *	Parse argc/argv argument vector.
++ */
++int
++getopt(nargc, nargv, ostr)
++	int nargc;
++	char * const nargv[];
++	const char *ostr;
++{
++	static const char *place = EMSG;	/* option letter processing */
++	char *oli;				/* option letter list index */
++
++	_DIAGASSERT(nargv != NULL);
++	_DIAGASSERT(ostr != NULL);
++
++	if (optreset || *place == 0) {		/* update scanning pointer */
++		optreset = 0;
++		place = nargv[optind];
++		if (optind >= nargc || *place++ != '-') {
++			/* Argument is absent or is not an option */
++			place = EMSG;
++			return (-1);
++		}
++		optopt = *place++;
++		if (optopt == '-' && *place == 0) {
++			/* "--" => end of options */
++			++optind;
++			place = EMSG;
++			return (-1);
++		}
++		if (optopt == 0) {
++			/* Solitary '-', treat as a '-' option
++			   if the program (eg su) is looking for it. */
++			place = EMSG;
++			if (strchr(ostr, '-') == NULL)
++				return -1;
++			optopt = '-';
++		}
++	} else
++		optopt = *place++;
++
++	/* See if option letter is one the caller wanted... */
++	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
++		if (*place == 0)
++			++optind;
++		if (opterr && *ostr != ':')
++			(void)fprintf(stderr,
++			    "%s: unknown option -- %c\n", getprogname(),
++			    optopt);
++		return (BADCH);
++	}
++
++	/* Does this option need an argument? */
++	if (oli[1] != ':') {
++		/* don't need argument */
++		optarg = NULL;
++		if (*place == 0)
++			++optind;
++	} else {
++		/* Option-argument is either the rest of this argument or the
++		   entire next argument. */
++		if (*place)
++			optarg = __UNCONST(place);
++		else if (nargc > ++optind)
++			optarg = nargv[optind];
++		else {
++			/* option-argument absent */
++			place = EMSG;
++			if (*ostr == ':')
++				return (BADARG);
++			if (opterr)
++				(void)fprintf(stderr,
++				    "%s: option requires an argument -- %c\n",
++				    getprogname(), optopt);
++			return (BADCH);
++		}
++		place = EMSG;
++		++optind;
++	}
++	return (optopt);			/* return option letter */
++}
+diff --git a/win32/config.h b/win32/config.h
+index 34ade6a..46dfe26 100644
+--- a/win32/config.h
++++ b/win32/config.h
+@@ -246,4 +246,4 @@
+ 
+ typedef SSIZE_T ssize_t;
+ 
+-
++#define HAVE_LOCALE_H 1
+
+commit 81fddf4c2299233f690b502be1134dc0fed2dab0
+Author: freddy77 <freddy77>
+Date:   Thu Jan 21 08:27:44 2010 +0000
+
+    Unify includes in VC++ projects, cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index 686adbe..09ef439 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jan 21 09:24:26 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/db-lib.vcproj src/replacements/replacements.vcproj:
++	* src/tds/TDS.vcproj:
++	- Unify includes in VC++ projects, cleanup
++
+ Tue Jan 12 10:38:18 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* Makefile.am src/apps/tsql.c src/replacements/getopt.c
+ 	* win32/config.h
+@@ -2127,4 +2132,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2940 2010/01/12 15:43:17 jklowden Exp $
++$Id: ChangeLog,v 1.2941 2010/01/21 08:27:44 freddy77 Exp $
+diff --git a/src/dblib/db-lib.vcproj b/src/dblib/db-lib.vcproj
+index 1c632d9..9c2817b 100755
+--- a/src/dblib/db-lib.vcproj
++++ b/src/dblib/db-lib.vcproj
+@@ -42,7 +42,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				ExceptionHandling="0"
+@@ -109,7 +109,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				ExceptionHandling="0"
+@@ -178,8 +178,8 @@
+ 			/>
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				WarningLevel="3"
+ 				Detect64BitPortabilityProblems="true"
+@@ -240,8 +240,8 @@
+ 			/>
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				WarningLevel="3"
+ 				Detect64BitPortabilityProblems="true"
+diff --git a/src/replacements/replacements.vcproj b/src/replacements/replacements.vcproj
+index 9665e45..2e5f922 100755
+--- a/src/replacements/replacements.vcproj
++++ b/src/replacements/replacements.vcproj
+@@ -42,7 +42,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				BasicRuntimeChecks="3"
+@@ -105,7 +105,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				BasicRuntimeChecks="3"
+@@ -167,8 +167,8 @@
+ 			/>
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
++				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				WarningLevel="3"
+ 				Detect64BitPortabilityProblems="true"
+@@ -228,8 +228,8 @@
+ 			/>
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+-				AdditionalIncludeDirectories="..\..\include;..\..\include\x64"
+-				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
++				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				WarningLevel="3"
+ 				Detect64BitPortabilityProblems="true"
+diff --git a/src/tds/TDS.vcproj b/src/tds/TDS.vcproj
+index 8faeebb..5e8f110 100755
+--- a/src/tds/TDS.vcproj
++++ b/src/tds/TDS.vcproj
+@@ -41,7 +41,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+-				AdditionalIncludeDirectories="../../include;../../include/x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				BasicRuntimeChecks="3"
+@@ -105,7 +105,7 @@
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+ 				Optimization="0"
+-				AdditionalIncludeDirectories="../../include;../../include/x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;_DEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				MinimalRebuild="true"
+ 				ExceptionHandling="0"
+@@ -169,7 +169,7 @@
+ 			/>
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+-				AdditionalIncludeDirectories="../../include;../../include/x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN32;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				UsePrecompiledHeader="0"
+@@ -229,7 +229,7 @@
+ 			/>
+ 			<Tool
+ 				Name="VCCLCompilerTool"
+-				AdditionalIncludeDirectories="../../include;../../include/x64"
++				AdditionalIncludeDirectories="..\..\win32;..\..\include"
+ 				PreprocessorDefinitions="WIN64;HAVE_CONFIG_H;_FREETDS_LIBRARY_SOURCE;NDEBUG;_LIB;_CRT_SECURE_NO_WARNINGS"
+ 				RuntimeLibrary="0"
+ 				UsePrecompiledHeader="0"
+@@ -337,20 +337,8 @@
+ 				>
+ 			</File>
+ 			<File
+-				RelativePath=".\unittests\common.c"
+-				>
+-			</File>
+-			<File
+ 				RelativePath=".\config.c"
+ 				>
+-				<FileConfiguration
+-					Name="Debug|Win32"
+-					>
+-					<Tool
+-						Name="VCCLCompilerTool"
+-						ShowIncludes="false"
+-					/>
+-				</FileConfiguration>
+ 			</File>
+ 			<File
+ 				RelativePath=".\convert.c"
+
+commit b992516db08e5d1b7e8502b982053ab5a39bc844
+Author: freddy77 <freddy77>
+Date:   Thu Jan 21 08:34:04 2010 +0000
+
+    Distribute VC++ projects
+
+diff --git a/ChangeLog b/ChangeLog
+index 09ef439..1a7d712 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jan 21 09:33:32 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* Makefile.am src/dblib/Makefile.am src/replacements/Makefile.am:
++	* src/tds/Makefile.am:
++	- Distribute VC++ projects
++
+ Thu Jan 21 09:24:26 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/db-lib.vcproj src/replacements/replacements.vcproj:
+ 	* src/tds/TDS.vcproj:
+@@ -2132,4 +2137,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2941 2010/01/21 08:27:44 freddy77 Exp $
++$Id: ChangeLog,v 1.2942 2010/01/21 08:34:04 freddy77 Exp $
+diff --git a/Makefile.am b/Makefile.am
+index cb83226..1ae6503 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-# version $Id: Makefile.am,v 1.46 2010/01/12 15:43:17 jklowden Exp $
++# version $Id: Makefile.am,v 1.47 2010/01/21 08:34:04 freddy77 Exp $
+ 
+ ## SUBDIRS determines in which directories automake will generate a Makefile
+ ## See also AC_OUTPUT in configure.ac
+@@ -18,7 +18,7 @@ VMS	=	vms/config_h.vms \
+ EXTRA_DIST = 	$(VMS) interfaces PWD.in BUGS \
+ 		freetds.conf locales.conf \
+ 		autogen.sh freetds.spec.in freetds.spec tds.dox \
+-		config.rpath Nmakefile
++		config.rpath Nmakefile FreeTDS.sln
+ 
+ 
+ ETC	=	$(DESTDIR)$(sysconfdir)
+diff --git a/src/dblib/Makefile.am b/src/dblib/Makefile.am
+index c3b422f..c76d796 100644
+--- a/src/dblib/Makefile.am
++++ b/src/dblib/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.36 2007/11/22 08:44:54 freddy77 Exp $
++# $Id: Makefile.am,v 1.37 2010/01/21 08:34:04 freddy77 Exp $
+ SUBDIRS		=	unittests
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include
+ 
+@@ -11,7 +11,7 @@ MINGW_SOURCES   =	../../win32/initnet.c
+ else
+ MINGW_SOURCES   =
+ endif
+-EXTRA_DIST	=	dbopen.c buffering.h
++EXTRA_DIST	=	dbopen.c buffering.h db-lib.vcproj
+ libsybdb_la_SOURCES=	dblib.c dbutil.c rpc.c bcp.c xact.c $(DBOPEN) $(MINGW_SOURCES)
+ # version bumped for 0.63, I hope we'll bump it less in the future -- freddy77
+ if MACOSX
+diff --git a/src/replacements/Makefile.am b/src/replacements/Makefile.am
+index 3d9e5e2..6ce28ca 100644
+--- a/src/replacements/Makefile.am
++++ b/src/replacements/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.15 2009/01/07 02:58:37 jklowden Exp $
++# $Id: Makefile.am,v 1.16 2010/01/21 08:34:04 freddy77 Exp $
+ AM_CPPFLAGS=			-I$(top_srcdir)/include -I$(top_srcdir)/src/replacements
+ noinst_LTLIBRARIES=		libreplacements.la
+ libreplacements_la_SOURCES=	iconv.c gettimeofday.c fakepoll.c
+@@ -11,5 +11,6 @@ EXTRA_DIST=	asprintf.c \
+ 		strlcat.c \
+ 		strlcpy.c \
+ 		strtok_r.c \
+-		vasprintf.c 
++		vasprintf.c \
++		replacements.vcproj
+ 
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index a2d4974..c0b887c 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.68 2008/12/12 13:56:11 freddy77 Exp $
++# $Id: Makefile.am,v 1.69 2010/01/21 08:34:04 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -14,7 +14,7 @@ libtds_la_LDFLAGS=
+ libtds_la_LIBADD=
+ 
+ noinst_HEADERS		= tds_willconvert.h encodings.h num_limits.h types.h
+-EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h types.h
++EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h types.h TDS.vcproj
+ 
+ if HAVE_DOXYGEN
+ doxyfile: $(srcdir)/tds.dox
+
+commit 1ae9baf6f157d45c7760b5445ca7ccfd5c96e091
+Author: freddy77 <freddy77>
+Date:   Thu Jan 21 13:41:31 2010 +0000
+
+    Really override server settings using extended server syntax
+
+diff --git a/ChangeLog b/ChangeLog
+index 1a7d712..032c7ff 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jan 21 14:39:15 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c:
++	- Really override server settings using extended server syntax
++
+ Thu Jan 21 09:33:32 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* Makefile.am src/dblib/Makefile.am src/replacements/Makefile.am:
+ 	* src/tds/Makefile.am:
+@@ -2137,4 +2141,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2942 2010/01/21 08:34:04 freddy77 Exp $
++$Id: ChangeLog,v 1.2943 2010/01/21 13:41:31 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 5857c88..f216db2 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007, 2008, 2009  Frediano Ziglio
++ * Copyright (C) 2006, 2007, 2008, 2009, 2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.154 2010/01/11 18:14:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.155 2010/01/21 13:41:31 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -157,7 +157,7 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 	char *s;
+ 	char *path;
+ 	pid_t pid;
+-	int opened = 0;
++	int opened = 0, found;
+ 
+ 	/* allocate a new structure with hard coded and build-time defaults */
+ 	connection = tds_alloc_connection(locale);
+@@ -184,9 +184,16 @@ tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale)
+ 
+ 	/* Read the config files. */
+ 	tdsdump_log(TDS_DBG_INFO1, "Attempting to read conf files.\n");
+-	if (!tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name)) &&
+-		(!parse_server_name_for_port(connection, login) ||
+-		 !tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name)))) {
++	found = tds_read_conf_file(connection, tds_dstr_cstr(&login->server_name));
++	if (!found) {
++		if (parse_server_name_for_port(connection, login)) {
++			found = tds_read_conf_file(connection, tds_dstr_cstr(&connection->server_name));
++			/* do it again to really override what found in freetds.conf */
++			if (found)
++				parse_server_name_for_port(connection, login);
++		}
++	}
++	if (!found) {
+ 		/* fallback to interfaces file */
+ 		tdsdump_log(TDS_DBG_INFO1, "Failed in reading conf file.  Trying interface files.\n");
+ 		if (!tds_read_interfaces(tds_dstr_cstr(&login->server_name), connection)) {
+@@ -1085,6 +1092,7 @@ parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login)
+ 	if (pSep && pSep != server) {	/* yes, i found it! */
+ 		/* modify connection-> && login->server_name & ->port */
+ 		login->port = connection->port = atoi(pSep + 1);
++		tds_dstr_copy(&connection->instance_name, "");
+ 	} else {
+ 		/* handle instance name */
+ 		pSep = strrchr(server, '\\');
+@@ -1092,10 +1100,10 @@ parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login)
+ 			return 0;
+ 
+ 		tds_dstr_copy(&connection->instance_name, pSep + 1);
++		connection->port = 0;
+ 	}
+ 
+-	tds_dstr_setlen(&login->server_name, pSep - server);
+-	if (!tds_dstr_dup(&connection->server_name, &login->server_name))
++	if (!tds_dstr_copyn(&connection->server_name, server, pSep - server))
+ 		return 0;
+ 
+ 	return 1;
+
+commit 19e307852b57f71989b8cfac69c852c631aa3744
+Author: freddy77 <freddy77>
+Date:   Fri Jan 22 09:37:58 2010 +0000
+
+    do not clean VC++ project files
+
+diff --git a/ChangeLog b/ChangeLog
+index 032c7ff..f49eed6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 22 10:37:50 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/Makefile.am: do not clean VC++ project files
++
+ Thu Jan 21 14:39:15 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c:
+ 	- Really override server settings using extended server syntax
+@@ -2141,4 +2144,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2943 2010/01/21 13:41:31 freddy77 Exp $
++$Id: ChangeLog,v 1.2944 2010/01/22 09:37:58 freddy77 Exp $
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index c0b887c..60a194c 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.69 2010/01/21 08:34:04 freddy77 Exp $
++# $Id: Makefile.am,v 1.70 2010/01/22 09:37:58 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -41,7 +41,7 @@ if HAVE_PERL_SOURCES
+ BUILT_SOURCES = tds_willconvert.h encodings.h num_limits.h types.h
+ 
+ clean-local: 
+-	cd $(srcdir) && rm -f $(EXTRA_DIST)
++	cd $(srcdir) && rm -f $(BUILT_SOURCES)
+ 	
+ tds_willconvert.h: tds_willconvert.pl Makefile
+ 	perl $(srcdir)/tds_willconvert.pl > $@.tmp
+
+commit 9c401a369a4dc34714c65893e268d32803c17ddd
+Author: freddy77 <freddy77>
+Date:   Fri Jan 22 10:43:48 2010 +0000
+
+    do not define tds_swap_datatype if not needed
+
+diff --git a/ChangeLog b/ChangeLog
+index f49eed6..f92ab09 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jan 22 11:43:29 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/token.c:
++	- do not define tds_swap_datatype if not needed
++
+ Fri Jan 22 10:37:50 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/Makefile.am: do not clean VC++ project files
+ 
+@@ -2144,4 +2148,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2944 2010/01/22 09:37:58 freddy77 Exp $
++$Id: ChangeLog,v 1.2945 2010/01/22 10:43:48 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index c278da4..634d348 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -1,5 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
++ * Copyright (C) 2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -20,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.325 2010/01/11 18:14:10 freddy77 Exp $ */
++/* $Id: tds.h,v 1.326 2010/01/22 10:43:48 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1516,7 +1517,9 @@ int tds_multiple_execute(TDSSOCKET *tds, TDSMULTIPLE *multiple, TDSDYNAMIC * dyn
+ 
+ /* token.c */
+ int tds_process_cancel(TDSSOCKET * tds);
++#ifdef WORDS_BIGENDIAN
+ void tds_swap_datatype(int coltype, unsigned char *buf);
++#endif
+ void tds_swap_numeric(TDS_NUMERIC *num);
+ int tds_get_token_size(int marker);
+ int tds_process_login_tokens(TDSSOCKET * tds);
+diff --git a/src/tds/token.c b/src/tds/token.c
+index f8140b4..22ad851 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005, 2006, 2007, 2008  Frediano Ziglio
++ * Copyright (C) 2005-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.378 2010/01/11 17:56:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.379 2010/01/22 10:43:48 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -3016,6 +3016,7 @@ tds_get_token_size(int marker)
+ 	}
+ }
+ 
++#ifdef WORDS_BIGENDIAN
+ void
+ tds_swap_datatype(int coltype, unsigned char *buf)
+ {
+@@ -3048,6 +3049,7 @@ tds_swap_datatype(int coltype, unsigned char *buf)
+ 		break;
+ 	}
+ }
++#endif
+ 
+ void
+ tds_swap_numeric(TDS_NUMERIC *num)
+
+commit 7fce903704886efd245acffefc5ce1f004c392e3
+Author: freddy77 <freddy77>
+Date:   Fri Jan 22 10:45:19 2010 +0000
+
+    check _SQLFreeDesc
+
+diff --git a/ChangeLog b/ChangeLog
+index f92ab09..406feed 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 22 11:45:04 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/copydesc.c: check _SQLFreeDesc
++
+ Fri Jan 22 11:43:29 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/token.c:
+ 	- do not define tds_swap_datatype if not needed
+@@ -2148,4 +2151,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2945 2010/01/22 10:43:48 freddy77 Exp $
++$Id: ChangeLog,v 1.2946 2010/01/22 10:45:19 freddy77 Exp $
+diff --git a/src/odbc/unittests/copydesc.c b/src/odbc/unittests/copydesc.c
+index 9488154..5771490 100644
+--- a/src/odbc/unittests/copydesc.c
++++ b/src/odbc/unittests/copydesc.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLCopyDesc and SQLAllocHandle(SQL_HANDLE_DESC) */
+ 
+-static char software_version[] = "$Id: copydesc.c,v 1.5 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: copydesc.c,v 1.6 2010/01/22 10:45:19 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -30,6 +30,8 @@ main(int argc, char *argv[])
+ 
+ 	CHKR(SQLCopyDesc, (ard, ard2), "S");
+ 
++	CHKFreeHandle(SQL_HANDLE_DESC, ard3, "S");
++
+ 	Disconnect();
+ 
+ 	printf("Done.\n");
+
+commit a37f67419ab3b12d9677faada1ac03a1ab257551
+Author: freddy77 <freddy77>
+Date:   Fri Jan 22 12:42:13 2010 +0000
+
+    package bzip2 file instead of gz one
+
+diff --git a/ChangeLog b/ChangeLog
+index 406feed..4c2fbb7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Jan 22 13:40:35 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac freetds.spec.in misc/prepare_win32.sh:
++	* misc/test-dist.sh:
++	- package bzip2 file instead of gz one
++
+ Fri Jan 22 11:45:04 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/copydesc.c: check _SQLFreeDesc
+ 
+@@ -2151,4 +2156,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2946 2010/01/22 10:45:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2947 2010/01/22 12:42:13 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 3653456..451232a 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.43 2009/09/14 10:02:13 freddy77 Exp $
++dnl $Id: configure.ac,v 1.44 2010/01/22 12:42:16 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,9 +15,9 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.43 $)
++AC_REVISION($Revision: 1.44 $)
+ 
+-AM_INIT_AUTOMAKE
++AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
+ AC_CONFIG_HEADERS(include/config.h)
+ 
+ dnl configuration directory will be /usr/local/etc
+diff --git a/freetds.spec.in b/freetds.spec.in
+index 8aa6485..47e2670 100644
+--- a/freetds.spec.in
++++ b/freetds.spec.in
+@@ -22,7 +22,7 @@ Release: 1
+ Vendor: www.freetds.org 
+ License: LGPL 
+ Group: System Environment/Libraries 
+-Source: http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/%{name}-%{version}.tar.gz 
++Source: http://ibiblio.org/pub/Linux/ALPHA/freetds/stable/%{name}-%{version}.tar.bz2
+ BuildRoot: %{_tmppath}/%{name}-buildroot
+ %{?tds_builddep:BuildRequires: %{tds_builddep}}
+ %{?tds_dep:Requires: %tds_dep}
+diff --git a/misc/prepare_win32.sh b/misc/prepare_win32.sh
+index 57999ff..595c4a9 100755
+--- a/misc/prepare_win32.sh
++++ b/misc/prepare_win32.sh
+@@ -67,10 +67,14 @@ if test "$PACKAGE_VERSION" = ""; then
+ 	PACKAGE_VERSION="$VERSION"
+ fi
+ test "$PACKAGE_VERSION" != "" || errore "PACKAGE_VERSION not found"
+-test -r "freetds-$PACKAGE_VERSION.tar.gz" || make dist
+-test -r "freetds-$PACKAGE_VERSION.tar.gz" || errore "package not found"
++test -r "freetds-$PACKAGE_VERSION.tar.gz" -o -r "freetds-$PACKAGE_VERSION.tar.bz2" || make dist
++test -r "freetds-$PACKAGE_VERSION.tar.gz" -o -r "freetds-$PACKAGE_VERSION.tar.bz2" || errore "package not found"
+ rm -rf "freetds-$PACKAGE_VERSION"
+-tar zxvf "freetds-$PACKAGE_VERSION.tar.gz"
++if test -r "freetds-$PACKAGE_VERSION.tar.gz"; then
++	gunzip -dc "freetds-$PACKAGE_VERSION.tar.gz" | tar xvf -
++else
++	bunzip2 -dc "freetds-$PACKAGE_VERSION.tar.bz2" | tar xvf -
++fi
+ cd "freetds-$PACKAGE_VERSION" || errore "Directory not found"
+ 
+ if ! $HOST-gcc --help > /dev/null 2> /dev/null; then
+diff --git a/misc/test-dist.sh b/misc/test-dist.sh
+index 02b5080..354d394 100755
+--- a/misc/test-dist.sh
++++ b/misc/test-dist.sh
+@@ -55,8 +55,8 @@ make dist
+ echo "make distribution ok" >> "$LOG"
+ 
+ # untar to test it, should already contains documentation
+-DIR=`echo freetds-* | sed s,.tar.gz$,,g`
+-gunzip -dc freetds-*.tar.gz | tar xf -
++DIR=`echo freetds-* | sed s,.tar.bz2$,,g`
++bzip2 -dc freetds-*.tar.bz2 | tar xf -
+ test -d "$DIR"
+ cd "$DIR"
+ echo "untar ok" >> "$LOG"
+@@ -116,7 +116,7 @@ make dist
+ # finally big test. I hope you have a fast machine :)
+ cd ..
+ rm -rf "$DIR"
+-gunzip -dc freetds-*.tar.gz | tar xf -
++bzip2 -dc freetds-*.tar.bz2 | tar xf -
+ cd "$DIR"
+ ./configure
+ if test ! -e PWD -a -e "$ORIGDIR/../PWD"; then
+@@ -139,7 +139,7 @@ if rpmbuild --help > /dev/null 2>&1; then
+ 	RPMCMD=rpmbuild
+ fi
+ if $RPMCMD --help > /dev/null 2>&1; then
+-	$RPMCMD -ta freetds-*.tar.gz || exit 1
++	$RPMCMD -ta freetds-*.tar.bz2 || exit 1
+ 	echo "rpm test ok" >> "$LOG"
+ else
+ 	echo "rpm test skipped, no rpm detected" >> "$LOG"
+
+commit 1c4d4f690042f978c44f4307960dcf9652e0db43
+Author: jklowden <jklowden>
+Date:   Fri Jan 22 22:41:47 2010 +0000
+
+    error message when hostfile wider than table
+
+diff --git a/ChangeLog b/ChangeLog
+index 4c2fbb7..d6f7d4e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 22 17:39:39 EST 2010	JK Lowden <jklowden@freetds.org>
++	* src/dblib/bcp.c error message when hostfile wider than table.
++
+ Fri Jan 22 13:40:35 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac freetds.spec.in misc/prepare_win32.sh:
+ 	* misc/test-dist.sh:
+@@ -2156,4 +2159,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2947 2010/01/22 12:42:13 freddy77 Exp $
++$Id: ChangeLog,v 1.2948 2010/01/22 22:41:47 jklowden Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index db4bac0..692409c 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -62,7 +62,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.191 2010/01/10 14:43:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.192 2010/01/22 22:41:48 jklowden Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -1151,13 +1151,22 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 		 * FIXME I think tab_colnum can be out of range - freddy77
+ 		 */
+ 		if (hostcol->tab_colnum) {
++			if (hostcol->tab_colnum > dbproc->bcpinfo->bindinfo->num_cols) {
++				tdsdump_log(TDS_DBG_FUNC, "error: file wider than table: %d/%d\n", 
++							  i+1, dbproc->bcpinfo->bindinfo->num_cols);
++				dbperror(dbproc, SYBEBEOF, NULL);
++				return FAIL;
++			}
++			tdsdump_log(TDS_DBG_FUNC, "host column %d uses bcpcol %d (%p)\n", 
++				                  i+1, hostcol->tab_colnum, bcpcol);
+ 			bcpcol = dbproc->bcpinfo->bindinfo->columns[hostcol->tab_colnum - 1];
++			assert(bcpcol != NULL);
+ 		}
+ 
+ 		/* detect prefix len */
+ 		if (bcpcol && hostcol->prefix_len == -1) {
+-			int plen = bcpcol->column_varint_size;
+-			hostcol->prefix_len = plen == 5 ? 4 : plen;
++			int len = bcpcol->column_varint_size;
++			hostcol->prefix_len = len == 5 ? 4 : len;
+ 		}
+ 
+ 		/* a prefix length, if extant, specifies how many bytes to read */
+
+commit 0d402704d2da9b45414d840598dc8bddc0626f65
+Author: freddy77 <freddy77>
+Date:   Sat Jan 23 20:25:56 2010 +0000
+
+    Removed 2009-12-22 patch "Better way to fix data_type for date" which does not work on Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index d6f7d4e..dd9a1db 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sat Jan 23 21:25:35 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c:
++	- Removed 2009-12-22 patch "Better way to fix data_type for date"
++	  which does not work on Sybase
++
+ Fri Jan 22 17:39:39 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/bcp.c error message when hostfile wider than table.
+ 
+@@ -2159,4 +2164,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2948 2010/01/22 22:41:47 jklowden Exp $
++$Id: ChangeLog,v 1.2949 2010/01/23 20:25:56 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 722548f..a9abcc1 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001  Brian Bruns
+- * Copyright (C) 2002-2008  Frediano Ziglio
++ * Copyright (C) 2002-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.525 2010/01/10 14:43:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.526 2010/01/23 20:25:56 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -88,7 +88,7 @@ static void odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name);
+ static SQLRETURN odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...);
+ static SQLRETURN odbc_free_dynamic(TDS_STMT * stmt);
+ static SQLRETURN odbc_free_cursor(TDS_STMT * stmt);
+-static SQLSMALLINT odbc_fix_datetime_sql_type(SQLSMALLINT sql_type, SQLINTEGER odbc_version);
++static SQLSMALLINT odbc_swap_datetime_sql_type(SQLSMALLINT sql_type);
+ static int odbc_process_tokens(TDS_STMT * stmt, unsigned flag);
+ static int odbc_lock_statement(TDS_STMT* stmt);
+ 
+@@ -3458,12 +3458,12 @@ odbc_fix_data_type_col(TDS_STMT *stmt, int idx)
+ 	switch (tds_get_conversion_type(colinfo->column_type, colinfo->column_size)) {
+ 	case SYBINT2: {
+ 		TDS_SMALLINT *data = (TDS_SMALLINT *) colinfo->column_data;
+-		*data = odbc_fix_datetime_sql_type(*data, stmt->dbc->env->attr.odbc_version);
++		*data = odbc_swap_datetime_sql_type(*data);
+ 		}
+ 		break;
+ 	case SYBINT4: {
+ 		TDS_INT *data = (TDS_INT *) colinfo->column_data;
+-		*data = odbc_fix_datetime_sql_type(*data, stmt->dbc->env->attr.odbc_version);
++		*data = odbc_swap_datetime_sql_type(*data);
+ 		}
+ 		break;
+ 	}
+@@ -5766,20 +5766,26 @@ odbc_upper_column_names(TDS_STMT * stmt)
+ }
+ 
+ static SQLSMALLINT
+-odbc_fix_datetime_sql_type(SQLSMALLINT sql_type, SQLINTEGER odbc_version)
++odbc_swap_datetime_sql_type(SQLSMALLINT sql_type)
+ {
+ 	switch (sql_type) {
+-	case SQL_TIMESTAMP:
+ 	case SQL_TYPE_TIMESTAMP:
+-		sql_type = odbc_version != SQL_OV_ODBC2 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP;
++		sql_type = SQL_TIMESTAMP;
++		break;
++	case SQL_TIMESTAMP:
++		sql_type = SQL_TYPE_TIMESTAMP;
+ 		break;
+-	case SQL_DATE:
+ 	case SQL_TYPE_DATE:
+-		sql_type = odbc_version != SQL_OV_ODBC2 ? SQL_TYPE_DATE : SQL_DATE;
++		sql_type = SQL_DATE;
++		break;
++	case SQL_DATE:
++		sql_type = SQL_TYPE_DATE;
+ 		break;
+-	case SQL_TIME:
+ 	case SQL_TYPE_TIME:
+-		sql_type = odbc_version != SQL_OV_ODBC2 ? SQL_TYPE_TIME : SQL_TIME;
++		sql_type = SQL_TIME;
++		break;
++	case SQL_TIME:
++		sql_type = SQL_TYPE_TIME;
+ 		break;
+ 	}
+ 	return sql_type;
+@@ -5810,7 +5816,7 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 	/* TODO ODBC3 convert type to ODBC version 2 (date) */
+ 	if (odbc3) {
+ 		if (TDS_IS_SYBASE(tds)) {
+-			sprintf(sql, sql_templ, odbc_fix_datetime_sql_type(fSqlType, SQL_OV_ODBC2));
++			sprintf(sql, sql_templ, odbc_swap_datetime_sql_type(fSqlType));
+ 			stmt->special_row = ODBC_SPECIAL_GETTYPEINFO;
+ 		} else {
+ 			sprintf(sql, sql_templ, fSqlType);
+
+commit 542c8c6a5acb02612da4c7856b22c4599736a122
+Author: freddy77 <freddy77>
+Date:   Sat Jan 23 20:42:25 2010 +0000
+
+    silly patch for Sybase bigint
+
+diff --git a/ChangeLog b/ChangeLog
+index dd9a1db..efc0fd2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jan 23 21:42:18 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c: silly patch for Sybase bigint
++
+ Sat Jan 23 21:25:35 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c:
+ 	- Removed 2009-12-22 patch "Better way to fix data_type for date"
+@@ -2164,4 +2167,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2949 2010/01/23 20:25:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2950 2010/01/23 20:42:25 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 99ce907..3ef090d 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005, 2006, 2007, 2008 Frediano Ziglio
++ * Copyright (C) 2005-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.110 2009/11/27 18:01:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.111 2010/01/23 20:42:25 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -271,6 +271,7 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBBITN:
+ 		return SQL_BIT;
+ #if (ODBCVER >= 0x0300)
++	case SYB5INT8:
+ 	case SYBINT8:
+ 		/* TODO return numeric for odbc2 and convert bigint to numeric */
+ 		return SQL_BIGINT;
+@@ -355,7 +356,6 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBUINT1:
+ 	case SYBDATE:
+ 	case SYBDATEN:
+-	case SYB5INT8:
+ 	case SYBINTERVAL:
+ 	case SYBTIME:
+ 	case SYBTIMEN:
+
+commit 96053bf4b0f81b78a0a57a9b3a3b65f1e8b31d98
+Author: freddy77 <freddy77>
+Date:   Mon Jan 25 14:24:11 2010 +0000
+
+    update copyright note
+
+diff --git a/ChangeLog b/ChangeLog
+index efc0fd2..c5958ee 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jan 25 15:23:22 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/version.rc.in: update copyright note
++
+ Sat Jan 23 21:42:18 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c: silly patch for Sybase bigint
+ 
+@@ -2167,4 +2170,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2950 2010/01/23 20:42:25 freddy77 Exp $
++$Id: ChangeLog,v 1.2951 2010/01/25 14:24:11 freddy77 Exp $
+diff --git a/win32/version.rc.in b/win32/version.rc.in
+index 9ec80ff..5ca43bf 100644
+--- a/win32/version.rc.in
++++ b/win32/version.rc.in
+@@ -27,7 +27,7 @@ BEGIN
+             VALUE "FileDescription", "FreeTDS\0"
+             VALUE "FileVersion", "@MAJOR@, @MINOR@, @SUBVERSION@, @BUILD_NUMBER@\0"
+             VALUE "InternalName", "FreeTDS\0"
+-            VALUE "LegalCopyright", "Copyright © 2004-2007 under terms of GNU LGPL\0"
++            VALUE "LegalCopyright", "Copyright © 2004-2010 under terms of GNU LGPL\0"
+             VALUE "LegalTrademarks", "\0"
+             VALUE "OriginalFilename", "FreeTDS.dll\0"
+             VALUE "PrivateBuild", "\0"
+
+commit 552870a0b90f03217df4a96e5c539f5b79952c02
+Author: freddy77 <freddy77>
+Date:   Mon Jan 25 23:05:58 2010 +0000
+
+    fix visilibility warning using mingw
+
+diff --git a/ChangeLog b/ChangeLog
+index c5958ee..8ad300a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,11 @@
++Tue Jan 26 00:05:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/ctlib.h include/dblib.h include/des.h include/hmac_md5.h:
++	* include/md4.h include/md5.h include/replacements.h:
++	* include/replacements/readpassphrase.h include/tds.h:
++	* include/tdsconvert.h include/tdsiconv.h include/tdsodbc.h:
++	* include/tdsstring.h src/tds/tds_checks.h:
++	- fix visilibility warning using mingw
++
+ Mon Jan 25 15:23:22 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/version.rc.in: update copyright note
+ 
+@@ -2170,4 +2178,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2951 2010/01/25 14:24:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2952 2010/01/25 23:05:58 freddy77 Exp $
+diff --git a/include/ctlib.h b/include/ctlib.h
+index 98e213d..0d35b98 100644
+--- a/include/ctlib.h
++++ b/include/ctlib.h
+@@ -24,7 +24,7 @@
+  * Internal (not part of the exposed API) prototypes and such.
+  */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -36,7 +36,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.28 2009/11/26 09:47:41 freddy77 Exp $";
++static const char rcsid_ctlib_h[] = "$Id: ctlib.h,v 1.29 2010/01/25 23:05:58 freddy77 Exp $";
+ static const void *const no_unused_ctlib_h_warn[] = { rcsid_ctlib_h, no_unused_ctlib_h_warn };
+ 
+ #include <tds.h>
+@@ -286,7 +286,7 @@ int _cs_locale_copy_inplace(CS_LOCALE *new_locale, CS_LOCALE *orig);
+ }
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/dblib.h b/include/dblib.h
+index 9da44de..f97b0a2 100644
+--- a/include/dblib.h
++++ b/include/dblib.h
+@@ -20,7 +20,7 @@
+ #ifndef _dblib_h_
+ #define _dblib_h_
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -32,7 +32,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: dblib.h,v 1.45 2008/12/12 13:56:11 freddy77 Exp $ */
++/* $Id: dblib.h,v 1.46 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+ typedef enum tag_DB_RESULT_STATE {
+ 	  _DB_RES_INIT
+@@ -199,7 +199,7 @@ extern EHANDLEFUNC _dblib_err_handler;
+ }
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/des.h b/include/des.h
+index 6eaaa44..612edf1 100644
+--- a/include/des.h
++++ b/include/des.h
+@@ -1,9 +1,9 @@
+ #ifndef DES_H
+ #define DES_H
+ 
+-/* $Id: des.h,v 1.12 2007/03/12 13:28:50 freddy77 Exp $ */
++/* $Id: des.h,v 1.13 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -23,7 +23,7 @@ int tds_des_set_key(DES_KEY * dkey, des_cblock user_key, int len);
+ void tds_des_encrypt(DES_KEY * key, des_cblock block);
+ void _mcrypt_decrypt(DES_KEY * key, unsigned char *block);
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/hmac_md5.h b/include/hmac_md5.h
+index 3999b44..7a66c42 100644
+--- a/include/hmac_md5.h
++++ b/include/hmac_md5.h
+@@ -20,15 +20,15 @@
+ #ifndef _hmac_md5_h_
+ #define _hmac_md5_h_
+ 
+-/* $Id: hmac_md5.h,v 1.2 2008/12/09 09:39:14 freddy77 Exp $ */
++/* $Id: hmac_md5.h,v 1.3 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ void hmac_md5(const unsigned char key[16],
+               const unsigned char* data, size_t data_len,
+               unsigned char* digest);
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/md4.h b/include/md4.h
+index 7cc636b..8d64bc3 100644
+--- a/include/md4.h
++++ b/include/md4.h
+@@ -1,9 +1,9 @@
+ #ifndef MD4_H
+ #define MD4_H
+ 
+-/* $Id: md4.h,v 1.8 2009/01/16 20:27:56 jklowden Exp $ */
++/* $Id: md4.h,v 1.9 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -21,7 +21,7 @@ void MD4Transform(TDS_UINT buf[4], TDS_UINT const in[16]);
+ 
+ typedef struct MD4Context MD4_CTX;
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/md5.h b/include/md5.h
+index 86efc0d..26cbe20 100644
+--- a/include/md5.h
++++ b/include/md5.h
+@@ -1,9 +1,9 @@
+ #ifndef MD5_H
+ #define MD5_H
+ 
+-/* $Id: md5.h,v 1.5 2009/01/16 20:27:56 jklowden Exp $ */
++/* $Id: md5.h,v 1.6 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -23,7 +23,7 @@ void MD5Transform(TDS_UINT buf[4], TDS_UINT const in[16]);
+  */
+ typedef struct MD5Context MD5_CTX;
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/replacements.h b/include/replacements.h
+index bde9cff..9ae9f9f 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.25 2010/01/11 18:04:04 jklowden Exp $ */
++/* $Id: replacements.h,v 1.26 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -39,7 +39,7 @@
+ # include <libgen.h>
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -126,7 +126,7 @@ extern int optind, offset, opterr;
+ }
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/replacements/readpassphrase.h b/include/replacements/readpassphrase.h
+index a1c0a0d..0b23465 100644
+--- a/include/replacements/readpassphrase.h
++++ b/include/replacements/readpassphrase.h
+@@ -32,7 +32,7 @@
+ #ifndef _READPASSPHRASE_H_
+ #define _READPASSPHRASE_H_
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -50,7 +50,7 @@ char * readpassphrase(const char *, char *, size_t, int);
+ 
+ #endif /* HAVE_READPASSPHRASE */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/tds.h b/include/tds.h
+index 634d348..1571531 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.326 2010/01/22 10:43:48 freddy77 Exp $ */
++/* $Id: tds.h,v 1.327 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -41,7 +41,7 @@ typedef struct tds_socket TDSSOCKET;
+ #include "tds_sysdep_private.h"
+ #endif /* _FREETDS_LIBRARY_SOURCE */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -1568,11 +1568,11 @@ unsigned int tds_gettime_ms(void);
+ void tdsdump_off(void);
+ void tdsdump_on(void);
+ int tdsdump_isopen(void);
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ int tdsdump_open(const char *filename);
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ void tdsdump_close(void);
+@@ -1680,7 +1680,7 @@ int tds_writetext_end(TDSSOCKET *tds);
+ }
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/tdsconvert.h b/include/tdsconvert.h
+index 9699247..90d12d7 100644
+--- a/include/tdsconvert.h
++++ b/include/tdsconvert.h
+@@ -20,7 +20,7 @@
+ #ifndef _tdsconvert_h_
+ #define _tdsconvert_h_
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -32,7 +32,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsconvert.h,v 1.25 2009/05/21 16:39:38 freddy77 Exp $ */
++/* $Id: tdsconvert.h,v 1.26 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+ typedef union conv_result
+ {
+@@ -101,7 +101,7 @@ size_t tds_strftime(char *buf, size_t maxsize, const char *format, const TDSDATE
+ }
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/tdsiconv.h b/include/tdsiconv.h
+index 3bd08fe..3ca83f6 100644
+--- a/include/tdsiconv.h
++++ b/include/tdsiconv.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_iconv_h_
+ #define _tds_iconv_h_
+ 
+-/* $Id: tdsiconv.h,v 1.37 2008/10/17 08:39:16 freddy77 Exp $ */
++/* $Id: tdsiconv.h,v 1.38 2010/01/25 23:05:58 freddy77 Exp $ */
+ 
+ #if HAVE_ICONV
+ #include <iconv.h>
+@@ -50,7 +50,7 @@ typedef void *iconv_t;
+ #include <stdlib.h>
+ #endif /* HAVE_STDLIB_H */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -172,7 +172,7 @@ TDSICONV *tds_iconv_get(TDSSOCKET * tds, const char *client_charset, const char
+ }
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 93416ed..f72cfe9 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,9 +66,9 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.117 2010/01/10 14:43:11 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.118 2010/01/25 23:05:59 freddy77 Exp $ */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #define ODBC_API SQL_API __attribute__((externally_visible))
+ #else
+@@ -558,7 +558,7 @@ size_t sqlwcslen(const SQLWCHAR * s);
+ #error SIZEOF_SQLWCHAR not supported !!
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/include/tdsstring.h b/include/tdsstring.h
+index 6e1aadc..ac85bac 100644
+--- a/include/tdsstring.h
++++ b/include/tdsstring.h
+@@ -20,9 +20,9 @@
+ #ifndef _tdsstring_h_
+ #define _tdsstring_h_
+ 
+-/* $Id: tdsstring.h,v 1.20 2009/01/16 20:27:57 jklowden Exp $ */
++/* $Id: tdsstring.h,v 1.21 2010/01/25 23:05:59 freddy77 Exp $ */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -71,7 +71,7 @@ DSTR* tds_dstr_alloc(DSTR *s, size_t length);
+ 
+ /** @} */
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ 
+diff --git a/src/tds/tds_checks.h b/src/tds/tds_checks.h
+index bbb474c..64738ee 100644
+--- a/src/tds/tds_checks.h
++++ b/src/tds/tds_checks.h
+@@ -20,8 +20,8 @@
+ #ifndef TDS_CHECKS_H
+ #define TDS_CHECKS_H
+ 
+-/* $Id: tds_checks.h,v 1.5 2009/11/26 09:07:28 freddy77 Exp $ */
+-#if defined(__GNUC__) && __GNUC__ >= 4
++/* $Id: tds_checks.h,v 1.6 2010/01/25 23:05:59 freddy77 Exp $ */
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+ 
+@@ -50,7 +50,7 @@ void tds_check_cursor_extra(const TDSCURSOR * cursor);
+ void tds_check_dynamic_extra(const TDSDYNAMIC * dynamic);
+ #endif
+ 
+-#if defined(__GNUC__) && __GNUC__ >= 4
++#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility pop
+ #endif
+ #endif /* TDS_CHECKS_H */
+
+commit d6f77ebeeb50d5643b3c7f0139f3bcf7a9ebcb92
+Author: freddy77 <freddy77>
+Date:   Mon Jan 25 23:06:59 2010 +0000
+
+    fix windows build out of directory
+
+diff --git a/ChangeLog b/ChangeLog
+index 8ad300a..ae1d77e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jan 26 00:06:54 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/Makefile.am: fix windows build out of directory
++
+ Tue Jan 26 00:05:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/ctlib.h include/dblib.h include/des.h include/hmac_md5.h:
+ 	* include/md4.h include/md5.h include/replacements.h:
+@@ -2178,4 +2181,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2952 2010/01/25 23:05:58 freddy77 Exp $
++$Id: ChangeLog,v 1.2953 2010/01/25 23:06:59 freddy77 Exp $
+diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am
+index 56cecf5..3b84e59 100644
+--- a/src/odbc/Makefile.am
++++ b/src/odbc/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.46 2008/07/07 11:27:12 freddy77 Exp $
++# $Id: Makefile.am,v 1.47 2010/01/25 23:06:59 freddy77 Exp $
+ SUBDIRS		= unittests
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC)
+ 
+@@ -15,10 +15,10 @@ libtdsodbc_la_SOURCES=	odbc.c connectparams.c convert_tds2sql.c \
+ if MINGW32
+ libtdsodbc_la_LIBADD=	../../win32/setup.res ../tds/libtds.la ../replacements/libreplacements.la $(ODBCINSTLIB) \
+ 	$(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+-libtdsodbc_la_LDFLAGS = -Wl,--enable-stdcall-fixup -Wl,-s -Wl,../../win32/FreeTDS.def -Wl,../../win32/setup.res $(FREETDS_SYMBOLIC)
++libtdsodbc_la_LDFLAGS = -Wl,--enable-stdcall-fixup -Wl,-s -Wl,$(top_srcdir)/win32/FreeTDS.def -Wl,../../win32/setup.res $(FREETDS_SYMBOLIC)
+ 
+ .rc.res:
+-	$(RC) -i $< --input-format=rc -o $@ -O coff
++	$(RC) -i $< -I $(top_builddir)/win32 --input-format=rc -o $@ -O coff
+ else
+ libtdsodbc_la_LIBADD=	../tds/libtds.la ../replacements/libreplacements.la $(ODBCINSTLIB) $(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+ if MACOSX
+
+commit 0e174fbc0468c138a61ad1acb8952f7cdaef2a86
+Author: freddy77 <freddy77>
+Date:   Tue Jan 26 11:10:51 2010 +0000
+
+    allow driver registration like ole controls
+
+diff --git a/ChangeLog b/ChangeLog
+index ae1d77e..393ca21 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Jan 26 12:09:58 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/FreeTDS.def win32/winsetup.c:
++	- allow driver registration like ole controls
++
+ Tue Jan 26 00:06:54 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/Makefile.am: fix windows build out of directory
+ 
+@@ -2181,4 +2185,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2953 2010/01/25 23:06:59 freddy77 Exp $
++$Id: ChangeLog,v 1.2954 2010/01/26 11:10:51 freddy77 Exp $
+diff --git a/win32/FreeTDS.def b/win32/FreeTDS.def
+index 15994f6..11b898f 100644
+--- a/win32/FreeTDS.def
++++ b/win32/FreeTDS.def
+@@ -76,3 +76,5 @@ EXPORTS
+ 	ConfigDSN
+ 	ConfigDriver
+ 	ConfigTranslator
++	DllRegisterServer
++	DllUnregisterServer
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index ea233f1..8a0b26f 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -50,6 +50,7 @@
+ #include <assert.h>
+ #include <ctype.h>
+ #include <assert.h>
++#include <olectl.h>
+ 
+ #include "resource.h"
+ 
+@@ -57,6 +58,7 @@
+ #include "tdsodbc.h"
+ #include "tdsstring.h"
+ #include "tdsconvert.h"
++#include "replacements.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+@@ -415,3 +417,49 @@ ConfigTranslator(HWND hwndParent, DWORD * pvOption)
+ {
+ 	return TRUE;
+ }
++
++HRESULT WINAPI
++DllRegisterServer(void)
++{
++	TCHAR fn[MAX_PATH], full_fn[MAX_PATH];
++	LPTSTR name;
++	WORD len_out;
++	DWORD cnt;
++	char *desc = NULL;
++	BOOL b_res;
++
++	if (!GetModuleFileName(hinstFreeTDS, fn, TDS_VECTOR_SIZE(fn)))
++		return SELFREG_E_CLASS;
++	if (!GetFullPathName(fn, TDS_VECTOR_SIZE(full_fn), full_fn, &name) || !name || full_fn == name)
++		return SELFREG_E_CLASS;
++
++	if (asprintf(&desc, "FreeTDS%c"
++		"APILevel=2%c"
++		"ConnectFunctions=YYN%c"
++		"DriverODBCVer=03.00%c"
++		"FileUsage=0%c"
++		"SQLLevel=2%c"
++		"Setup=%s%c"
++		"Driver=%s%c",
++		0, 0, 0, 0, 0, 0,
++		name, 0, name, 0
++		) < 0)
++		return SELFREG_E_CLASS;
++	name[-1] = 0;
++
++	b_res = SQLInstallDriverEx(desc, full_fn, fn, TDS_VECTOR_SIZE(fn), &len_out, ODBC_INSTALL_COMPLETE, &cnt);
++	free(desc);
++	if (!b_res)
++		return SELFREG_E_CLASS;
++	return S_OK;
++}
++
++HRESULT WINAPI
++DllUnregisterServer(void)
++{
++	DWORD cnt;
++	if (!SQLRemoveDriver("FreeTDS", FALSE, &cnt))
++		return SELFREG_E_CLASS;
++	return S_OK;
++}
++
+
+commit 998db86a5c6ec50cea533042e40bcd92d7375560
+Author: freddy77 <freddy77>
+Date:   Tue Jan 26 11:21:10 2010 +0000
+
+    add experimental support for SSPI (not enabled by default)
+
+diff --git a/ChangeLog b/ChangeLog
+index 393ca21..a885aff 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jan 26 12:20:56 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tds.h src/tds/Makefile.am src/tds/login.c:
++	* src/tds/sspi.c:
++	- add experimental support for SSPI (not enabled by default)
++
+ Tue Jan 26 12:09:58 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/FreeTDS.def win32/winsetup.c:
+ 	- allow driver registration like ole controls
+@@ -2185,4 +2190,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2954 2010/01/26 11:10:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2955 2010/01/26 11:21:10 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 451232a..ab53e1f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.44 2010/01/22 12:42:16 freddy77 Exp $
++dnl $Id: configure.ac,v 1.45 2010/01/26 11:21:10 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.44 $)
++AC_REVISION($Revision: 1.45 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -232,6 +232,17 @@ int main()
+ 	LIBS="$PTHREAD_LIBS $LIBS"
+ fi
+ 
++# check for SSPI
++AC_ARG_ENABLE(sspi,
++  AS_HELP_STRING([--enable-sspi], [enable SSPI support (EXPERIMENTAL)]))
++# disable by default
++enable_sspi=${enable_sspi-no}
++# only if MingW (TODO other compilers)
++test $tds_mingw != yes && enable_sspi=no
++AM_CONDITIONAL(HAVE_SSPI, test "$enable_sspi" = "yes")
++if test "$enable_sspi" = "yes"; then
++	AC_DEFINE(HAVE_SSPI, 1, [Defined if --enable-sspi and SSPI detected])
++fi
+ 
+ # ------------------------------------------------------------
+ # Checks for header files.
+diff --git a/include/tds.h b/include/tds.h
+index 1571531..b5caccb 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.327 2010/01/25 23:05:58 freddy77 Exp $ */
++/* $Id: tds.h,v 1.328 2010/01/26 11:21:10 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1613,8 +1613,12 @@ TDS_INT tds_numeric_change_prec_scale(TDS_NUMERIC * numeric, unsigned char new_p
+ /* getmac.c */
+ void tds_getmac(TDS_SYS_SOCKET s, unsigned char mac[6]);
+ 
++#ifndef HAVE_SSPI
+ TDSAUTHENTICATION * tds_ntlm_get_auth(TDSSOCKET * tds);
+ TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds);
++#else
++TDSAUTHENTICATION * tds_sspi_get_auth(TDSSOCKET * tds);
++#endif
+ 
+ /* bulk.c */
+ typedef struct tds_bcpinfo
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index 60a194c..df8f185 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,20 +1,29 @@
+-# $Id: Makefile.am,v 1.70 2010/01/22 09:37:58 freddy77 Exp $
++# $Id: Makefile.am,v 1.71 2010/01/26 11:21:10 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+ 
+ noinst_LTLIBRARIES	=	libtds.la
++if HAVE_SSPI
++AUTH_FILES_DIST	= challenge.c md4.c md5.c des.c gssapi.c hmac_md5.c
++AUTH_FILES	= sspi.c
++else
++AUTH_FILES	= challenge.c md4.c md5.c des.c gssapi.c hmac_md5.c
++AUTH_FILES_DIST	= sspi.c
++endif
+ libtds_la_SOURCES=	mem.c token.c util.c login.c read.c \
+ 	write.c convert.c numeric.c config.c query.c iconv.c \
+-	locale.c challenge.c threadsafe.c vstrbuild.c md4.c md5.c \
+-	des.c tdsstring.c getmac.c data.c net.c \
++	locale.c threadsafe.c vstrbuild.c \
++	tdsstring.c getmac.c data.c net.c \
+ 	tds_checks.c tds_checks.h enum_cap.h log.c \
+-	gssapi.c hmac_md5.c bulk.c
++	bulk.c \
++	$(AUTH_FILES)
+ libtds_la_LDFLAGS=
+ libtds_la_LIBADD=
+ 
+ noinst_HEADERS		= tds_willconvert.h encodings.h num_limits.h types.h
+-EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h types.h TDS.vcproj
++EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h types.h \
++	TDS.vcproj $(AUTH_FILES_DIST)
+ 
+ if HAVE_DOXYGEN
+ doxyfile: $(srcdir)/tds.dox
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 6c33546..ccca13c 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005, 2006, 2007, 2008  Ziglio Frediano
++ * Copyright (C) 2005-2010  Ziglio Frediano
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.193 2010/01/11 18:14:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.194 2010/01/26 11:21:10 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -743,6 +743,14 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	packet_size = current_pos + (host_name_len + app_name_len + server_name_len + library_len + language_len + database_len) * 2;
+ 
+ 	/* check ntlm */
++#ifdef HAVE_SSPI
++	if (strchr(user_name, '\\') != NULL || user_name_len == 0) {
++		tds->authentication = tds_sspi_get_auth(tds);
++		if (!tds->authentication)
++			return TDS_FAIL;
++		auth_len = tds->authentication->packet_len;
++		packet_size += auth_len;
++#else
+ 	if (strchr(user_name, '\\') != NULL) {
+ 		tds->authentication = tds_ntlm_get_auth(tds);
+ 		if (!tds->authentication)
+@@ -750,15 +758,16 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		auth_len = tds->authentication->packet_len;
+ 		packet_size += auth_len;
+ 	} else if (user_name_len == 0) {
+-#ifdef ENABLE_KRB5
++# ifdef ENABLE_KRB5
+ 		/* try kerberos */
+ 		tds->authentication = tds_gss_get_auth(tds);
+ 		if (!tds->authentication)
+ 			return TDS_FAIL;
+ 		auth_len = tds->authentication->packet_len;
+ 		packet_size += auth_len;
+-#else
++# else
+ 		return TDS_FAIL;
++# endif
+ #endif
+ 	} else
+ 		packet_size += (user_name_len + password_len) * 2;
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+new file mode 100644
+index 0000000..86c3735
+--- /dev/null
++++ b/src/tds/sspi.c
+@@ -0,0 +1,240 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#if HAVE_STDLIB_H
++#include <stdlib.h>
++#endif /* HAVE_STDLIB_H */
++
++#if HAVE_STRING_H
++#include <string.h>
++#endif /* HAVE_STRING_H */
++
++#if HAVE_SSPI
++
++#include <windows.h>
++#include <security.h>
++#include <sspi.h>
++#include <rpc.h>
++
++#include "tds.h"
++#include "tdsstring.h"
++#include "replacements.h"
++
++#ifdef DMALLOC
++#include <dmalloc.h>
++#endif
++
++TDS_RCSID(var, "$Id: sspi.c,v 1.1 2010/01/26 11:21:10 freddy77 Exp $");
++
++/**
++ * \ingroup libtds
++ * \defgroup auth Authentication
++ * Functions for handling authentication.
++ */
++
++/**
++ * \addtogroup auth
++ * @{
++ */
++
++typedef struct tds_sspi_auth
++{
++	TDSAUTHENTICATION tds_auth;
++	CredHandle cred;
++	CtxtHandle cred_ctx;
++} TDSSSPIAUTH;
++
++static HMODULE secdll = NULL;
++static PSecurityFunctionTableA sec_fn = NULL;
++
++static int
++tds_init_secdll(void)
++{
++	/* FIXME therad safe !!! */
++	if (!secdll) {
++		OSVERSIONINFO osver;
++
++		memset(&osver, 0, sizeof(osver));
++		osver.dwOSVersionInfoSize = sizeof(osver);
++		if (!GetVersionEx(&osver))
++			return 0;
++		if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT && osver.dwMajorVersion <= 4)
++			secdll = LoadLibrary("security.dll");
++		else
++			secdll = LoadLibrary("secur32.dll");
++		if (!secdll)
++			return 0;
++	}
++	if (!sec_fn) {
++		INIT_SECURITY_INTERFACE_A pInitSecurityInterface;
++
++		pInitSecurityInterface = (INIT_SECURITY_INTERFACE_A) GetProcAddress(secdll, "InitSecurityInterfaceA");
++		if (!pInitSecurityInterface)
++			return 0;
++
++		sec_fn = pInitSecurityInterface();
++		if (!sec_fn)
++			return 0;
++	}
++	return 1;
++}
++
++static int
++tds_sspi_free(TDSSOCKET * tds, struct tds_authentication * tds_auth)
++{
++	TDSSSPIAUTH *auth = (TDSSSPIAUTH *) tds_auth;
++
++	sec_fn->DeleteSecurityContext(&auth->cred_ctx);
++	sec_fn->FreeCredentialsHandle(&auth->cred);
++	free(auth->tds_auth.packet);
++	free(auth);
++	return TDS_SUCCEED;
++}
++
++enum { NTLMBUF_LEN = 4096 };
++
++static int
++tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size_t len)
++{
++	SecBuffer in_buf, out_buf;
++	SecBufferDesc in_desc, out_desc;
++	SECURITY_STATUS status;
++	ULONG attrs;
++	TimeStamp ts;
++	TDS_UCHAR *auth_buf;
++
++	TDSSSPIAUTH *auth = (TDSSSPIAUTH *) tds_auth;
++
++	if (len < 32 || len > NTLMBUF_LEN)
++		return TDS_FAIL;
++
++	auth_buf = (TDS_UCHAR *) malloc(len);
++	if (!auth_buf)
++		return TDS_FAIL;
++	tds_get_n(tds, auth_buf, len);
++
++	in_desc.ulVersion  = out_desc.ulVersion  = SECBUFFER_VERSION;
++	in_desc.cBuffers   = out_desc.cBuffers   = 1;
++	in_desc.pBuffers   = &in_buf;
++	out_desc.pBuffers   = &out_buf;
++
++	in_buf.BufferType = SECBUFFER_TOKEN;
++	in_buf.pvBuffer   = auth_buf;
++	in_buf.cbBuffer   = len;
++
++	out_buf.BufferType = SECBUFFER_TOKEN;
++	out_buf.pvBuffer   = auth->tds_auth.packet;
++	out_buf.cbBuffer   = NTLMBUF_LEN;
++
++	status = sec_fn->InitializeSecurityContextA(&auth->cred, &auth->cred_ctx,
++		// (char *) host,
++		NULL,
++		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
++		0, SECURITY_NETWORK_DREP, &in_desc,
++		0, &auth->cred_ctx, &out_desc,
++		&attrs, &ts);
++
++	free(auth_buf);
++
++	if (status != SEC_E_OK)
++		return TDS_FAIL;
++
++	tds_put_n(tds, auth->tds_auth.packet, out_buf.cbBuffer);
++
++	return tds_flush_packet(tds);
++}
++
++/**
++ * Build a SSPI packet to send to server
++ * @param tds     A pointer to the TDSSOCKET structure managing a client/server operation.
++ */
++TDSAUTHENTICATION *
++tds_sspi_get_auth(TDSSOCKET * tds)
++{
++	SecBuffer buf;
++	SecBufferDesc desc;
++	SECURITY_STATUS status;
++	ULONG attrs;
++	TimeStamp ts;
++
++	TDSSSPIAUTH *auth;
++
++	if (!tds_init_secdll())
++		return NULL;
++
++	auth = (TDSSSPIAUTH *) calloc(1, sizeof(TDSSSPIAUTH));
++	if (!auth || !tds->connection)
++		return NULL;
++
++	auth->tds_auth.free = tds_sspi_free;
++	auth->tds_auth.handle_next = tds_sspi_handle_next;
++
++	/* TODO parse user/pass and use them if available */
++	/* TODO use SPNEGO to use Kerberos if possible */
++	if (sec_fn->AcquireCredentialsHandleA(NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND,
++		NULL, NULL, // ntlm->p_identity,
++		NULL, NULL, &auth->cred, &ts) != SEC_E_OK) {
++		free(auth);
++		return NULL;
++	}
++
++	auth->tds_auth.packet = (TDS_UCHAR *) malloc(NTLMBUF_LEN);
++	if (!auth->tds_auth.packet) {
++		sec_fn->FreeCredentialsHandle(&auth->cred);
++		free(auth);
++		return NULL;
++	}
++	desc.ulVersion = SECBUFFER_VERSION;
++	desc.cBuffers  = 1;
++	desc.pBuffers  = &buf;
++
++	buf.cbBuffer   = NTLMBUF_LEN;
++	buf.BufferType = SECBUFFER_TOKEN;
++	buf.pvBuffer   = auth->tds_auth.packet;
++
++	status = sec_fn->InitializeSecurityContextA(&auth->cred, NULL,
++		//(char *) host,
++		"",
++		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
++		0, SECURITY_NETWORK_DREP,
++		NULL, 0,
++		&auth->cred_ctx, &desc,
++		&attrs, &ts);
++
++	if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) {
++		sec_fn->CompleteAuthToken(&auth->cred_ctx, &desc);
++	} else if(status != SEC_E_OK) {
++		free(auth->tds_auth.packet);
++		sec_fn->FreeCredentialsHandle(&auth->cred);
++		free(auth);
++		return NULL;
++	}
++
++	auth->tds_auth.packet_len = buf.cbBuffer;
++	return &auth->tds_auth;
++}
++
++#endif
++
++/** @} */
++
+
+commit a246543987cbaf05b2040637bee6eb8b570838b3
+Author: freddy77 <freddy77>
+Date:   Tue Jan 26 13:43:09 2010 +0000
+
+    avoid silly buffer overflow
+
+diff --git a/ChangeLog b/ChangeLog
+index a885aff..58245a2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jan 26 14:41:18 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/winsetup.c: avoid silly buffer overflow
++
+ Tue Jan 26 12:20:56 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac include/tds.h src/tds/Makefile.am src/tds/login.c:
+ 	* src/tds/sspi.c:
+@@ -2190,4 +2193,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2955 2010/01/26 11:21:10 freddy77 Exp $
++$Id: ChangeLog,v 1.2956 2010/01/26 13:43:09 freddy77 Exp $
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index 8a0b26f..c37384f 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -396,19 +396,22 @@ ConfigDSN(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszAttribut
+ BOOL INSTAPI
+ ConfigDriver(HWND hwndParent, WORD fRequest, LPCSTR lpszDriver, LPCSTR lpszArgs, LPSTR lpszMsg, WORD cbMsgMax, WORD * pcbMsgOut)
+ {
++	const char *msg = NULL;
++
+ 	/* TODO finish ?? */
+ 	switch (fRequest) {
+ 	case ODBC_INSTALL_DRIVER:
+-		/* FIXME possible buffer overflow */
+-		strcpy(lpszMsg, "Hello");
+-		*pcbMsgOut = strlen(lpszMsg);
++		msg = "Hello";
+ 		break;
+ 	case ODBC_REMOVE_DRIVER:
+-		/* FIXME possible buffer overflow */
+-		strcpy(lpszMsg, "Goodbye");
+-		*pcbMsgOut = strlen(lpszMsg);
++		msg = "Goodbye";
+ 		break;
+ 	}
++
++	if (msg && lpszMsg && cbMsgMax > strlen(msg)) {
++		strcpy(lpszMsg, msg);
++		*pcbMsgOut = strlen(msg);
++	}
+ 	return TRUE;
+ }
+ 
+
+commit 516e6d2aed0af05dec524ae731b6e03fb23b1b24
+Author: jklowden <jklowden>
+Date:   Tue Jan 26 16:28:04 2010 +0000
+
+    Generate header files for Win32 CVS commit
+
+diff --git a/ChangeLog b/ChangeLog
+index 58245a2..82bb698 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jan 26 11:25:49 EST 2010	JK Lowden <jklowden@freetds.org>
++	* Nmakefile generate header files for CVS checkout
++
+ Tue Jan 26 14:41:18 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/winsetup.c: avoid silly buffer overflow
+ 
+@@ -2193,4 +2196,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2956 2010/01/26 13:43:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2957 2010/01/26 16:28:04 jklowden Exp $
+diff --git a/Nmakefile b/Nmakefile
+index d17881b..78369b3 100755
+--- a/Nmakefile
++++ b/Nmakefile
+@@ -1,4 +1,4 @@
+-# $Id: Nmakefile,v 1.2 2010/01/08 22:08:01 jklowden Exp $
++# $Id: Nmakefile,v 1.3 2010/01/26 16:28:05 jklowden Exp $
+ # Build FreeTDS and assorted utilities for Win32/Win64 without an IDE. 
+ # Makefiles, unlike Visual Studio project files, are stable over time.  
+ # Contributed to the public domain by James K. Lowden, February 2009
+@@ -13,6 +13,7 @@
+ #	
+ 
+ MKDIR = MD
++MV = move /Y
+ 
+ DBLIB_DIR        = src\dblib
+ REPLACEMENTS_DIR = src\replacements
+@@ -196,7 +197,34 @@ $(DBLIB_OUT) $(REPLACEMENTS_OUT) $(TDS_OUT) $(APPS_OUT):
+ 	@if "" equ "$(CONFIGURATION)" 	CONFIGURATION not defined, see comments in Nmakefile >&2 && exit 1
+ 	$(MKDIR) $@
+ 
+-$(DBLIB_OUT)\db-lib.lib: $(DBLIB_OUT) $(DBLIB_OBJ) $(REPLACEMENTS_OUT)\replacements.lib $(TDS_OUT)\tds.lib
++#
++# Generate distributed header files
++#
++include\tdsver.h:
++	perl -e"@a=localtime; printf qq(#undef  TDS_VERSION_NO\n#define TDS_VERSION_NO \"freetds v0.83.dev.%d%02d%02d\"\n), 1900+$$a[5], 1+$$a[-1], $$a[3]" \
++	> $@.err 
++	move /Y $@.err $@
++
++include\types.h:
++	perl src\tds\types.pl misc\types.txt > $@.err
++	move /Y $@.err $@
++
++src\tds\tds_willconvert.h: src\tds\tds_willconvert.pl
++	perl src\tds\tds_willconvert.pl > $@.tmp
++	$(MV) $@.tmp $@
++
++src\tds\encodings.h: src\tds\encodings.pl src\tds\alternative_character_sets.h
++	perl src\tds\encodings.pl src\tds > $@.tmp 2> NUL:
++	$(MV) $@.tmp $@
++
++src\tds\num_limits.h: src\tds\num_limits.pl
++	perl src\tds\num_limits.pl > $@.tmp
++	$(MV) $@.tmp $@
++
++GENERATED_FILES = include\tdsver.h include\types.h \
++	src\tds\tds_willconvert.h src\tds\encodings.h src\tds\num_limits.h
++
++$(DBLIB_OUT)\db-lib.lib: $(GENERATED_FILES) $(DBLIB_OUT) $(DBLIB_OBJ) $(REPLACEMENTS_OUT)\replacements.lib $(TDS_OUT)\tds.lib
+ 	@echo building $@ >&2
+ 	lib -nologo -out:"$@" 	$(DBLIB_OBJ) \
+ 				$(REPLACEMENTS_OUT)\replacements.lib \
+
+commit 5d8f88f3fb6fecc1002f30dbc92d011a06d0456a
+Author: jklowden <jklowden>
+Date:   Tue Jan 26 18:15:39 2010 +0000
+
+    build with sspi on Win32, not really working yet
+
+diff --git a/ChangeLog b/ChangeLog
+index 82bb698..ba4612f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Jan 26 13:11:37 EST 2010	JK Lowden <jklowden@freetds.org>
++	* Nmakefile src/tds/sspi.c win32/config.h
++	- build with sspi on Win32, not really working yet
++
+ Tue Jan 26 11:25:49 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* Nmakefile generate header files for CVS checkout
+ 
+@@ -2196,4 +2200,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2957 2010/01/26 16:28:04 jklowden Exp $
++$Id: ChangeLog,v 1.2958 2010/01/26 18:15:39 jklowden Exp $
+diff --git a/Nmakefile b/Nmakefile
+index 78369b3..bc360ed 100755
+--- a/Nmakefile
++++ b/Nmakefile
+@@ -1,4 +1,4 @@
+-# $Id: Nmakefile,v 1.3 2010/01/26 16:28:05 jklowden Exp $
++# $Id: Nmakefile,v 1.4 2010/01/26 18:15:39 jklowden Exp $
+ # Build FreeTDS and assorted utilities for Win32/Win64 without an IDE. 
+ # Makefiles, unlike Visual Studio project files, are stable over time.  
+ # Contributed to the public domain by James K. Lowden, February 2009
+@@ -83,6 +83,7 @@ TDS_SRC =	$(TDS_DIR)\bulk.c \
+ 		$(TDS_DIR)\numeric.c \
+ 		$(TDS_DIR)\query.c \
+ 		$(TDS_DIR)\read.c \
++		$(TDS_DIR)\sspi.c \
+ 		$(TDS_DIR)\tds_checks.c \
+ 		$(TDS_DIR)\tdsstring.c \
+ 		$(TDS_DIR)\threadsafe.c \
+@@ -111,6 +112,7 @@ TDS_OBJ =	$(TDS_OUT)\bulk.obj \
+ 		$(TDS_OUT)\numeric.obj \
+ 		$(TDS_OUT)\query.obj \
+ 		$(TDS_OUT)\read.obj \
++		$(TDS_OUT)\sspi.obj \
+ 		$(TDS_OUT)\tds_checks.obj \
+ 		$(TDS_OUT)\tdsstring.obj \
+ 		$(TDS_OUT)\threadsafe.obj \
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index 86c3735..10616fc 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -30,6 +30,7 @@
+ #endif /* HAVE_STRING_H */
+ 
+ #if HAVE_SSPI
++#define SECURITY_WIN32
+ 
+ #include <windows.h>
+ #include <security.h>
+@@ -44,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.1 2010/01/26 11:21:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.2 2010/01/26 18:15:39 jklowden Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -131,7 +132,7 @@ tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size
+ 	auth_buf = (TDS_UCHAR *) malloc(len);
+ 	if (!auth_buf)
+ 		return TDS_FAIL;
+-	tds_get_n(tds, auth_buf, len);
++	tds_get_n(tds, auth_buf, (int)len);
+ 
+ 	in_desc.ulVersion  = out_desc.ulVersion  = SECBUFFER_VERSION;
+ 	in_desc.cBuffers   = out_desc.cBuffers   = 1;
+@@ -140,15 +141,13 @@ tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size
+ 
+ 	in_buf.BufferType = SECBUFFER_TOKEN;
+ 	in_buf.pvBuffer   = auth_buf;
+-	in_buf.cbBuffer   = len;
++	in_buf.cbBuffer   = (ULONG)len;
+ 
+ 	out_buf.BufferType = SECBUFFER_TOKEN;
+ 	out_buf.pvBuffer   = auth->tds_auth.packet;
+ 	out_buf.cbBuffer   = NTLMBUF_LEN;
+ 
+-	status = sec_fn->InitializeSecurityContextA(&auth->cred, &auth->cred_ctx,
+-		// (char *) host,
+-		NULL,
++	status = sec_fn->InitializeSecurityContextA(&auth->cred, &auth->cred_ctx, NULL,  
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP, &in_desc,
+ 		0, &auth->cred_ctx, &out_desc,
+@@ -212,9 +211,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	buf.BufferType = SECBUFFER_TOKEN;
+ 	buf.pvBuffer   = auth->tds_auth.packet;
+ 
+-	status = sec_fn->InitializeSecurityContextA(&auth->cred, NULL,
+-		//(char *) host,
+-		"",
++	status = sec_fn->InitializeSecurityContext(&auth->cred, NULL, "",
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP,
+ 		NULL, 0,
+@@ -234,7 +231,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	return &auth->tds_auth;
+ }
+ 
+-#endif
++#endif /* HAVE_SSPI */
+ 
+ /** @} */
+ 
+diff --git a/win32/config.h b/win32/config.h
+index 46dfe26..0a0005c 100644
+--- a/win32/config.h
++++ b/win32/config.h
+@@ -205,6 +205,9 @@
+ /* The size of a `__int64', as computed by sizeof. */
+ #define SIZEOF___INT64 8
+ 
++/* Define to 1 if you want to use SSPI for Win32 */
++#define HAVE_SSPI 1
++
+ /* Define to 1 if you have the ANSI C header files. */
+ #define STDC_HEADERS 1
+ 
+
+commit 0cd5dd7706420859de74adb32dfad578e98ed431
+Author: freddy77 <freddy77>
+Date:   Tue Jan 26 20:26:11 2010 +0000
+
+    small comments
+
+diff --git a/ChangeLog b/ChangeLog
+index ba4612f..5d226f9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jan 26 21:25:59 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/winsetup.c: small comments
++
+ Tue Jan 26 13:11:37 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* Nmakefile src/tds/sspi.c win32/config.h
+ 	- build with sspi on Win32, not really working yet
+@@ -2200,4 +2203,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2958 2010/01/26 18:15:39 jklowden Exp $
++$Id: ChangeLog,v 1.2959 2010/01/26 20:26:11 freddy77 Exp $
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index c37384f..a0809e4 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -421,6 +421,9 @@ ConfigTranslator(HWND hwndParent, DWORD * pvOption)
+ 	return TRUE;
+ }
+ 
++/**
++ * Allow install using regsvr32
++ */
+ HRESULT WINAPI
+ DllRegisterServer(void)
+ {
+@@ -457,6 +460,9 @@ DllRegisterServer(void)
+ 	return S_OK;
+ }
+ 
++/**
++ * Allow uninstall using regsvr32 command
++ */
+ HRESULT WINAPI
+ DllUnregisterServer(void)
+ {
+
+commit eb24fbc4d06fca4f525f28f41f21081969a5427d
+Author: jklowden <jklowden>
+Date:   Wed Jan 27 03:21:07 2010 +0000
+
+    link libiconv cf ML 26 Jan 2010
+
+diff --git a/ChangeLog b/ChangeLog
+index 5d226f9..708072d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jan 26 22:18:16 EST 2010	JK Lowden <jklowden@freetds.org>
++	* src/apps/Makefile.am src/dblib/dblib.c
++	* src/pool/Makefile.am src/server/Makefile.am
++	- link libiconv cf ML 26 Jan 2010
++
+ Tue Jan 26 21:25:59 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/winsetup.c: small comments
+ 
+@@ -2203,4 +2208,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2959 2010/01/26 20:26:11 freddy77 Exp $
++$Id: ChangeLog,v 1.2960 2010/01/27 03:21:07 jklowden Exp $
+diff --git a/src/apps/Makefile.am b/src/apps/Makefile.am
+index 4545913..2ee6431 100644
+--- a/src/apps/Makefile.am
++++ b/src/apps/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.29 2009/01/09 04:59:58 jklowden Exp $
++# $Id: Makefile.am,v 1.30 2010/01/27 03:21:08 jklowden Exp $
+ 
+ AM_CPPFLAGS	= -I$(top_srcdir)/include 
+ 
+@@ -16,7 +16,7 @@ endif
+ 
+ dist_bin_SCRIPTS = osql
+ 
+-freebcp_LDADD	= ../dblib/libsybdb.la ../replacements/libreplacements.la $(NETWORK_LIBS)
++freebcp_LDADD	= ../dblib/libsybdb.la ../replacements/libreplacements.la $(LIBICONV) $(NETWORK_LIBS)
+ freebcp_SOURCES = freebcp.c freebcp.h
+ 
+ tsql_LDADD	= ../tds/libtds.la \
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index e1a9d04..7f527e9 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.359 2010/01/10 14:43:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.360 2010/01/27 03:21:08 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -7805,7 +7805,7 @@ static const DBLIB_ERROR_MESSAGE dblib_error_messages[] =
+ int
+ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ {
+-	static const char int_exit_text[] = "FreeTDS: db-lib: exiting because client error handler returned %d for msgno %d\n";
++	static const char int_exit_text[] = "FreeTDS: db-lib: exiting because client error handler returned %s for msgno %d\n";
+ 	static const char int_invalid_text[] = "%s (%d) received from client-installed error handler for nontimeout for error %d."
+ 					       "  Treating as INT_EXIT\n";
+ 	static const DBLIB_ERROR_MESSAGE default_message = { 0, EXCONSISTENCY, "unrecognized msgno" };
+@@ -7814,6 +7814,7 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 	
+ 	int i, rc = INT_CANCEL;
+ 	char *os_msgtext = strerror(errnum), *rc_name;
++	char db_msgtext[32] = "INT_CANCEL"; 
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbperror(%p, %d, %ld)\n", dbproc, msgno, errnum);	/* dbproc can be NULL */
+ 
+@@ -7927,6 +7928,7 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 		return rc;	/* normal case */
+ 		break;
+ 	default:
++		sprintf(db_msgtext, "%d", rc);
+ 		tdsdump_log(TDS_DBG_SEVERE, int_invalid_text, "Invalid return code", rc, msgno);
+ 		/* fall through */
+ 	case INT_EXIT:
+@@ -7934,7 +7936,7 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 			/* Microsoft behavior */
+ 			return INT_CANCEL;
+ 		}
+-		fprintf(stderr, int_exit_text, rc, msgno);
++		fprintf(stderr, int_exit_text, db_msgtext, msgno);
+ 		tdsdump_log(TDS_DBG_SEVERE, int_exit_text, rc, msgno);
+ 		break;
+ 	}
+diff --git a/src/pool/Makefile.am b/src/pool/Makefile.am
+index 09be616..eee0a2d 100644
+--- a/src/pool/Makefile.am
++++ b/src/pool/Makefile.am
+@@ -1,10 +1,10 @@
+-# $Id: Makefile.am,v 1.14 2006/03/27 07:22:54 jklowden Exp $
++# $Id: Makefile.am,v 1.15 2010/01/27 03:21:08 jklowden Exp $
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include -I. -I$(SERVERDIR)
+ bin_PROGRAMS	=	tdspool
+ 
+ tdspool_SOURCES	=	config.c main.c member.c user.c util.c pool.h
+ SERVERDIR	=	../server
+-LDADD		=	../server/libtdssrv.la $(NETWORK_LIBS)
++LDADD		=	../server/libtdssrv.la $(LIBICONV) $(NETWORK_LIBS)
+ EXTRA_DIST	=	BUGS pool.conf
+ 
+ ETC	=	$(DESTDIR)$(sysconfdir)
+diff --git a/src/server/Makefile.am b/src/server/Makefile.am
+index 3eb8bbd..c2eb3f4 100644
+--- a/src/server/Makefile.am
++++ b/src/server/Makefile.am
+@@ -1,8 +1,8 @@
+-# $Id: Makefile.am,v 1.16 2007/03/12 13:28:51 freddy77 Exp $
++# $Id: Makefile.am,v 1.17 2010/01/27 03:21:08 jklowden Exp $
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include
+ noinst_LTLIBRARIES	=	libtdssrv.la
+ libtdssrv_la_SOURCES=	query.c server.c login.c
+ libtdssrv_la_LIBADD =	../tds/libtds.la ../replacements/libreplacements.la $(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+ noinst_PROGRAMS	= tdssrv
+-tdssrv_LDADD	= libtdssrv.la $(NETWORK_LIBS)
++tdssrv_LDADD	= libtdssrv.la $(LIBICONV) $(NETWORK_LIBS)
+ tdssrv_SOURCES	= unittest.c
+
+commit b5ae54f356359d427d24ce13043d26efa0f7147b
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 08:08:32 2010 +0000
+
+    remove useless "A" suffix
+
+diff --git a/ChangeLog b/ChangeLog
+index 708072d..46e541d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jan 27 09:07:13 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/sspi.c: remove useless "A" suffix
++
+ Tue Jan 26 22:18:16 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/Makefile.am src/dblib/dblib.c
+ 	* src/pool/Makefile.am src/server/Makefile.am
+@@ -2208,4 +2211,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2960 2010/01/27 03:21:07 jklowden Exp $
++$Id: ChangeLog,v 1.2961 2010/01/27 08:08:32 freddy77 Exp $
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index 10616fc..109ac88 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.2 2010/01/26 18:15:39 jklowden Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.3 2010/01/27 08:08:32 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -147,7 +147,7 @@ tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size
+ 	out_buf.pvBuffer   = auth->tds_auth.packet;
+ 	out_buf.cbBuffer   = NTLMBUF_LEN;
+ 
+-	status = sec_fn->InitializeSecurityContextA(&auth->cred, &auth->cred_ctx, NULL,  
++	status = sec_fn->InitializeSecurityContext(&auth->cred, &auth->cred_ctx, NULL,
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP, &in_desc,
+ 		0, &auth->cred_ctx, &out_desc,
+@@ -190,7 +190,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 
+ 	/* TODO parse user/pass and use them if available */
+ 	/* TODO use SPNEGO to use Kerberos if possible */
+-	if (sec_fn->AcquireCredentialsHandleA(NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND,
++	if (sec_fn->AcquireCredentialsHandle(NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND,
+ 		NULL, NULL, // ntlm->p_identity,
+ 		NULL, NULL, &auth->cred, &ts) != SEC_E_OK) {
+ 		free(auth);
+
+commit 9e9d9e94f0e0c2ae19fbd8150aea44bf521bfad6
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 08:31:26 2010 +0000
+
+    add support for user/password using SSPI
+
+diff --git a/ChangeLog b/ChangeLog
+index 46e541d..0bfd60c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jan 27 09:29:57 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/tds/sspi.c:
++	- add support for user/password using SSPI
++
+ Wed Jan 27 09:07:13 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/sspi.c: remove useless "A" suffix
+ 
+@@ -2211,4 +2215,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2961 2010/01/27 08:08:32 freddy77 Exp $
++$Id: ChangeLog,v 1.2962 2010/01/27 08:31:26 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a9abcc1..efe7c8a 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.526 2010/01/23 20:25:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.527 2010/01/27 08:31:26 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -474,12 +474,6 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+ 
+-	if (tds_dstr_isempty(&connection->user_name)) {
+-		tds_free_connection(connection);
+-		odbc_errs_add(&dbc->errs, "IM007", "Could not find UID parameter");
+-		ODBC_RETURN(dbc, SQL_ERROR);
+-	}
+-
+ 	if (odbc_connect(dbc, connection) != SQL_SUCCESS) {
+ 		tds_free_connection(connection);
+ 		ODBC_RETURN_(dbc);
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index 109ac88..072fb56 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.3 2010/01/27 08:08:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.4 2010/01/27 08:31:26 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -147,7 +147,7 @@ tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size
+ 	out_buf.pvBuffer   = auth->tds_auth.packet;
+ 	out_buf.cbBuffer   = NTLMBUF_LEN;
+ 
+-	status = sec_fn->InitializeSecurityContext(&auth->cred, &auth->cred_ctx, NULL,
++	status = sec_fn->InitializeSecurityContext(&auth->cred, &auth->cred_ctx, NULL /* TODO SPN */,
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP, &in_desc,
+ 		0, &auth->cred_ctx, &out_desc,
+@@ -175,12 +175,33 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	SECURITY_STATUS status;
+ 	ULONG attrs;
+ 	TimeStamp ts;
++	SEC_WINNT_AUTH_IDENTITY identity;
++	const char *p, *user_name;
+ 
+ 	TDSSSPIAUTH *auth;
++	TDSCONNECTION *connection = tds->connection;
++
++	/* check connection */
++	if (!connection)
++		return TDS_FAIL;
+ 
+ 	if (!tds_init_secdll())
+ 		return NULL;
+ 
++	/* parse username/password informations */
++	memset(&identity, 0, sizeof(identity));
++	user_name = tds_dstr_cstr(&connection->user_name);
++	if ((p = strchr(user_name, '\\')) != NULL) {
++		identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
++		identity.Password = (unsigned short *) tds_dstr_cstr(&connection->password);
++		identity.PasswordLength = tds_dstr_len(&connection->password);
++		identity.Domain = (unsigned short *) user_name;
++		identity.DomainLength = p - user_name;
++		user_name = p + 1;
++		identity.User = (unsigned short *) user_name;
++		identity.UserLength = strlen(user_name);
++	}
++
+ 	auth = (TDSSSPIAUTH *) calloc(1, sizeof(TDSSSPIAUTH));
+ 	if (!auth || !tds->connection)
+ 		return NULL;
+@@ -188,10 +209,9 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	auth->tds_auth.free = tds_sspi_free;
+ 	auth->tds_auth.handle_next = tds_sspi_handle_next;
+ 
+-	/* TODO parse user/pass and use them if available */
+ 	/* TODO use SPNEGO to use Kerberos if possible */
+ 	if (sec_fn->AcquireCredentialsHandle(NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND,
+-		NULL, NULL, // ntlm->p_identity,
++		NULL, identity.Domain ? &identity : NULL,
+ 		NULL, NULL, &auth->cred, &ts) != SEC_E_OK) {
+ 		free(auth);
+ 		return NULL;
+@@ -211,7 +231,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	buf.BufferType = SECBUFFER_TOKEN;
+ 	buf.pvBuffer   = auth->tds_auth.packet;
+ 
+-	status = sec_fn->InitializeSecurityContext(&auth->cred, NULL, "",
++	status = sec_fn->InitializeSecurityContext(&auth->cred, NULL, "" /* TODO SPN */,
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP,
+ 		NULL, 0,
+
+commit 1ed8edc2f47a73865c6a7656ed22b1f5c62e5528
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 12:16:09 2010 +0000
+
+    set correctly server_host_name from odbc
+
+diff --git a/ChangeLog b/ChangeLog
+index 0bfd60c..cf78d98 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jan 27 13:14:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/connectparams.c src/tds/config.c:
++	- set correctly server_host_name from odbc
++
+ Wed Jan 27 09:29:57 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/tds/sspi.c:
+ 	- add support for user/password using SSPI
+@@ -2215,4 +2219,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2962 2010/01/27 08:31:26 freddy77 Exp $
++$Id: ChangeLog,v 1.2963 2010/01/27 12:16:09 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index b5caccb..f65ef17 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.328 2010/01/26 11:21:10 freddy77 Exp $ */
++/* $Id: tds.h,v 1.329 2010/01/27 12:16:09 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1414,7 +1414,7 @@ void tds_parse_conf_section(const char *option, const char *value, void *param);
+ TDSCONNECTION *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale);
+ void tds_fix_connection(TDSCONNECTION * connection);
+ TDS_USMALLINT tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
+-void tds_lookup_host(const char *servername, char *ip);
++int tds_lookup_host(const char *servername, char *ip);
+ int tds_set_interfaces_file_loc(const char *interfloc);
+ extern const char STD_DATETIME_FMT[];
+ 
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 333ed1d..953eaa8 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005-2008  Frediano Ziglio
++ * Copyright (C) 2005-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.82 2010/01/10 14:43:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.83 2010/01/27 12:16:09 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -124,7 +124,9 @@ parse_server(TDS_ERRS *errs, char *server, TDSCONNECTION * connection)
+ 		*p = 0;
+ 	}
+ 
+-	tds_lookup_host(server, ip);
++	if (tds_lookup_host(server, ip) == TDS_SUCCEED)
++		tds_dstr_copy(&connection->server_host_name, server);
++
+ 	if (!tds_dstr_copy(&connection->ip_addr, ip)) {
+ 		odbc_errs_add(errs, "HY001", NULL);
+ 		return 0;
+diff --git a/src/tds/config.c b/src/tds/config.c
+index f216db2..19979fe 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.155 2010/01/21 13:41:31 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.156 2010/01/27 12:16:09 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -771,7 +771,7 @@ tds_set_interfaces_file_loc(const char *interf)
+  * string.
+  */
+ /* TODO callers seem to set always connection info... change it */
+-void
++int
+ tds_lookup_host(const char *servername,	/* (I) name of the server                  */
+ 		char *ip	/* (O) dotted-decimal ip address of server */
+ 	)
+@@ -792,7 +792,7 @@ tds_lookup_host(const char *servername,	/* (I) name of the server
+ 	ip_addr = inet_addr(servername);
+ 	if (ip_addr != INADDR_NONE) {
+ 		tds_strlcpy(ip, servername, 17);
+-		return;
++		return TDS_SUCCEED;
+ 	}
+ 
+ 	host = tds_gethostbyname_r(servername, &result, buffer, sizeof(buffer), &h_errnop);
+@@ -802,7 +802,9 @@ tds_lookup_host(const char *servername,	/* (I) name of the server
+ 		struct in_addr *ptr = (struct in_addr *) host->h_addr;
+ 
+ 		tds_inet_ntoa_r(*ptr, ip, 17);
++		return TDS_SUCCEED;
+ 	}
++	return TDS_FAIL;
+ }
+ 
+ /**
+
+commit c74ba9434a7ceb9aa494c490831d2ff564c65625
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 12:22:00 2010 +0000
+
+    use Negotiate and provide SPN in order to enable Kerberos support using SSPI
+
+diff --git a/ChangeLog b/ChangeLog
+index cf78d98..1a4476a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Jan 27 13:20:42 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/sspi.c:
++	- use Negotiate and provide SPN in order to enable Kerberos support
++	  using SSPI
++
+ Wed Jan 27 13:14:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/connectparams.c src/tds/config.c:
+ 	- set correctly server_host_name from odbc
+@@ -2219,4 +2224,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2963 2010/01/27 12:16:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2964 2010/01/27 12:22:00 freddy77 Exp $
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index 072fb56..51ee44e 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.4 2010/01/27 08:31:26 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.5 2010/01/27 12:22:00 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -63,6 +63,7 @@ typedef struct tds_sspi_auth
+ 	TDSAUTHENTICATION tds_auth;
+ 	CredHandle cred;
+ 	CtxtHandle cred_ctx;
++	char *sname;
+ } TDSSSPIAUTH;
+ 
+ static HMODULE secdll = NULL;
+@@ -108,6 +109,7 @@ tds_sspi_free(TDSSOCKET * tds, struct tds_authentication * tds_auth)
+ 	sec_fn->DeleteSecurityContext(&auth->cred_ctx);
+ 	sec_fn->FreeCredentialsHandle(&auth->cred);
+ 	free(auth->tds_auth.packet);
++	free(auth->sname);
+ 	free(auth);
+ 	return TDS_SUCCEED;
+ }
+@@ -147,7 +149,7 @@ tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size
+ 	out_buf.pvBuffer   = auth->tds_auth.packet;
+ 	out_buf.cbBuffer   = NTLMBUF_LEN;
+ 
+-	status = sec_fn->InitializeSecurityContext(&auth->cred, &auth->cred_ctx, NULL /* TODO SPN */,
++	status = sec_fn->InitializeSecurityContext(&auth->cred, &auth->cred_ctx, auth->sname,
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP, &in_desc,
+ 		0, &auth->cred_ctx, &out_desc,
+@@ -157,6 +159,8 @@ tds_sspi_handle_next(TDSSOCKET * tds, struct tds_authentication * tds_auth, size
+ 
+ 	if (status != SEC_E_OK)
+ 		return TDS_FAIL;
++	if (out_buf.cbBuffer == 0)
++		return TDS_SUCCEED;
+ 
+ 	tds_put_n(tds, auth->tds_auth.packet, out_buf.cbBuffer);
+ 
+@@ -176,14 +180,14 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	ULONG attrs;
+ 	TimeStamp ts;
+ 	SEC_WINNT_AUTH_IDENTITY identity;
+-	const char *p, *user_name;
++	const char *p, *user_name, *server_name;
+ 
+ 	TDSSSPIAUTH *auth;
+ 	TDSCONNECTION *connection = tds->connection;
+ 
+ 	/* check connection */
+ 	if (!connection)
+-		return TDS_FAIL;
++		return NULL;
+ 
+ 	if (!tds_init_secdll())
+ 		return NULL;
+@@ -193,12 +197,12 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	user_name = tds_dstr_cstr(&connection->user_name);
+ 	if ((p = strchr(user_name, '\\')) != NULL) {
+ 		identity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
+-		identity.Password = (unsigned short *) tds_dstr_cstr(&connection->password);
++		identity.Password = (void *) tds_dstr_cstr(&connection->password);
+ 		identity.PasswordLength = tds_dstr_len(&connection->password);
+-		identity.Domain = (unsigned short *) user_name;
++		identity.Domain = (void *) user_name;
+ 		identity.DomainLength = p - user_name;
+ 		user_name = p + 1;
+-		identity.User = (unsigned short *) user_name;
++		identity.User = (void *) user_name;
+ 		identity.UserLength = strlen(user_name);
+ 	}
+ 
+@@ -210,13 +214,14 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	auth->tds_auth.handle_next = tds_sspi_handle_next;
+ 
+ 	/* TODO use SPNEGO to use Kerberos if possible */
+-	if (sec_fn->AcquireCredentialsHandle(NULL, (char *)"NTLM", SECPKG_CRED_OUTBOUND,
++	if (sec_fn->AcquireCredentialsHandle(NULL, (char *)"Negotiate", SECPKG_CRED_OUTBOUND,
+ 		NULL, identity.Domain ? &identity : NULL,
+ 		NULL, NULL, &auth->cred, &ts) != SEC_E_OK) {
+ 		free(auth);
+ 		return NULL;
+ 	}
+ 
++	/* allocate buffer */
+ 	auth->tds_auth.packet = (TDS_UCHAR *) malloc(NTLMBUF_LEN);
+ 	if (!auth->tds_auth.packet) {
+ 		sec_fn->FreeCredentialsHandle(&auth->cred);
+@@ -231,7 +236,27 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	buf.BufferType = SECBUFFER_TOKEN;
+ 	buf.pvBuffer   = auth->tds_auth.packet;
+ 
+-	status = sec_fn->InitializeSecurityContext(&auth->cred, NULL, "" /* TODO SPN */,
++	/* build SPN */
++	server_name = tds_dstr_cstr(&connection->server_host_name);
++	if (strchr(server_name, '.') == NULL) {
++		struct hostent result;
++		int h_errnop;
++
++		struct hostent *host = tds_gethostbyname_r(server_name, &result, auth->tds_auth.packet, NTLMBUF_LEN, &h_errnop);
++		if (host && strchr(host->h_name, '.') != NULL)
++			server_name = host->h_name;
++	}
++	if (strchr(server_name, '.') != NULL) {
++		if (asprintf(&auth->sname, "MSSQLSvc/%s:%d", server_name, connection->port) < 0) {
++			free(auth->tds_auth.packet);
++			sec_fn->FreeCredentialsHandle(&auth->cred);
++			free(auth);
++			return NULL;
++		}
++		tdsdump_log(TDS_DBG_NETWORK, "kerberos name %s\n", auth->sname);
++	}
++
++	status = sec_fn->InitializeSecurityContext(&auth->cred, NULL, auth->sname,
+ 		ISC_REQ_CONFIDENTIALITY | ISC_REQ_REPLAY_DETECT | ISC_REQ_CONNECTION,
+ 		0, SECURITY_NETWORK_DREP,
+ 		NULL, 0,
+@@ -241,6 +266,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	if (status == SEC_I_COMPLETE_AND_CONTINUE || status == SEC_I_CONTINUE_NEEDED) {
+ 		sec_fn->CompleteAuthToken(&auth->cred_ctx, &desc);
+ 	} else if(status != SEC_E_OK) {
++		free(auth->sname);
+ 		free(auth->tds_auth.packet);
+ 		sec_fn->FreeCredentialsHandle(&auth->cred);
+ 		free(auth);
+
+commit 7d61f2d5db716bbd1389d543e488b944886b5319
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 15:32:02 2010 +0000
+
+    implement pthread compatible mutex for windows (partial code from pthread-win32, LGPL 2 too)
+
+diff --git a/ChangeLog b/ChangeLog
+index 1a4476a..50266c4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Jan 27 16:29:44 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsthread.h src/tds/Makefile.am src/tds/ptw32_MCS_lock.c:
++	* src/tds/win_mutex.c:
++	- implement pthread compatible mutex for windows (partial code from
++	  pthread-win32, LGPL 2 too)
++
+ Wed Jan 27 13:20:42 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/sspi.c:
+ 	- use Negotiate and provide SPN in order to enable Kerberos support
+@@ -2224,4 +2230,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2964 2010/01/27 12:22:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2965 2010/01/27 15:32:02 freddy77 Exp $
+diff --git a/include/tdsthread.h b/include/tdsthread.h
+index fde1c52..c2e5c13 100644
+--- a/include/tdsthread.h
++++ b/include/tdsthread.h
+@@ -1,6 +1,7 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  *
+  * Copyright (C) 2005 Liam Widdowson
++ * Copyright (C) 2010 Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -21,34 +22,38 @@
+ #ifndef TDSTHREAD_H
+ #define TDSTHREAD_H 1
+ 
+-/* $Id: tdsthread.h,v 1.4 2008/12/11 12:37:57 freddy77 Exp $ */
++/* $Id: tdsthread.h,v 1.5 2010/01/27 15:32:04 freddy77 Exp $ */
+ 
+ #if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX)
+ 
+ #include <pthread.h>
+ 
+-#define TDS_MUTEX_DECLARE(name) pthread_mutex_t name
+ #define TDS_MUTEX_DEFINE(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+ #define TDS_MUTEX_LOCK(a) pthread_mutex_lock(a)
+ #define TDS_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
+-#define TDS_MUTEX_T pthread_mutex_t
+-#define TDS_MUTEX_DECLARE_RECURSIVE(name) pthread_mutex_t name = PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP;
+-#define TDS_MUTEX_INIT_RECURSIVE(mutex) do { \
+-		pthread_mutexattr_t _attr; \
+-		pthread_mutexattr_init(&_attr); \
+-		pthread_mutexattr_settype(&_attr, PTHREAD_MUTEX_RECURSIVE); \
+-		pthread_mutex_init(mutex, &_attr); \
+-		pthread_mutexattr_destroy(&_attr); \
+-	} while(0)
++
++#elif defined(_WIN32)
++
++typedef struct tds_win_mutex_t_ {
++	void *lock;
++	LONG done;
++	CRITICAL_SECTION crit;
++} tds_win_mutex_t;
++
++void tds_win_mutex_lock(tds_win_mutex_t *mutex);
++/* void tds_win_mutex_unlock(tds_win_mutex_t *mutex); */
++
++#define TDS_MUTEX_DEFINE(name) tds_win_mutex_t name = { NULL, 0 }
++#define TDS_MUTEX_LOCK(a) \
++	do { if ((a)->done) EnterCriticalSection(&(a)->crit); else tds_win_mutex_lock(a); } while(0)
++#define TDS_MUTEX_UNLOCK(a) LeaveCriticalSection(&(a)->crit)
++
+ #else
+ 
+-#define TDS_MUTEX_DECLARE(name) int name
+ #define TDS_MUTEX_DEFINE(name) int name
+ #define TDS_MUTEX_LOCK(a)
+ #define TDS_MUTEX_UNLOCK(a)
+-#define TDS_MUTEX_T int
+-#define TDS_MUTEX_DECLARE_RECURSIVE(name) int name
+-#define TDS_MUTEX_INIT_RECURSIVE(mutex)
++
+ #endif
+ 
+ #endif
+diff --git a/src/tds/Makefile.am b/src/tds/Makefile.am
+index df8f185..f694ee1 100644
+--- a/src/tds/Makefile.am
++++ b/src/tds/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.71 2010/01/26 11:21:10 freddy77 Exp $
++# $Id: Makefile.am,v 1.72 2010/01/27 15:32:04 freddy77 Exp $
+ 
+ SUBDIRS			=	unittests
+ AM_CPPFLAGS		=	-I$(top_srcdir)/include
+@@ -16,14 +16,14 @@ libtds_la_SOURCES=	mem.c token.c util.c login.c read.c \
+ 	locale.c threadsafe.c vstrbuild.c \
+ 	tdsstring.c getmac.c data.c net.c \
+ 	tds_checks.c tds_checks.h enum_cap.h log.c \
+-	bulk.c \
++	bulk.c win_mutex.c \
+ 	$(AUTH_FILES)
+ libtds_la_LDFLAGS=
+ libtds_la_LIBADD=
+ 
+ noinst_HEADERS		= tds_willconvert.h encodings.h num_limits.h types.h
+ EXTRA_DIST		= tds_willconvert.h encodings.h num_limits.h types.h \
+-	TDS.vcproj $(AUTH_FILES_DIST)
++	TDS.vcproj ptw32_MCS_lock.c $(AUTH_FILES_DIST)
+ 
+ if HAVE_DOXYGEN
+ doxyfile: $(srcdir)/tds.dox
+diff --git a/src/tds/ptw32_MCS_lock.c b/src/tds/ptw32_MCS_lock.c
+new file mode 100644
+index 0000000..cdf6eda
+--- /dev/null
++++ b/src/tds/ptw32_MCS_lock.c
+@@ -0,0 +1,206 @@
++/*
++ * ptw32_MCS_lock.c
++ *
++ * Description:
++ * This translation unit implements queue-based locks.
++ *
++ * --------------------------------------------------------------------------
++ *
++ *      Pthreads-win32 - POSIX Threads Library for Win32
++ *      Copyright(C) 1998 John E. Bossom
++ *      Copyright(C) 1999,2005 Pthreads-win32 contributors
++ *
++ *      Contact Email: rpj@callisto.canberra.edu.au
++ *
++ *      The current list of contributors is contained
++ *      in the file CONTRIBUTORS included with the source
++ *      code distribution. The list can also be seen at the
++ *      following World Wide Web location:
++ *      http://sources.redhat.com/pthreads-win32/contributors.html
++ *
++ *      This library is free software; you can redistribute it and/or
++ *      modify it under the terms of the GNU Lesser General Public
++ *      License as published by the Free Software Foundation; either
++ *      version 2 of the License, or (at your option) any later version.
++ *
++ *      This library is distributed in the hope that it will be useful,
++ *      but WITHOUT ANY WARRANTY; without even the implied warranty of
++ *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ *      Lesser General Public License for more details.
++ *
++ *      You should have received a copy of the GNU Lesser General Public
++ *      License along with this library in the file COPYING.LIB;
++ *      if not, write to the Free Software Foundation, Inc.,
++ *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
++ */
++
++/*
++ * About MCS locks:
++ *
++ * MCS locks are queue-based locks, where the queue nodes are local to the
++ * thread. The 'lock' is nothing more than a global pointer that points to
++ * the last node in the queue, or is NULL if the queue is empty.
++ *
++ * Originally designed for use as spin locks requiring no kernel resources
++ * for synchronisation or blocking, the implementation below has adapted
++ * the MCS spin lock for use as a general mutex that will suspend threads
++ * when there is lock contention.
++ *
++ * Because the queue nodes are thread-local, most of the memory read/write
++ * operations required to add or remove nodes from the queue do not trigger
++ * cache-coherence updates.
++ *
++ * Like 'named' mutexes, MCS locks consume system resources transiently -
++ * they are able to acquire and free resources automatically - but MCS
++ * locks do not require any unique 'name' to identify the lock to all
++ * threads using it.
++ *
++ * Usage of MCS locks:
++ *
++ * - you need a global ptw32_mcs_lock_t instance initialised to 0 or NULL.
++ * - you need a local thread-scope ptw32_mcs_local_node_t instance, which
++ *   may serve several different locks but you need at least one node for
++ *   every lock held concurrently by a thread.
++ *
++ * E.g.:
++ *
++ * ptw32_mcs_lock_t lock1 = 0;
++ * ptw32_mcs_lock_t lock2 = 0;
++ *
++ * void *mythread(void *arg)
++ * {
++ *   ptw32_mcs_local_node_t node;
++ *
++ *   ptw32_mcs_acquire (&lock1, &node);
++ *   ptw32_mcs_release (&node);
++ *
++ *   ptw32_mcs_acquire (&lock2, &node);
++ *   ptw32_mcs_release (&node);
++ *   {
++ *      ptw32_mcs_local_node_t nodex;
++ *
++ *      ptw32_mcs_acquire (&lock1, &node);
++ *      ptw32_mcs_acquire (&lock2, &nodex);
++ *
++ *      ptw32_mcs_release (&nodex);
++ *      ptw32_mcs_release (&node);
++ *   }
++ *   return (void *)0;
++ * }
++ */
++
++#if 0
++#include "implement.h"
++#include "pthread.h"
++#endif
++
++struct ptw32_mcs_node_t_
++{
++	struct ptw32_mcs_node_t_ **lock;	/* ptr to tail of queue */
++	struct ptw32_mcs_node_t_ *next;	/* ptr to successor in queue */
++	void *readyFlag;	/* set after lock is released by predecessor */
++	void *nextFlag;		/* set after 'next' ptr is set by successor */
++};
++
++typedef struct ptw32_mcs_node_t_ ptw32_mcs_local_node_t;
++typedef struct ptw32_mcs_node_t_ *ptw32_mcs_lock_t;
++
++/*
++ * ptw32_mcs_flag_set -- notify another thread about an event.
++ *
++ * Set event if an event handle has been stored in the flag, and
++ * set flag to -1 otherwise. Note that -1 cannot be a valid handle value.
++ */
++static inline void
++ptw32_mcs_flag_set(PVOID volatile *flag)
++{
++	HANDLE e = (HANDLE) InterlockedCompareExchangePointer(flag, (void *) -1, (void *) 0);
++
++	if ((HANDLE) 0 != e) {
++		/* another thread has already stored an event handle in the flag */
++		SetEvent(e);
++	}
++}
++
++/*
++ * ptw32_mcs_flag_set -- wait for notification from another.
++ *
++ * Store an event handle in the flag and wait on it if the flag has not been
++ * set, and proceed without creating an event otherwise.
++ */
++static inline void
++ptw32_mcs_flag_wait(PVOID volatile *flag)
++{
++	if (0 == InterlockedCompareExchangePointer(flag, 0, 0)) {	/* MBR fence */
++		/* the flag is not set. create event. */
++		HANDLE e = CreateEvent(NULL, FALSE, FALSE, NULL);
++
++		if (0 == InterlockedCompareExchangePointer(flag, (void *) e, (void *) 0)) {
++			/* stored handle in the flag. wait on it now. */
++			WaitForSingleObject(e, INFINITE);
++		}
++		CloseHandle(e);
++	}
++}
++
++/*
++ * ptw32_mcs_lock_acquire -- acquire an MCS lock.
++ *
++ * See:
++ * J. M. Mellor-Crummey and M. L. Scott.
++ * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors.
++ * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991.
++ */
++static inline void
++ptw32_mcs_lock_acquire(ptw32_mcs_lock_t * lock, ptw32_mcs_local_node_t * node)
++{
++	ptw32_mcs_local_node_t *pred;
++
++	node->lock = lock;
++	node->nextFlag = 0;
++	node->readyFlag = 0;
++	node->next = 0;		/* initially, no successor */
++
++	/* queue for the lock */
++	pred = (ptw32_mcs_local_node_t *) InterlockedExchangePointer((void **) lock, node);
++
++	if (0 != pred) {
++		/* the lock was not free. link behind predecessor. */
++		pred->next = node;
++		ptw32_mcs_flag_set(&pred->nextFlag);
++		ptw32_mcs_flag_wait(&node->readyFlag);
++	}
++}
++
++/*
++ * ptw32_mcs_lock_release -- release an MCS lock.
++ *
++ * See:
++ * J. M. Mellor-Crummey and M. L. Scott.
++ * Algorithms for Scalable Synchronization on Shared-Memory Multiprocessors.
++ * ACM Transactions on Computer Systems, 9(1):21-65, Feb. 1991.
++ */
++static inline void
++ptw32_mcs_lock_release(ptw32_mcs_local_node_t * node)
++{
++	ptw32_mcs_lock_t *lock = node->lock;
++
++	ptw32_mcs_local_node_t *next = (ptw32_mcs_local_node_t *)
++		InterlockedCompareExchangePointer(&node->next, 0, 0);	/* MBR fence */
++
++	if (0 == next) {
++		/* no known successor */
++		if (node == (ptw32_mcs_local_node_t *) InterlockedCompareExchangePointer(lock, 0, node)) {
++			/* no successor, lock is free now */
++			return;
++		}
++
++		/* wait for successor */
++		ptw32_mcs_flag_wait(&node->nextFlag);
++		next = (ptw32_mcs_local_node_t *) InterlockedCompareExchangePointer(&node->next, 0, 0);	/* MBR fence */
++	}
++
++	/* pass the lock */
++	ptw32_mcs_flag_set(&next->readyFlag);
++}
++
+diff --git a/src/tds/win_mutex.c b/src/tds/win_mutex.c
+new file mode 100644
+index 0000000..c1bba58
+--- /dev/null
++++ b/src/tds/win_mutex.c
+@@ -0,0 +1,57 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Frediano Ziglio
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++#if HAVE_CONFIG_H
++#include <config.h>
++#endif
++
++#if HAVE_STDLIB_H
++#include <stdlib.h>
++#endif /* HAVE_STDLIB_H */
++
++#ifdef _WIN32
++
++#if HAVE_STRING_H
++#include <string.h>
++#endif /* HAVE_STRING_H */
++
++#include "tds.h"
++#include "tdsthread.h"
++
++TDS_RCSID(var, "$Id: win_mutex.c,v 1.1 2010/01/27 15:32:04 freddy77 Exp $");
++
++#include "ptw32_MCS_lock.c"
++
++void
++tds_win_mutex_lock(tds_win_mutex_t * mutex)
++{
++	if (!InterlockedExchangeAdd(&mutex->done, 0)) {	/* MBR fence */
++		ptw32_mcs_local_node_t node;
++
++		ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *) &mutex->lock, &node);
++		if (!mutex->done) {
++			InitializeCriticalSection(&mutex->crit);
++			mutex->done = 1;
++		}
++		ptw32_mcs_lock_release(&node);
++	}
++	EnterCriticalSection(&mutex->crit);
++}
++
++#endif
+
+commit d1a657f2dd38de5713ff5c8c3382f4d2a72db157
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 15:35:18 2010 +0000
+
+    fix thread issue with SSPI
+
+diff --git a/ChangeLog b/ChangeLog
+index 50266c4..03a72f7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jan 27 16:34:28 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/sspi.c: fix thread issue with SSPI
++
+ Wed Jan 27 16:29:44 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsthread.h src/tds/Makefile.am src/tds/ptw32_MCS_lock.c:
+ 	* src/tds/win_mutex.c:
+@@ -2230,4 +2233,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2965 2010/01/27 15:32:02 freddy77 Exp $
++$Id: ChangeLog,v 1.2966 2010/01/27 15:35:18 freddy77 Exp $
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index 51ee44e..d660534 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -38,6 +38,7 @@
+ #include <rpc.h>
+ 
+ #include "tds.h"
++#include "tdsthread.h"
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+@@ -45,7 +46,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.5 2010/01/27 12:22:00 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.6 2010/01/27 15:35:18 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -68,37 +69,48 @@ typedef struct tds_sspi_auth
+ 
+ static HMODULE secdll = NULL;
+ static PSecurityFunctionTableA sec_fn = NULL;
++static TDS_MUTEX_DEFINE(sec_mutex);
+ 
+ static int
+ tds_init_secdll(void)
+ {
+-	/* FIXME therad safe !!! */
+-	if (!secdll) {
+-		OSVERSIONINFO osver;
+-
+-		memset(&osver, 0, sizeof(osver));
+-		osver.dwOSVersionInfoSize = sizeof(osver);
+-		if (!GetVersionEx(&osver))
+-			return 0;
+-		if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT && osver.dwMajorVersion <= 4)
+-			secdll = LoadLibrary("security.dll");
+-		else
+-			secdll = LoadLibrary("secur32.dll");
+-		if (!secdll)
+-			return 0;
+-	}
+-	if (!sec_fn) {
+-		INIT_SECURITY_INTERFACE_A pInitSecurityInterface;
++	int res = 0;
++
++	if (sec_fn)
++		return 1;
++
++	TDS_MUTEX_LOCK(&sec_mutex);
++	for (;;) {
++		if (!secdll) {
++			OSVERSIONINFO osver;
++
++			memset(&osver, 0, sizeof(osver));
++			osver.dwOSVersionInfoSize = sizeof(osver);
++			if (!GetVersionEx(&osver))
++				break;
++			if (osver.dwPlatformId == VER_PLATFORM_WIN32_NT && osver.dwMajorVersion <= 4)
++				secdll = LoadLibrary("security.dll");
++			else
++				secdll = LoadLibrary("secur32.dll");
++			if (!secdll)
++				break;
++		}
++		if (!sec_fn) {
++			INIT_SECURITY_INTERFACE_A pInitSecurityInterface;
+ 
+-		pInitSecurityInterface = (INIT_SECURITY_INTERFACE_A) GetProcAddress(secdll, "InitSecurityInterfaceA");
+-		if (!pInitSecurityInterface)
+-			return 0;
++			pInitSecurityInterface = (INIT_SECURITY_INTERFACE_A) GetProcAddress(secdll, "InitSecurityInterfaceA");
++			if (!pInitSecurityInterface)
++				break;
+ 
+-		sec_fn = pInitSecurityInterface();
+-		if (!sec_fn)
+-			return 0;
++			sec_fn = pInitSecurityInterface();
++			if (!sec_fn)
++				break;
++		}
++		res = 1;
++		break;
+ 	}
+-	return 1;
++	TDS_MUTEX_UNLOCK(&sec_mutex);
++	return res;
+ }
+ 
+ static int
+
+commit 06757c6b357eb0c313d71eeaaf2ebd1e51f89bef
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 15:39:00 2010 +0000
+
+    fix format error which could cause core
+
+diff --git a/ChangeLog b/ChangeLog
+index 03a72f7..cade78d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jan 27 16:37:25 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/dblib.c: fix format error which could cause core
++
+ Wed Jan 27 16:34:28 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/sspi.c: fix thread issue with SSPI
+ 
+@@ -2233,4 +2236,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2966 2010/01/27 15:35:18 freddy77 Exp $
++$Id: ChangeLog,v 1.2967 2010/01/27 15:39:00 freddy77 Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 7f527e9..475cb9b 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006, 2007, 2008  Frediano Ziglio
++ * Copyright (C) 2006-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.360 2010/01/27 03:21:08 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.361 2010/01/27 15:39:00 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -7937,7 +7937,7 @@ dbperror (DBPROCESS *dbproc, DBINT msgno, long errnum, ...)
+ 			return INT_CANCEL;
+ 		}
+ 		fprintf(stderr, int_exit_text, db_msgtext, msgno);
+-		tdsdump_log(TDS_DBG_SEVERE, int_exit_text, rc, msgno);
++		tdsdump_log(TDS_DBG_SEVERE, int_exit_text, db_msgtext, msgno);
+ 		break;
+ 	}
+ 	exit(EXIT_FAILURE);
+
+commit 1f76525e44383d95b0885aec47e41d67925595a9
+Author: freddy77 <freddy77>
+Date:   Wed Jan 27 23:15:39 2010 +0000
+
+    remove small warning
+
+diff --git a/ChangeLog b/ChangeLog
+index cade78d..1341030 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 28 00:15:31 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: remove small warning
++
+ Wed Jan 27 16:37:25 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/dblib.c: fix format error which could cause core
+ 
+@@ -2236,4 +2239,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2967 2010/01/27 15:39:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2968 2010/01/27 23:15:39 freddy77 Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 692409c..76bc931 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -62,7 +62,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.192 2010/01/22 22:41:48 jklowden Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.193 2010/01/27 23:15:39 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -1154,7 +1154,7 @@ _bcp_read_hostfile(DBPROCESS * dbproc, FILE * hostfile, int *row_error)
+ 			if (hostcol->tab_colnum > dbproc->bcpinfo->bindinfo->num_cols) {
+ 				tdsdump_log(TDS_DBG_FUNC, "error: file wider than table: %d/%d\n", 
+ 							  i+1, dbproc->bcpinfo->bindinfo->num_cols);
+-				dbperror(dbproc, SYBEBEOF, NULL);
++				dbperror(dbproc, SYBEBEOF, 0);
+ 				return FAIL;
+ 			}
+ 			tdsdump_log(TDS_DBG_FUNC, "host column %d uses bcpcol %d (%p)\n", 
+
+commit 83dd1754be7d5378da59b235b536adbf958c2969
+Author: jklowden <jklowden>
+Date:   Thu Jan 28 05:35:54 2010 +0000
+
+    more checks for NULL DBPROCESS/LOGINREC
+
+diff --git a/ChangeLog b/ChangeLog
+index 1341030..e5e5c44 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 28 00:31:25 EST 2010	JK Lowden <jklowden@freetds.org>
++	* src/dblib/dblib.c more checks for NULL DBPROCESS/LOGINREC
++
+ Thu Jan 28 00:15:31 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/bcp.c: remove small warning
+ 
+@@ -2239,4 +2242,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2968 2010/01/27 23:15:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2969 2010/01/28 05:35:54 jklowden Exp $
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 475cb9b..035d17f 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.361 2010/01/27 15:39:00 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.362 2010/01/28 05:35:55 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -803,6 +803,11 @@ dbsetllong(LOGINREC * login, long value, int which)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsetllong(%p, %ld, %d)\n", login, value, which);
+ 
++	if( login == NULL ) {
++		dbperror(NULL, SYBEASNL, 0);
++		return FAIL;
++	}
++
+ 	switch (which) {
+ 	case DBSETPACKET:
+ 		if (0 <= value && value <= 999999) { 
+@@ -836,6 +841,11 @@ dbsetlshort(LOGINREC * login, int value, int which)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsetlshort(%p, %d, %d)\n", login, value, which);
+ 
++	if( login == NULL ) {
++		dbperror(NULL, SYBEASNL, 0);
++		return FAIL;
++	}
++
+ 	switch (which) {
+ 	case DBSETHIER:
+ 	default:
+@@ -864,6 +874,11 @@ dbsetlbool(LOGINREC * login, int value, int which)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsetlbool(%p, %d, %d)\n", login, value, which);
+ 
++	if( login == NULL ) {
++		dbperror(NULL, SYBEASNL, 0);
++		return FAIL;
++	}
++
+ 	switch (which) {
+ 	case DBSETBCP:
+ 		tds_set_bulk(login->tds_login, (TDS_TINYINT) value);
+@@ -888,8 +903,12 @@ dbsetlversion (LOGINREC * login, BYTE version)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "dbsetlversion(%p, %x)\n", login, version);
+ 
+-	if (login == NULL || login->tds_login == NULL)
++	if( login == NULL ) {
++		dbperror(NULL, SYBEASNL, 0);
+ 		return FAIL;
++	}
++
++	assert(login->tds_login != NULL);
+ 		
+ 	switch (version) {
+ 	case DBVER42:
+@@ -1237,7 +1256,7 @@ dbfcmd(DBPROCESS * dbproc, const char *fmt, ...)
+ 	va_end(ap);
+ 
+ 	if (len < 0) {
+-		dbperror(NULL, SYBEMEM, errno);
++		dbperror(dbproc, SYBEMEM, errno);
+ 		return FAIL;
+ 	}
+ 
+@@ -1460,8 +1479,7 @@ dbexit()
+ {
+ 	TDSSOCKET *tds;
+ 	DBPROCESS *dbproc;
+-	int i, list_size;
+-	int count = 1;
++	int i, list_size, count = 1;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbexit(void)\n");
+ 
+@@ -1791,6 +1809,7 @@ dbcolname(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 	
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcolname(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2591,7 +2610,7 @@ dbbind(DBPROCESS * dbproc, int column, int vartype, DBINT varlen, BYTE * varaddr
+ void
+ dbsetifile(char *filename)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "dbsetifile(%s)\n", filename);
++	tdsdump_log(TDS_DBG_FUNC, "dbsetifile(%s)\n", filename? filename : "0x00");
+ 	if (filename == NULL) { 
+ 		dbperror(NULL, SYBENULP, 0); 
+ 		return;
+@@ -2626,7 +2645,7 @@ dbnullbind(DBPROCESS * dbproc, int column, DBINT * indicator)
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+-		return FAIL;
++		return FAIL; /* dbcolptr sent SYBECNOR, Column number out of range */
+ 
+ 	colinfo->column_nullbind = (TDS_SMALLINT *)indicator;
+ 	return SUCCEED;
+@@ -2758,6 +2777,7 @@ dbcoltype(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcoltype(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2787,6 +2807,7 @@ dbcolutype(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcolutype(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2801,6 +2822,7 @@ dbcolutype(DBPROCESS * dbproc, int column)
+  * 
+  * \param dbproc contains all information needed by db-lib to manage communications with the server.
+  * \param column Nth in the result set, starting from 1.
++ * \return Pointer to a DBTYPEINFO structure .  NULL \a column is out of range.
+  * \sa dbcollen(), dbcolname(), dbcoltype(), dbdata(), dbdatlen(), dbnumcols(), dbprtype(), dbvarylen().
+  */
+ DBTYPEINFO *
+@@ -2810,6 +2832,7 @@ dbcoltypeinfo(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcoltypeinfo(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2841,6 +2864,7 @@ dbcolinfo (DBPROCESS *dbproc, CI_TYPE type, DBINT column, DBINT computeid, DBCOL
+ 	int i;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcolinfo(%p, %d, %d, %d, %p)\n", dbproc, type, column, computeid, pdbcol);
++	CHECK_PARAMETER(dbproc, SYBENULL, FAIL);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2951,6 +2975,7 @@ dbcolsource(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcolsource(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2974,6 +2999,7 @@ dbcollen(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbcollen(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -2999,6 +3025,7 @@ dbvarylen(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbvarylen(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, FALSE);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -3049,6 +3076,7 @@ dbdatlen(DBPROCESS * dbproc, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbdatlen(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -3077,6 +3105,7 @@ dbdata(DBPROCESS * dbproc, int column)
+ 	const static BYTE empty[1] = { 0 };
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbdata(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo)
+@@ -4001,6 +4030,7 @@ dbaltcolid(DBPROCESS * dbproc, int computeid, int column)
+ 	TDSCOLUMN *curcol;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbaltcolid(%p, %d, %d)\n", dbproc, computeid, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	curcol = dbacolptr(dbproc, computeid, column, 0);
+ 	if (!curcol)
+@@ -4028,6 +4058,7 @@ dbadlen(DBPROCESS * dbproc, int computeid, int column)
+ 	DBINT len;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbadlen(%p, %d, %d)\n", dbproc, computeid, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	colinfo = dbacolptr(dbproc, computeid, column, 0);
+ 	if (!colinfo)
+@@ -4057,6 +4088,7 @@ dbalttype(DBPROCESS * dbproc, int computeid, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbalttype(%p, %d, %d)\n", dbproc, computeid, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	colinfo = dbacolptr(dbproc, computeid, column, 0);
+ 	if (!colinfo)
+@@ -4124,6 +4156,7 @@ dbaltbind(DBPROCESS * dbproc, int computeid, int column, int vartype, DBINT varl
+ 	TDSCOLUMN *colinfo = NULL;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbaltbind(%p, %d, %d, %d, %d, %p)\n", dbproc, computeid, column, vartype, varlen, varaddr);
++	CHECK_PARAMETER(dbproc, SYBENULL, FAIL);
+ 
+ 	colinfo = dbacolptr(dbproc, computeid, column, 1);
+ 	if (!colinfo)
+@@ -4167,6 +4200,7 @@ dbadata(DBPROCESS * dbproc, int computeid, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbadata(%p, %d, %d)\n", dbproc, computeid, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbacolptr(dbproc, computeid, column, 0);
+ 	if (!colinfo)
+@@ -4196,6 +4230,7 @@ dbaltop(DBPROCESS * dbproc, int computeid, int column)
+ 	TDSCOLUMN *curcol;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbaltop(%p, %d, %d)\n", dbproc, computeid, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	if ((curcol=dbacolptr(dbproc, computeid, column, 0)) == NULL)
+ 		return -1;
+@@ -6255,6 +6290,7 @@ dbtxtimestamp(DBPROCESS * dbproc, int column)
+ 	TDSBLOB *blob;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbtxtimestamp(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo || !is_blob_col(colinfo))
+@@ -6281,6 +6317,7 @@ dbtxptr(DBPROCESS * dbproc, int column)
+ 	TDSBLOB *blob;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbtxptr(%p, %d)\n", dbproc, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, 0);
+ 
+ 	colinfo = dbcolptr(dbproc, column);
+ 	if (!colinfo || !is_blob_col(colinfo))
+@@ -6836,6 +6873,7 @@ dbaltutype(DBPROCESS * dbproc, int computeid, int column)
+ 	TDSCOLUMN *colinfo;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "dbaltutype(%p, %d, %d)\n", dbproc, computeid, column);
++	CHECK_PARAMETER(dbproc, SYBENULL, -1);
+ 
+ 	colinfo = dbacolptr(dbproc, computeid, column, 0);
+ 	if (!colinfo)
+@@ -7039,9 +7077,9 @@ dbstrbuild(DBPROCESS * dbproc, char *charbuf, int bufsize, char *text, char *for
+ static char *
+ _dbprdate(char *timestr)
+ {
+-	time_t currtime;
+-
+-	currtime = time(NULL);
++	time_t currtime = time(NULL);
++	
++	assert(timestr);
+ 
+ 	strcpy(timestr, asctime(gmtime(&currtime)));
+ 	timestr[strlen(timestr) - 1] = '\0';	/* remove newline */
+
+commit 763e1ba948387ce2d925b73730012bc8d72266e7
+Author: freddy77 <freddy77>
+Date:   Thu Jan 28 08:54:35 2010 +0000
+
+    reuse string constants
+
+diff --git a/ChangeLog b/ChangeLog
+index e5e5c44..ff372fc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 28 09:53:35 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c: reuse string constants
++
+ Thu Jan 28 00:31:25 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/dblib.c more checks for NULL DBPROCESS/LOGINREC
+ 
+@@ -2242,4 +2245,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2969 2010/01/28 05:35:54 jklowden Exp $
++$Id: ChangeLog,v 1.2970 2010/01/28 08:54:35 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 953eaa8..62d9119 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.83 2010/01/27 12:16:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.84 2010/01/28 08:54:35 freddy77 Exp $");
+ 
+ static const char odbc_param_Servername[] = "Servername";
+ static const char odbc_param_Address[] = "Address";
+@@ -287,7 +287,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 			return 0;
+ 		}
+ 
+-		if (strcasecmp(option, "SERVER") == 0) {
++		if (strcasecmp(option, odbc_param_Server) == 0) {
+ 			/* error if servername or DSN specified */
+ 			if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+@@ -303,7 +303,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 				}
+ 				cfgs = CFG_SERVER;
+ 			}
+-		} else if (strcasecmp(option, "SERVERNAME") == 0) {
++		} else if (strcasecmp(option, odbc_param_Servername) == 0) {
+ 			if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
+ 				tds_dstr_free(&value);
+ 				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+@@ -331,7 +331,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 				p = connect_string;
+ 				continue;
+ 			}
+-		} else if (strcasecmp(option, "DATABASE") == 0) {
++		} else if (strcasecmp(option, odbc_param_Database) == 0) {
+ 			dest_s = &connection->database;
+ 		} else if (strcasecmp(option, "UID") == 0) {
+ 			dest_s = &connection->user_name;
+@@ -341,7 +341,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 			dest_s = &connection->app_name;
+ 		} else if (strcasecmp(option, "WSID") == 0) {
+ 			dest_s = &connection->client_host_name;
+-		} else if (strcasecmp(option, "LANGUAGE") == 0) {
++		} else if (strcasecmp(option, odbc_param_Language) == 0) {
+ 			tds_parse_conf_section(TDS_STR_LANGUAGE, tds_dstr_cstr(&value), connection);
+ 		} else if (strcasecmp(option, odbc_param_Port) == 0) {
+ 			tds_parse_conf_section(TDS_STR_PORT, tds_dstr_cstr(&value), connection);
+
+commit 5a1e1e4069b8486d64c24c81c847438952c74af2
+Author: freddy77 <freddy77>
+Date:   Thu Jan 28 10:07:18 2010 +0000
+
+    remove wrong TODO comment
+
+diff --git a/ChangeLog b/ChangeLog
+index ff372fc..8746c61 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 28 11:06:05 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/sspi.c: remove wrong TODO comment
++
+ Thu Jan 28 09:53:35 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c: reuse string constants
+ 
+@@ -2245,4 +2248,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2970 2010/01/28 08:54:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2971 2010/01/28 10:07:18 freddy77 Exp $
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index d660534..89c4222 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -46,7 +46,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.6 2010/01/27 15:35:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.7 2010/01/28 10:07:18 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -225,7 +225,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	auth->tds_auth.free = tds_sspi_free;
+ 	auth->tds_auth.handle_next = tds_sspi_handle_next;
+ 
+-	/* TODO use SPNEGO to use Kerberos if possible */
++	/* using Negotiate system will use proper protocol (either NTLM or Kerberos) */
+ 	if (sec_fn->AcquireCredentialsHandle(NULL, (char *)"Negotiate", SECPKG_CRED_OUTBOUND,
+ 		NULL, identity.Domain ? &identity : NULL,
+ 		NULL, NULL, &auth->cred, &ts) != SEC_E_OK) {
+
+commit 1ec79bfaaa9fc97b4867e96a4501c94df240a7b0
+Author: freddy77 <freddy77>
+Date:   Thu Jan 28 13:15:20 2010 +0000
+
+    does not overwrite error with other calls
+
+diff --git a/ChangeLog b/ChangeLog
+index 8746c61..4b2ee45 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jan 28 14:14:04 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: does not overwrite error with other calls
++
+ Thu Jan 28 11:06:05 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/sspi.c: remove wrong TODO comment
+ 
+@@ -2248,4 +2251,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2971 2010/01/28 10:07:18 freddy77 Exp $
++$Id: ChangeLog,v 1.2972 2010/01/28 13:15:20 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 2b2a226..f1f1b76 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.100 2010/01/10 14:43:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.101 2010/01/28 13:15:21 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -273,10 +273,10 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	if (retval == 0) {
+ 		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
+ 	} else {
+-		tds->oserr = sock_errno;
+-		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", sock_strerror(sock_errno));
++		int err = tds->oserr = sock_errno;
++		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", sock_strerror(err));
+ #if DEBUGGING_CONNECTING_PROBLEM
+-		if (sock_errno != ECONNREFUSED && sock_errno != ENETUNREACH && sock_errno != TDSSOCK_EINPROGRESS) {
++		if (err != ECONNREFUSED && err != ENETUNREACH && err != TDSSOCK_EINPROGRESS) {
+ 			tdsdump_dump_buf(TDS_DBG_ERROR, "Contents of sockaddr_in", &sin, sizeof(sin));
+ 			tdsdump_log(TDS_DBG_ERROR, 	" sockaddr_in:\t"
+ 							      "%s = %x\n" 
+@@ -290,7 +290,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 							);
+ 		}
+ #endif
+-		if (sock_errno != TDSSOCK_EINPROGRESS)
++		if (err != TDSSOCK_EINPROGRESS)
+ 			goto not_available;
+ 		
+ 		if (tds_select(tds, TDSSELWRITE|TDSSELERR, timeout) <= 0) {
+@@ -691,6 +691,7 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 
+ 	while (p - buffer < len) {
+ 		if ((rc = tds_select(tds, TDSSELWRITE, tds->query_timeout)) > 0) {
++			int err;
+ 			size_t remaining = len - (p - buffer);
+ #ifdef USE_MSGMORE
+ 			ssize_t nput = send(tds->s, p, remaining, last ? MSG_NOSIGNAL : MSG_NOSIGNAL|MSG_MORE);
+@@ -704,22 +705,24 @@ tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t len, unsigned
+ 				p += nput;
+ 				continue;
+ 			}
+-			
+-			if (0 == nput || TDSSOCK_WOULDBLOCK(sock_errno))
++
++			err = sock_errno;
++			if (0 == nput || TDSSOCK_WOULDBLOCK(err))
+ 				continue;
+ 
+ 			assert(nput < 0);
+-			
+-			tdsdump_log(TDS_DBG_NETWORK, "send(2) failed: %d (%s)\n", sock_errno, sock_strerror(sock_errno));
+-			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
++
++			tdsdump_log(TDS_DBG_NETWORK, "send(2) failed: %d (%s)\n", err, sock_strerror(err));
++			tdserror(tds->tds_ctx, tds, TDSEWRIT, err);
+ 			tds_close_socket(tds);
+ 			return -1;
+ 
+ 		} else if (rc < 0) {
+-			if (TDSSOCK_WOULDBLOCK(sock_errno)) /* shouldn't happen, but OK, retry */
++			int err = sock_errno;
++			if (TDSSOCK_WOULDBLOCK(err)) /* shouldn't happen, but OK, retry */
+ 				continue;
+-			tdsdump_log(TDS_DBG_NETWORK, "select(2) failed: %d (%s)\n", sock_errno, sock_strerror(sock_errno));
+-			tdserror(tds->tds_ctx, tds, TDSEWRIT, sock_errno);
++			tdsdump_log(TDS_DBG_NETWORK, "select(2) failed: %d (%s)\n", err, sock_strerror(err));
++			tdserror(tds->tds_ctx, tds, TDSEWRIT, err);
+ 			tds_close_socket(tds);
+ 			return -1;
+ 		} else { /* timeout */
+
+commit 83fc95982d8838c33f1be57693c0db53e5d74b0f
+Author: freddy77 <freddy77>
+Date:   Thu Jan 28 13:31:51 2010 +0000
+
+    improve (a lot!) log performance under windows using append mode
+
+diff --git a/ChangeLog b/ChangeLog
+index 4b2ee45..6801f79 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jan 28 14:30:21 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsthread.h src/tds/log.c:
++	- improve (a lot!) log performance under windows using append mode
++
+ Thu Jan 28 14:14:04 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: does not overwrite error with other calls
+ 
+@@ -2251,4 +2255,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2972 2010/01/28 13:15:20 freddy77 Exp $
++$Id: ChangeLog,v 1.2973 2010/01/28 13:31:51 freddy77 Exp $
+diff --git a/include/tdsthread.h b/include/tdsthread.h
+index c2e5c13..b4249f1 100644
+--- a/include/tdsthread.h
++++ b/include/tdsthread.h
+@@ -22,7 +22,9 @@
+ #ifndef TDSTHREAD_H
+ #define TDSTHREAD_H 1
+ 
+-/* $Id: tdsthread.h,v 1.5 2010/01/27 15:32:04 freddy77 Exp $ */
++/* $Id: tdsthread.h,v 1.6 2010/01/28 13:31:51 freddy77 Exp $ */
++
++#undef TDS_HAVE_MUTEX
+ 
+ #if defined(_THREAD_SAFE) && defined(TDS_HAVE_PTHREAD_MUTEX)
+ 
+@@ -32,6 +34,8 @@
+ #define TDS_MUTEX_LOCK(a) pthread_mutex_lock(a)
+ #define TDS_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
+ 
++#define TDS_HAVE_MUTEX 1
++
+ #elif defined(_WIN32)
+ 
+ typedef struct tds_win_mutex_t_ {
+@@ -48,6 +52,8 @@ void tds_win_mutex_lock(tds_win_mutex_t *mutex);
+ 	do { if ((a)->done) EnterCriticalSection(&(a)->crit); else tds_win_mutex_lock(a); } while(0)
+ #define TDS_MUTEX_UNLOCK(a) LeaveCriticalSection(&(a)->crit)
+ 
++#define TDS_HAVE_MUTEX 1
++
+ #else
+ 
+ #define TDS_MUTEX_DEFINE(name) int name
+diff --git a/src/tds/log.c b/src/tds/log.c
+index c064963..335bf59 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2006-2008 Frediano Ziglio
++ * Copyright (C) 2006-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.16 2010/01/11 18:00:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.17 2010/01/28 13:31:51 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+@@ -154,7 +154,7 @@ tdsdump_open(const char *filename)
+ 	if (tds_g_append_mode) {
+ 		g_dump_filename = strdup(filename);
+ 		/* if mutex are available do not reopen file every time */
+-#ifdef TDS_HAVE_PTHREAD_MUTEX
++#ifdef TDS_HAVE_MUTEX
+ 		g_dumpfile = tdsdump_append();
+ #endif
+ 	} else if (!strcmp(filename, "stdout")) {
+@@ -296,7 +296,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con
+ 	TDS_MUTEX_LOCK(&g_dump_mutex);
+ 
+ 	dumpfile = g_dumpfile;
+-#ifdef TDS_HAVE_PTHREAD_MUTEX
++#ifdef TDS_HAVE_MUTEX
+ 	if (tds_g_append_mode && dumpfile == NULL)
+ 		dumpfile = g_dumpfile = tdsdump_append();
+ #else
+@@ -354,7 +354,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con
+ 
+ 	fflush(dumpfile);
+ 
+-#ifndef TDS_HAVE_PTHREAD_MUTEX
++#ifndef TDS_HAVE_MUTEX
+ 	if (tds_g_append_mode) {
+ 		if (dumpfile != stdout && dumpfile != stderr)
+ 			fclose(dumpfile);
+@@ -389,7 +389,7 @@ tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ 	TDS_MUTEX_LOCK(&g_dump_mutex);
+ 
+ 	dumpfile = g_dumpfile;
+-#ifdef TDS_HAVE_PTHREAD_MUTEX
++#ifdef TDS_HAVE_MUTEX
+ 	if (tds_g_append_mode && dumpfile == NULL)
+ 		dumpfile = g_dumpfile = tdsdump_append();
+ #else
+@@ -411,7 +411,7 @@ tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ 
+ 	fflush(dumpfile);
+ 
+-#ifndef TDS_HAVE_PTHREAD_MUTEX
++#ifndef TDS_HAVE_MUTEX
+ 	if (tds_g_append_mode) {
+ 		if (dumpfile != stdout && dumpfile != stderr)
+ 			fclose(dumpfile);
+
+commit c67758afe2e2dc58abfa0abba1a98138fd84690d
+Author: freddy77 <freddy77>
+Date:   Fri Jan 29 14:04:57 2010 +0000
+
+    peephole optimization
+
+diff --git a/ChangeLog b/ChangeLog
+index 6801f79..bf7d338 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 29 15:04:27 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h: peephole optimization
++
+ Thu Jan 28 14:30:21 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsthread.h src/tds/log.c:
+ 	- improve (a lot!) log performance under windows using append mode
+@@ -2255,4 +2258,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2973 2010/01/28 13:31:51 freddy77 Exp $
++$Id: ChangeLog,v 1.2974 2010/01/29 14:04:57 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index f65ef17..c2ec04b 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.329 2010/01/27 12:16:09 freddy77 Exp $ */
++/* $Id: tds.h,v 1.330 2010/01/29 14:04:59 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -852,13 +852,13 @@ typedef struct tds_login
+ 	DSTR password;
+ 	
+ 	DSTR library;	/* Ct-Library, DB-Library,  TDS-Library or ODBC */
+-	TDS_TINYINT bulk_copy;
+-	TDS_TINYINT suppress_language;
+ 	TDS_TINYINT encryption_level;
+ 
+ 	TDS_INT query_timeout;
+ 	unsigned char capabilities[TDS_MAX_CAPABILITY];
+ 	DSTR client_charset;
++	unsigned int bulk_copy:1;
++	unsigned int suppress_language:1;
+ } TDSLOGIN;
+ 
+ typedef struct tds_connection
+@@ -877,8 +877,6 @@ typedef struct tds_connection
+ 	DSTR user_name;	    	/**< account for login */
+ 	DSTR password;	    	/**< password of account login */
+ 	DSTR library;
+-	TDS_TINYINT bulk_copy;
+-	TDS_TINYINT suppress_language;
+ 	TDS_TINYINT encryption_level;
+ 
+ 	TDS_INT query_timeout;
+@@ -893,6 +891,8 @@ typedef struct tds_connection
+ 	int text_size;
+ 	unsigned int broken_dates:1;
+ 	unsigned int emul_little_endian:1;
++	unsigned int bulk_copy:1;
++	unsigned int suppress_language:1;
+ } TDSCONNECTION;
+ 
+ typedef struct tds_locale
+
+commit 93faaaa5ba68d574ea86ce8922f9aea80ad2171a
+Author: freddy77 <freddy77>
+Date:   Fri Jan 29 14:08:56 2010 +0000
+
+    make popup window always visible
+
+diff --git a/ChangeLog b/ChangeLog
+index bf7d338..600d0b4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jan 29 15:08:07 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/setup.rc: make popup window always visible
++
+ Fri Jan 29 15:04:27 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h: peephole optimization
+ 
+@@ -2258,4 +2261,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2974 2010/01/29 14:04:57 freddy77 Exp $
++$Id: ChangeLog,v 1.2975 2010/01/29 14:08:56 freddy77 Exp $
+diff --git a/win32/setup.rc b/win32/setup.rc
+index 3eeb9b2..083533d 100644
+--- a/win32/setup.rc
++++ b/win32/setup.rc
+@@ -58,7 +58,7 @@ BEGIN
+ END
+ 
+ IDD_LOGIN DIALOG DISCARDABLE  0, 0, 164, 117
+-STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION
++STYLE DS_MODALFRAME | DS_3DLOOK | WS_CAPTION | WS_VISIBLE
+ CAPTION "FreeTDS Login"
+ FONT 8, "MS Sans Serif"
+ BEGIN
+
+commit 859b92a50e7971393a845672a546a85c6284477a
+Author: freddy77 <freddy77>
+Date:   Fri Jan 29 18:57:03 2010 +0000
+
+    complete connection string if possible
+
+diff --git a/ChangeLog b/ChangeLog
+index 600d0b4..5c5547c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Jan 29 19:56:51 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h include/tdsodbc.h src/odbc/connectparams.c:
++	* src/odbc/odbc.c src/tds/config.c win32/winsetup.c:
++	- complete connection string if possible
++
+ Fri Jan 29 15:08:07 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/setup.rc: make popup window always visible
+ 
+@@ -2261,4 +2266,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2975 2010/01/29 14:08:56 freddy77 Exp $
++$Id: ChangeLog,v 1.2976 2010/01/29 18:57:03 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index c2ec04b..63f151d 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.330 2010/01/29 14:04:59 freddy77 Exp $ */
++/* $Id: tds.h,v 1.331 2010/01/29 18:57:03 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1417,6 +1417,7 @@ TDS_USMALLINT tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
+ int tds_lookup_host(const char *servername, char *ip);
+ int tds_set_interfaces_file_loc(const char *interfloc);
+ extern const char STD_DATETIME_FMT[];
++int tds_config_boolean(const char *value);
+ 
+ TDSLOCALE *tds_get_locale(void);
+ int tds_alloc_row(TDSRESULTINFO * res_info);
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index f72cfe9..afd1c65 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2004, 2005, 2006, 2007, 2008  Frediano Ziglio
++ * Copyright (C) 2004-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.118 2010/01/25 23:05:59 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.119 2010/01/29 18:57:03 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -434,9 +434,45 @@ typedef struct _hchk TDS_CHK;
+ BOOL get_login_info(HWND hwndParent, TDSCONNECTION * connection);
+ #endif
+ 
++#define ODBC_PARAM_LIST \
++	ODBC_PARAM(Servername) \
++	ODBC_PARAM(Server) \
++	ODBC_PARAM(DSN) \
++	ODBC_PARAM(UID) \
++	ODBC_PARAM(PWD) \
++	ODBC_PARAM(Address) \
++	ODBC_PARAM(Port) \
++	ODBC_PARAM(TDS_Version) \
++	ODBC_PARAM(Language) \
++	ODBC_PARAM(Database) \
++	ODBC_PARAM(TextSize) \
++	ODBC_PARAM(PacketSize) \
++	ODBC_PARAM(ClientCharset) \
++	ODBC_PARAM(DumpFile) \
++	ODBC_PARAM(DumpFileAppend) \
++	ODBC_PARAM(DebugFlags) \
++	ODBC_PARAM(Encryption) \
++	ODBC_PARAM(Trusted_Connection) \
++	ODBC_PARAM(APP) \
++	ODBC_PARAM(WSID)
++
++#define ODBC_PARAM(p) ODBC_PARAM_##p,
++enum {
++	ODBC_PARAM_LIST
++	ODBC_PARAM_SIZE
++};
++#undef ODBC_PARAM
++
++
+ /*
+  * connectparams.h
+  */
++
++typedef struct {
++	const char *p;
++	size_t len;
++} TDS_PARSED_PARAM;
++
+ /**
+  * Parses a connection string for SQLDriverConnect().
+  * \param connect_string      point to connection string
+@@ -444,8 +480,11 @@ BOOL get_login_info(HWND hwndParent, TDSCONNECTION * connection);
+  * \param connection          structure where to store informations
+  * \return 0 if error, 1 otherwise
+  */
+-int odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection);
++int odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection, TDS_PARSED_PARAM *parsed_params);
+ int odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSCONNECTION * connection);
++#ifdef _WIN32
++int odbc_build_connect_string(TDS_ERRS *errs, TDS_PARSED_PARAM *params, char **out);
++#endif
+ 
+ /*
+  * convert_tds2sql.c
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 62d9119..9f076db 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,22 +37,17 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.84 2010/01/28 08:54:35 freddy77 Exp $");
+-
+-static const char odbc_param_Servername[] = "Servername";
+-static const char odbc_param_Address[] = "Address";
+-static const char odbc_param_Server[] = "Server";
+-static const char odbc_param_Port[] = "Port";
+-static const char odbc_param_TDS_Version[] = "TDS_Version";
+-static const char odbc_param_Language[] = "Language";
+-static const char odbc_param_Database[] = "Database";
+-static const char odbc_param_TextSize[] = "TextSize";
+-static const char odbc_param_PacketSize[] = "PacketSize";
+-static const char odbc_param_ClientCharset[] = "ClientCharset";
+-static const char odbc_param_DumpFile[] = "DumpFile";
+-static const char odbc_param_DumpFileAppend[] = "DumpFileAppend";
+-static const char odbc_param_DebugFlags[] = "DebugFlags";
+-static const char odbc_param_Encryption[] = "Encryption";
++TDS_RCSID(var, "$Id: connectparams.c,v 1.85 2010/01/29 18:57:03 freddy77 Exp $");
++
++#define ODBC_PARAM(p) static const char odbc_param_##p[] = #p;
++ODBC_PARAM_LIST
++#undef ODBC_PARAM
++
++#define ODBC_PARAM(p) odbc_param_##p,
++static const char *odbc_param_names[] = {
++	ODBC_PARAM_LIST
++};
++#undef ODBC_PARAM
+ 
+ #if !HAVE_SQLGETPRIVATEPROFILESTRING
+ 
+@@ -233,16 +228,23 @@ odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSCONNECTION * connection)
+  * @return 1 if success 0 otherwhise
+  */
+ int
+-odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection)
++odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char *connect_string_end, TDSCONNECTION * connection,
++			  TDS_PARSED_PARAM *parsed_params)
+ {
+ 	const char *p, *end;
+ 	DSTR *dest_s, value;
+ 	enum { CFG_DSN = 1, CFG_SERVER = 2, CFG_SERVERNAME = 4 };
+ 	unsigned int cfgs = 0;	/* flags for indicate second parse of string */
+-	char option[16];
++	char option[24];
++	int trusted = 0;
++
++	if (parsed_params)
++		memset(parsed_params, 0, sizeof(*parsed_params)*ODBC_PARAM_SIZE);
+ 
+ 	tds_dstr_init(&value);
+ 	for (p = connect_string; p < connect_string_end && *p;) {
++		int num_param = -1;
++
+ 		dest_s = NULL;
+ 
+ 		/* handle empty options */
+@@ -287,7 +289,8 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 			return 0;
+ 		}
+ 
+-		if (strcasecmp(option, odbc_param_Server) == 0) {
++#define CHK_PARAM(p) (strcasecmp(option, odbc_param_##p) == 0 && (num_param=ODBC_PARAM_##p) >= 0)
++		if (CHK_PARAM(Server)) {
+ 			/* error if servername or DSN specified */
+ 			if ((cfgs & (CFG_DSN|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+@@ -303,7 +306,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 				}
+ 				cfgs = CFG_SERVER;
+ 			}
+-		} else if (strcasecmp(option, odbc_param_Servername) == 0) {
++		} else if (CHK_PARAM(Servername)) {
+ 			if ((cfgs & (CFG_DSN|CFG_SERVER)) != 0) {
+ 				tds_dstr_free(&value);
+ 				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+@@ -316,7 +319,7 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 				p = connect_string;
+ 				continue;
+ 			}
+-		} else if (strcasecmp(option, "DSN") == 0) {
++		} else if (CHK_PARAM(DSN)) {
+ 			if ((cfgs & (CFG_SERVER|CFG_SERVERNAME)) != 0) {
+ 				tds_dstr_free(&value);
+ 				odbc_errs_add(errs, "HY000", "Only one between SERVER, SERVERNAME and DSN can be specified");
+@@ -331,39 +334,48 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 				p = connect_string;
+ 				continue;
+ 			}
+-		} else if (strcasecmp(option, odbc_param_Database) == 0) {
++		} else if (CHK_PARAM(Database)) {
+ 			dest_s = &connection->database;
+-		} else if (strcasecmp(option, "UID") == 0) {
++		} else if (CHK_PARAM(UID)) {
+ 			dest_s = &connection->user_name;
+-		} else if (strcasecmp(option, "PWD") == 0) {
++		} else if (CHK_PARAM(PWD)) {
+ 			dest_s = &connection->password;
+-		} else if (strcasecmp(option, "APP") == 0) {
++		} else if (CHK_PARAM(APP)) {
+ 			dest_s = &connection->app_name;
+-		} else if (strcasecmp(option, "WSID") == 0) {
++		} else if (CHK_PARAM(WSID)) {
+ 			dest_s = &connection->client_host_name;
+-		} else if (strcasecmp(option, odbc_param_Language) == 0) {
++		} else if (CHK_PARAM(Language)) {
+ 			tds_parse_conf_section(TDS_STR_LANGUAGE, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_Port) == 0) {
++		} else if (CHK_PARAM(Port)) {
+ 			tds_parse_conf_section(TDS_STR_PORT, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_TDS_Version) == 0) {
++		} else if (CHK_PARAM(TDS_Version)) {
+ 			tds_parse_conf_section(TDS_STR_VERSION, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_TextSize) == 0) {
++		} else if (CHK_PARAM(TextSize)) {
+ 			tds_parse_conf_section(TDS_STR_TEXTSZ, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_PacketSize) == 0) {
++		} else if (CHK_PARAM(PacketSize)) {
+ 			tds_parse_conf_section(TDS_STR_BLKSZ, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_ClientCharset) == 0) {
++		} else if (CHK_PARAM(ClientCharset)) {
+ 			tds_parse_conf_section(TDS_STR_CLCHARSET, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_DumpFile) == 0) {
++		} else if (CHK_PARAM(DumpFile)) {
+ 			tds_parse_conf_section(TDS_STR_DUMPFILE, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_DumpFileAppend) == 0) {
++		} else if (CHK_PARAM(DumpFileAppend)) {
+ 			tds_parse_conf_section(TDS_STR_APPENDMODE, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_DebugFlags) == 0) {
++		} else if (CHK_PARAM(DebugFlags)) {
+ 			tds_parse_conf_section(TDS_STR_DEBUGFLAGS, tds_dstr_cstr(&value), connection);
+-		} else if (strcasecmp(option, odbc_param_Encryption) == 0) {
++		} else if (CHK_PARAM(Encryption)) {
+ 			tds_parse_conf_section(TDS_STR_ENCRYPTION, tds_dstr_cstr(&value), connection);
++		} else if (CHK_PARAM(Trusted_Connection)) {
++			trusted = tds_config_boolean(tds_dstr_cstr(&value));
++			tdsdump_log(TDS_DBG_INFO1, "trusted %s -> %d\n", tds_dstr_cstr(&value), trusted);
++			num_param = -1;
+ 			/* TODO odbc_param_Address field */
+ 		}
+ 
++		if (num_param >= 0 && parsed_params) {
++			parsed_params[num_param].p = p;
++			parsed_params[num_param].len = end - p;
++		}
++
+ 		/* copy to destination */
+ 		if (dest_s) {
+ 			DSTR tmp = *dest_s;
+@@ -380,10 +392,53 @@ odbc_parse_connect_string(TDS_ERRS *errs, const char *connect_string, const char
+ 		++p;
+ 	}
+ 
++	if (trusted) {
++		if (parsed_params) {
++			parsed_params[ODBC_PARAM_Trusted_Connection].p = "Yes";
++			parsed_params[ODBC_PARAM_Trusted_Connection].len = 3;
++			parsed_params[ODBC_PARAM_UID].p = NULL;
++			parsed_params[ODBC_PARAM_PWD].p = NULL;
++		}
++		tds_dstr_copy(&connection->user_name, "");
++		tds_dstr_copy(&connection->password, "");
++	}
++
+ 	tds_dstr_free(&value);
+ 	return 1;
+ }
+ 
++#ifdef _WIN32
++int
++odbc_build_connect_string(TDS_ERRS *errs, TDS_PARSED_PARAM *params, char **out)
++{
++	unsigned n;
++	size_t len = 1;
++	char *p;
++
++	/* compute string size */
++	for (n = 0; n < ODBC_PARAM_SIZE; ++n) {
++		if (params[n].p)
++			len += strlen(odbc_param_names[n]) + params[n].len + 2;
++	}
++
++	/* allocate */
++	p = (char*) malloc(len);
++	if (!p) {
++		odbc_errs_add(errs, "HY001", NULL);
++		return 0;
++	}
++	*out = p;
++
++	/* build it */
++	for (n = 0; n < ODBC_PARAM_SIZE; ++n) {
++		if (params[n].p)
++			p += sprintf(p, "%s=%.*s;", odbc_param_names[n], (int) params[n].len, params[n].p);
++	}
++	*p = 0;
++	return 1;
++}
++#endif
++
+ #if !HAVE_SQLGETPRIVATEPROFILESTRING
+ 
+ #ifdef _WIN32
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index efe7c8a..eba4f63 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.527 2010/01/27 08:31:26 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.528 2010/01/29 18:57:03 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -411,6 +411,7 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ {
+ 	TDSCONNECTION *connection;
+ 	int conlen = odbc_get_string_size(cbConnStrIn, szConnStrIn);
++	TDS_PARSED_PARAM params[ODBC_PARAM_SIZE];
+ 
+ 	INIT_HDBC;
+ 
+@@ -447,27 +448,49 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 		tds_dstr_dup(&connection->database, &dbc->attr.current_catalog);
+ 
+ 	/* parse the DSN string */
+-	odbc_parse_connect_string(&dbc->errs, (const char *) szConnStrIn, (const char *) szConnStrIn + conlen, connection);
++	if (!odbc_parse_connect_string(&dbc->errs, (const char *) szConnStrIn, (const char *) szConnStrIn + conlen,
++				       connection, params))
++		ODBC_RETURN(dbc, SQL_ERROR);
++
++	odbc_set_string(szConnStrOut, cbConnStrOutMax, pcbConnStrOut, (const char *) szConnStrIn, conlen);
+ 
+ 	/* add login info */
+-	if (hwnd) {
++	if (hwnd && fDriverCompletion != SQL_DRIVER_NOPROMPT
++	    && (fDriverCompletion == SQL_DRIVER_PROMPT || (!params[ODBC_PARAM_UID].p && !params[ODBC_PARAM_Trusted_Connection].p)
++		|| tds_dstr_isempty(&connection->server_name))) {
+ #ifdef _WIN32
++		char *out = NULL;
++
+ 		/* prompt for login information */
+ 		if (!get_login_info(hwnd, connection)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "08001", "User canceled login");
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
++		if (tds_dstr_isempty(&connection->user_name)) {
++			params[ODBC_PARAM_UID].p = NULL;
++			params[ODBC_PARAM_PWD].p = NULL;
++			params[ODBC_PARAM_Trusted_Connection].p = "Yes";
++			params[ODBC_PARAM_Trusted_Connection].len = 3;
++		} else {
++			params[ODBC_PARAM_UID].p   = tds_dstr_cstr(&connection->user_name);
++			params[ODBC_PARAM_UID].len = tds_dstr_len(&connection->user_name);
++			params[ODBC_PARAM_PWD].p   = tds_dstr_cstr(&connection->password);
++			params[ODBC_PARAM_PWD].len = tds_dstr_len(&connection->password);
++			params[ODBC_PARAM_Trusted_Connection].p = NULL;
++		}
++		if (!odbc_build_connect_string(&dbc->errs, params, &out))
++			ODBC_RETURN(dbc, SQL_ERROR);
++
++		odbc_set_string(szConnStrOut, cbConnStrOutMax, pcbConnStrOut, out, -1);
++		tdsdump_log(TDS_DBG_INFO1, "connection string is now: %s\n", out);
++		free(out);
+ #else
+ 		/* we dont support a dialog box */
+ 		odbc_errs_add(&dbc->errs, "HYC00", NULL);
+ #endif
+ 	}
+ 
+-	/* TODO what should be correct behavior for output string?? -- freddy77 */
+-	if (szConnStrOut)
+-		odbc_set_string(szConnStrOut, cbConnStrOutMax, pcbConnStrOut, (const char *) szConnStrIn, conlen);
+-
+ 	if (tds_dstr_isempty(&connection->server_name)) {
+ 		tds_free_connection(connection);
+ 		odbc_errs_add(&dbc->errs, "IM007", "Could not find Servername or server parameter");
+@@ -3800,7 +3823,7 @@ SQLFetchScroll(SQLHSTMT hstmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset)
+ SQLRETURN ODBC_API
+ SQLFreeHandle(SQLSMALLINT HandleType, SQLHANDLE Handle)
+ {
+-	tdsdump_log(TDS_DBG_INFO1, "SQLFreeHandle(%d, 0x%p)\n", HandleType, (void *) Handle);
++	tdsdump_log(TDS_DBG_INFO1, "SQLFreeHandle(%d, %p)\n", HandleType, (void *) Handle);
+ 
+ 	switch (HandleType) {
+ 	case SQL_HANDLE_STMT:
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 19979fe..96cbd9c 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -76,7 +76,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.156 2010/01/27 12:16:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.157 2010/01/29 18:57:03 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -85,7 +85,6 @@ static void tds_config_env_tdsport(TDSCONNECTION * connection);
+ static void tds_config_env_tdshost(TDSCONNECTION * connection);
+ static int tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection);
+ static int tds_read_interfaces(const char *server, TDSCONNECTION * connection);
+-static int tds_config_boolean(const char *value);
+ static int parse_server_name_for_port(TDSCONNECTION * connection, TDSLOGIN * login);
+ static int tds_lookup_port(const char *portname);
+ static void tds_config_encryption(const char * value, TDSCONNECTION * connection);
+@@ -396,7 +395,7 @@ static const struct {
+ 	{ "false",	0 }
+ };
+ 
+-static int
++int
+ tds_config_boolean(const char *value)
+ {
+ 	int p;
+diff --git a/win32/winsetup.c b/win32/winsetup.c
+index a0809e4..ac8ec3b 100644
+--- a/win32/winsetup.c
++++ b/win32/winsetup.c
+@@ -135,7 +135,7 @@ parse_wacky_dsn_string(LPCSTR attribs, DSNINFO * di)
+ 	}
+ 
+ 	/* let odbc_parse_connect_string() parse the ;-delimited version */
+-	odbc_parse_connect_string(NULL, build, build + strlen(build), di->connection);
++	odbc_parse_connect_string(NULL, build, build + strlen(build), di->connection, NULL);
+ }
+ 
+ 
+
+commit ef5e4aa92c667e6fde8c7bf0725003375c93f3c8
+Author: freddy77 <freddy77>
+Date:   Mon Feb 1 10:10:19 2010 +0000
+
+    update documentation
+
+diff --git a/ChangeLog b/ChangeLog
+index 5c5547c..6ba2e74 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Feb  1 11:09:51 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac doc/userguide.sgml: update documentation
++
+ Fri Jan 29 19:56:51 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h include/tdsodbc.h src/odbc/connectparams.c:
+ 	* src/odbc/odbc.c src/tds/config.c win32/winsetup.c:
+@@ -2266,4 +2269,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2976 2010/01/29 18:57:03 freddy77 Exp $
++$Id: ChangeLog,v 1.2977 2010/02/01 10:10:19 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index ab53e1f..db49bf0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.45 2010/01/26 11:21:10 freddy77 Exp $
++dnl $Id: configure.ac,v 1.46 2010/02/01 10:10:19 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.45 $)
++AC_REVISION($Revision: 1.46 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -134,7 +134,7 @@ AC_SUBST(HAVE_PERL_SOURCES)
+ # Checks for libraries.
+ # ------------------------------------------------------------
+ AC_ARG_ENABLE(krb5,
+-  AS_HELP_STRING([--enable-krb5], [enable Kerberos support (EXPERIMENTAL)]))
++  AS_HELP_STRING([--enable-krb5], [enable Kerberos support]))
+ 
+ OLDLIBS="$LIBS"
+ LIBS=""
+@@ -234,7 +234,7 @@ fi
+ 
+ # check for SSPI
+ AC_ARG_ENABLE(sspi,
+-  AS_HELP_STRING([--enable-sspi], [enable SSPI support (EXPERIMENTAL)]))
++  AS_HELP_STRING([--enable-sspi], [enable SSPI support]))
+ # disable by default
+ enable_sspi=${enable_sspi-no}
+ # only if MingW (TODO other compilers)
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 4f07c80..9d32b7f 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -9,8 +9,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2009/12/14 01:02:27 $</date>
+-		<releaseinfo>$Revision: 1.126 $</releaseinfo>
++		<date>$Date: 2010/02/01 10:10:20 $</date>
++		<releaseinfo>$Revision: 1.127 $</releaseinfo>
+ 		<title>&freetds; User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running &freetds;</subtitle>
+ 		<author>
+@@ -61,9 +61,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.126 $</>
+-<member>$Date: 2009/12/14 01:02:27 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.126 2009/12/14 01:02:27 jklowden Exp $.</>
++<member>$Revision: 1.127 $</>
++<member>$Date: 2010/02/01 10:10:20 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.127 2010/02/01 10:10:20 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the &freetds; 
+@@ -432,6 +432,27 @@ There are a few optional arguments to <Command>configure</> that may be importan
+ 				</listitem>
+ 				</varlistentry>
+ 			<varlistentry>
++				<term><Option>--disable-apps
++					</Option></term>
++				<listitem><para>Do not attempt to build applications like tsql.
++				</para>
++				</listitem>
++				</varlistentry>
++			<varlistentry>
++				<term><Option>--disable-server
++					</Option></term>
++				<listitem><para>Do not attempt to build server stuff.
++				</para>
++				</listitem>
++				</varlistentry>
++			<varlistentry>
++				<term><Option>--disable-pool
++					</Option></term>
++				<listitem><para>Do not attempt to build pool stuff.
++				</para>
++				</listitem>
++				</varlistentry>
++			<varlistentry>
+ 				<term><Option>--disable-libiconv</Option></term>
+ 				<listitem><para>By default, <command>configure</> will search your system for an <systemitem class="library">iconv</systemitem> library for use with Microsoft servers (because TDS 7.0 employs Unicode).  This switch prevents that search.  If no <systemitem class="library">iconv</systemitem> library is used, &freetds; relies on its built-in iconv emulation, which is capable of converting ISO-8859-1 to UCS-2, sufficient for many applications.  </para>
+ 					</listitem>
+@@ -464,6 +485,20 @@ There are a few optional arguments to <Command>configure</> that may be importan
+ 			</varlistentry>
+ 
+ 			<varlistentry>
++				<term><Option>--enable-krb5</Option></term>
++				<listitem><para>Enable Kerberos support. With Kerberos you can connect to server using your stored Kerberos ticket.
++					This require you to configure Kerberos support on your machine.
++				</para></listitem>
++				</varlistentry>
++
++			<varlistentry>
++				<term><Option>--enable-sspi</Option></term>
++				<listitem><para>Enable SSPI support. SSPI is a Windows library that allow you to use your current logged account for 
++					authentication. This allow you to login without entering a password again.
++				</para></listitem>
++				</varlistentry>
++
++			<varlistentry>
+ 				<term><Option>--enable-extra-checks</Option></term>
+ 				<listitem><para>Intended for debugging purposes, enables certain internal consistency checks against problems like memory corruption and buffer exhaustion.  
+ 				</para></listitem>
+@@ -543,8 +578,8 @@ With any luck, you've built and installed the &freetds; libraries.
+ 				<listitem><para>The Borland Builder 6.0 compiler is also reported to work, but requires some tweaking of the <literal>#include</> statements.  We would apply any patches that make this work cleanly.</para></listitem>
+ 
+ 			</itemizedlist>	
++			</para>
+ 
+-Threadsafe operation will not be enabled.  </para>
+ 			<para>From the Department of Double Emulation: &freetds; builds as a <filename>.dll</> under <productname>WINE</> and as a <filename>.a</> under <productname>Interix</>.  See the mailing list archives (second half of 2003) for details.  </para>
+ 		</sect2>
+ 		<sect2 id="VMS"><title>VMS&reg;</title>
+@@ -581,7 +616,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2009/12/14 01:02:27 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2010/02/01 10:10:20 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -1728,6 +1763,13 @@ The following table defines all possible ODBC connection attributes for the <pro
+ 	<entry>DB dependent</entry>
+ 	<entry>Size of packets to server.  Some users saw some performance gain by increasing this value.  Normally you shouldn't set it.  </entry>
+ 	</row>
++	<row>
++	<entry><literal>Trusted_Connection</></entry>
++	<entry>Yes/No</entry>
++	<entry>No</entry>
++	<entry>Use your current account instead of <literal>UID</>/<literal>PWD</> attributes.
++		This option require SSPI or Kerberos. This superceed <literal>UID</>/<literal>PWD</> attributes.</entry>
++	</row>
+ </tbody>
+ </tgroup>
+ </table>
+@@ -2114,31 +2156,6 @@ The SQL Server machine may belong to an NT domain.  &freetds; provides an encryp
+ 			<para>
+ Support for domain logins in &freetds; is limited to the TCP/IP network protocol stack.   &freetds; does not currently implement support for Named Pipe-based SQL connections &mdash; that is, connections transported over the DCE/RPC interface, which uses TCP port 139, 445, or 135 on Win32 machines depending on the type of encapsulation used for DCE/RPC itself. Supporting this would require a fairly extensive DCE/RPC library for Unix.   <productname>Samba</productname> has one that is licensed under the GPL and therefore not usable by LGPL-licensed projects such as &freetds; . 
+ 			</para>
+-			<para>
+-Your domain controller must allow authentication over TCP/IP, or you will be unable to log in.  One symptom of a server that requires Named Pipes for authentication is an error message such as:
+-			</para>
+-			<para>
+-<informalexample><screen><computeroutput>
+-Login failed for user '(null)'. 
+-Reason: Not associated with a trusted SQL Server connection.
+-</computeroutput></screen></informalexample>
+-			</para>
+-			<para>
+-The telltale sign being <literal>user '(null)'</>.  
+-			</para>
+-			<para>
+-If you suspect a problem along these lines, you could ask your friendly system administrator to check the following setting:
+-
+-<programlisting>
+-Computer Configuration
+- 	\Windows Settings
+-		\Security Settings
+-			\Local Policies
+-				\Security Options
+-					\LAN Manager Authentication Level
+-</programlisting>
+-The setting should be <quote><literal>Send LM & NTLM responses</></quote>.  
+-  			</para>
+ 
+ <para>
+ For a technical description of the protocol used for domain logins, see 
+@@ -2146,6 +2163,16 @@ For a technical description of the protocol used for domain logins, see
+ </para>
+ 		</sect2>
+ 		</sect1>
++		<sect1 id="kerberos">
++			<title>Kerberos support</title>
++			<para>In order to take advantage of Kerberos you have to set up your machine with keytab from your Active Directory.
++				To configure your stuff you could use samba or configure directly Kerberos (<filename>/etc/krb5.conf</>).
++			</para>
++			<para>By default Unix do not initialize Kerberos ticket with your login account. You have to use kinit to initialize ticket.
++				You could also configure Kerberos in PAM in order to initialize Kerberos ticket at login time. 
++			</para>
++		</sect1>
++
+ 		<sect1 id="appendmode">
+ 			<title>Appending Dump Files</title>
+ 			<para>
+@@ -2827,7 +2854,7 @@ Server</productname> uses the facilities of the host operating system (<productn
+ username alone, without requiring a separate login name and password.
+ 			</para>
+ <Note><para>
+-The &freetds; supports integrated security mode.  If you have <productname>SQL Server</productname> running in integrated (domain) mode along with a Windows PDC, and wish to try it, see <link linkend="domains">Domain Logins</link> in the <link linkend="configs">Advanced Configurations</link> chapter.
++The &freetds; supports integrated security mode.  If you have <productname>SQL Server</productname> running in integrated (domain) mode along with a Windows PDC, and wish to try it, see <link linkend="domains">Domain Logins</link> in the <link linkend="configs">Advanced Configurations</link> chapter. If you have Active Directory you can also use Kerberos, see <link linkend="kerberos">Kerberos support</link>.
+ </para></Note>
+ 			<para>
+ &freetds; supports the traditional database
+@@ -4162,7 +4189,7 @@ err_handler(DBPROCESS * dbproc, int severity, int dberr, int oserr,
+ <ulink url="mailto:thompbil@exchange.uk.ml.com">Bill Thompson</ulink> (thompbil@exchange.uk.ml.com)</member>
+ <member>Completer of the <systemitem class="library">db-lib</systemitem> bcp API and author of <application>freebcp</application>.</>
+ 				<member>
+-<ulink url="mailto:freddy77@angelfire.com">Frediano Ziglio</ulink> (freddy77@angelfire.com)</member>
++<ulink url="mailto:freddy77@gmail.com">Frediano Ziglio</ulink> (freddy77@gmail.com)</member>
+ <member>Extended the ODBC library, and added many, many fixes and enhancements to libtds.  </>
+ 			</simplelist>
+ 			<para>
+
+commit 86927a04dc0fdd3955234f02ce16be81ffa3cbdd
+Author: freddy77 <freddy77>
+Date:   Mon Feb 1 10:16:05 2010 +0000
+
+    update for trusted connections, support Trusted_Connection attribute in odbc.ini
+
+diff --git a/ChangeLog b/ChangeLog
+index 6ba2e74..121ccd2 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Feb  1 11:15:12 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c src/odbc/odbc.c:
++	- update for trusted connections, support Trusted_Connection
++	  attribute in odbc.ini
++
+ Mon Feb  1 11:09:51 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac doc/userguide.sgml: update documentation
+ 
+@@ -2269,4 +2274,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2977 2010/02/01 10:10:19 freddy77 Exp $
++$Id: ChangeLog,v 1.2978 2010/02/01 10:16:05 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 9f076db..1f9be9b 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,17 +37,19 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.85 2010/01/29 18:57:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.86 2010/02/01 10:16:05 freddy77 Exp $");
+ 
+ #define ODBC_PARAM(p) static const char odbc_param_##p[] = #p;
+ ODBC_PARAM_LIST
+ #undef ODBC_PARAM
+ 
++#ifdef _WIN32
+ #define ODBC_PARAM(p) odbc_param_##p,
+ static const char *odbc_param_names[] = {
+ 	ODBC_PARAM_LIST
+ };
+ #undef ODBC_PARAM
++#endif
+ 
+ #if !HAVE_SQLGETPRIVATEPROFILESTRING
+ 
+@@ -217,6 +219,11 @@ odbc_get_dsn_info(TDS_ERRS *errs, const char *DSN, TDSCONNECTION * connection)
+ 	if (myGetPrivateProfileString(DSN, odbc_param_Encryption, tmp) > 0)
+ 		tds_parse_conf_section(TDS_STR_ENCRYPTION, tmp, connection);
+ 
++	if (myGetPrivateProfileString(DSN, odbc_param_Trusted_Connection, tmp) > 0 && tds_config_boolean(tmp)) {
++		tds_dstr_copy(&connection->user_name, "");
++		tds_dstr_copy(&connection->password, "");
++	}
++
+ 	return 1;
+ }
+ 
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index eba4f63..0ef13fd 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.528 2010/01/29 18:57:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.529 2010/02/01 10:16:05 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -1758,7 +1758,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 	}
+ 
+ 	/* password */
+-	if (szAuthStr) {
++	if (szAuthStr && !tds_dstr_isempty(&connection->user_name)) {
+ 		if (!tds_dstr_copyn(&connection->password, (char *) szAuthStr, odbc_get_string_size(cbAuthStr, szAuthStr))) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+
+commit b812a051614ffa422a5b8c1b6e145344eb75c64f
+Author: freddy77 <freddy77>
+Date:   Mon Feb 1 14:56:28 2010 +0000
+
+    make null2 test work using TDS 4.2
+
+diff --git a/ChangeLog b/ChangeLog
+index 121ccd2..b38a4a1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Feb  1 15:55:30 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/null2.c: make null2 test work using TDS 4.2
++
+ Mon Feb  1 11:15:12 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c src/odbc/odbc.c:
+ 	- update for trusted connections, support Trusted_Connection
+@@ -2274,4 +2277,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2978 2010/02/01 10:16:05 freddy77 Exp $
++$Id: ChangeLog,v 1.2979 2010/02/01 14:56:28 freddy77 Exp $
+diff --git a/src/dblib/unittests/null2.c b/src/dblib/unittests/null2.c
+index 781441b..6433147 100644
+--- a/src/dblib/unittests/null2.c
++++ b/src/dblib/unittests/null2.c
+@@ -6,7 +6,7 @@
+ 
+ #include <unistd.h>
+ 
+-static char software_version[] = "$Id: null2.c,v 1.6 2009/04/17 09:54:27 freddy77 Exp $";
++static char software_version[] = "$Id: null2.c,v 1.7 2010/02/01 14:56:28 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static DBPROCESS *dbproc = NULL;
+@@ -185,12 +185,14 @@ main(int argc, char **argv)
+ 
+ 	test("NVARCHAR(10)", 0);
+ #ifndef DBNTWIN32
+-	test("NTEXT", 0);
++	if (dbtds(dbproc) >= DBTDS_7_0)
++		test("NTEXT", 0);
+ #endif
+ 
+ 	test("VARCHAR(MAX)", 0);
+ #ifndef DBNTWIN32
+-	test("NVARCHAR(MAX)", 0);
++	if (dbtds(dbproc) >= DBTDS_7_0)
++		test("NVARCHAR(MAX)", 0);
+ #endif
+ 
+ 	dbexit();
+
+commit b93ef3d6adff906be4f4d7d3766b54899988171a
+Author: freddy77 <freddy77>
+Date:   Tue Feb 2 09:37:39 2010 +0000
+
+    add some ODBC considerations
+
+diff --git a/ChangeLog b/ChangeLog
+index b38a4a1..0035abc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Feb  2 10:35:20 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* doc/userguide.sgml: add some ODBC considerations
++
+ Mon Feb  1 15:55:30 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/null2.c: make null2 test work using TDS 4.2
+ 
+@@ -2277,4 +2280,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2979 2010/02/01 14:56:28 freddy77 Exp $
++$Id: ChangeLog,v 1.2980 2010/02/02 09:37:39 freddy77 Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 9d32b7f..4de1756 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -9,8 +9,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2010/02/01 10:10:20 $</date>
+-		<releaseinfo>$Revision: 1.127 $</releaseinfo>
++		<date>$Date: 2010/02/02 09:37:39 $</date>
++		<releaseinfo>$Revision: 1.128 $</releaseinfo>
+ 		<title>&freetds; User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running &freetds;</subtitle>
+ 		<author>
+@@ -32,6 +32,7 @@
+ 		  <year>2007</year>
+ 		  <year>2008</year>
+ 		  <year>2009</year>
++		  <year>2010</year>
+ 		  <holder>Brian Bruns and James K. Lowden</holder>
+ 		</copyright>
+ 		<legalnotice><para>
+@@ -61,9 +62,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.127 $</>
+-<member>$Date: 2010/02/01 10:10:20 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.127 2010/02/01 10:10:20 freddy77 Exp $.</>
++<member>$Revision: 1.128 $</>
++<member>$Date: 2010/02/02 09:37:39 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.128 2010/02/02 09:37:39 freddy77 Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the &freetds; 
+@@ -616,7 +617,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2010/02/01 10:10:20 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2010/02/02 09:37:39 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -2173,6 +2174,30 @@ For a technical description of the protocol used for domain logins, see
+ 			</para>
+ 		</sect1>
+ 
++		<sect1 id="uothread">
++			<title>Threading on unixODBC</title>
++			<para><productname>unixODBC</> use strong thread locking policy. This cause big locks using default configurations for &freetds; which lead to performance issues using multi-thread applications (every single operation get serialized). In order to avoid this problem you have to set up threading model on <filename>odbcinst.ini</> (this configuration is supported only in this file).
++<example id="odbcinstthread"><title>Sample <filename>odbcinst.ini</> for threading model</title>
++<programlisting>
++[FreeTDS]
++	Driver = /usr/local/freetds/lib/libtdsodbc.so
++	Threading = 1
++</programlisting>
++</example>
++<example id="odbcinithread"><title>Sample <filename>odbc.ini</> for threading model</title>
++<programlisting>
++[Server1]
++	Driver = FreeTDS
++	Server = myServer1
++	Port = 1433
++	TDS_Version = 7.2
++</programlisting>
++</example>
++You can use also a connection string like <literal>DRIVER=FreeTDS;SERVER=myServer1;PORT=1433;TDS_Version=7.2;</>.
++			</para>
++		</sect1>
++
++
+ 		<sect1 id="appendmode">
+ 			<title>Appending Dump Files</title>
+ 			<para>
+@@ -2753,6 +2778,43 @@ symbols for version use 100
+ </screen>
+ 			</para>
+ 		</sect1>
++
++		<sect1 id="qt">
++			<title>Qt</title>
++			<para><productname>Qt</> has two driver to access SQL Server databases: QTDS and QODBC.
++				At the time of writing (January 2010) QTDS has a performance problem cause it does not reuse connection but do a connection for every query so use QODBC.
++			</para>
++			<para>There are however some problems with wide character support on Qt. Qt assume sizeof(SQLWCHAR) == 2 however using some DM (like <productname>iODBC</> using Linux which is the default setting on <productname>Ubuntu</>) which could lead to wrong characters conversion.
++			</para>
++		</sect1>
++
++		<sect1 id="uodbc">
++			<title>ODBC on Unix</title>
++			<para><productname>ODBC</> have many issues under Unix mainly due to lack of specifications.
++			</para>
++			<sect2 id="uodbc64">
++				<title>ODBC and 64-bit</title>
++				<para>On first specifications ODBC was only 32-bit. Converting it to 64-bit there was not good specification which leads to wrong declarations and problems. For instance some SQLINTEGER are used for pointer offsets specification but SQLINTEGER was 32-bit while pointer offsets must be 64-bit. Also row numbers and other stuffs are now 64-bit.
++				</para>
++				<para>If you use <productname>unixODBC</> I would recommend at least version 2.2.14. Former versions have issues if used on 64-bit environments.</para>
++			</sect2>
++			<sect2 id="uodbcwchar">
++				<title>sizeof(SQLWCHAR)</title>
++				<para>Under Windows you have sizeof(wchar_t) == sizeof(SQLWCHAR) == 2 but on many Unix systems you have sizeof(wchar_t) == 4. The problem is that some DM decided to keep sizeof(SQLWCHAR) == 2 (like <productname>unixODBC</>) while in other DM sizeof(SQLWCHAR) == sizeof(wchar_t) == 4 (like <productname>iODBC</>). This leads to ABI imcompatibility between applications and drivers. If you compile &freetds; ODBC driver using <productname>iODBC</> on such systems (like Linux) do not use the driver using <productname>unixODBC</> and viceversa.
++				</para>
++				<para>You can compile &freetds; with both includes and rename the library to use two ABI (for instance having a <filename>libtdsiodbc.so</> and a <filename>libtdsuodbc.so</>).
++				</para>
++				<para>As the time of writing <productname>Ubuntu</> compiled Qt using <productname>iODBC</> but mostly packages use <productname>unixODBC</>. If you plan to use Qt using &freetds; ODBC driver you should have a <productname>iODBC</> compatible driver. Also QODBC Qt driver have problems with <productname>iODBC</> and SQLWCHAR (see <link linkend="qt">Qt</link>). Due to these problems I would suggest to not use this configuration (Qt database) on <productname>Ubuntu</>.
++				</para>
++			</sect2>
++			<sect2 id="uodbcchar">
++				<title>Default charset</title>
++				<para>Is not possible to specify charset under ODBC and there was not so clear specifications. For this reason by default many DM converting from multi-byte to wide characters assume ISO8859-1 charset. For this reason even &freetds; driver assume ISO8859-1 by default. Also some DM have problems converting multi-byte encodings (like UTF-8) assuming a byte get converted to a single wide character (and viceversa). This can create problems if you use multi-byte encoding for &freetds; driver.
++				</para>
++			</sect2>
++		</sect1>
++
++
+ 	</chapter>
+ 				<!-- ////////////////// CHAPTER /////////////////////// -->
+ 	<chapter id="troubleshooting">
+
+commit 5ebbd068deb7bce3e5e2ebf1c3057e379d595396
+Author: freddy77 <freddy77>
+Date:   Tue Feb 2 09:48:52 2010 +0000
+
+    replaced getopt with LGPL version
+
+diff --git a/ChangeLog b/ChangeLog
+index 0035abc..ec71d0b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Feb  2 10:47:26 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/getopt.c: replaced getopt with LGPL version
++
+ Tue Feb  2 10:35:20 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* doc/userguide.sgml: add some ODBC considerations
+ 
+@@ -2280,4 +2283,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2980 2010/02/02 09:37:39 freddy77 Exp $
++$Id: ChangeLog,v 1.2981 2010/02/02 09:48:52 freddy77 Exp $
+diff --git a/src/replacements/getopt.c b/src/replacements/getopt.c
+index 3a51ef6..9bafa45 100644
+--- a/src/replacements/getopt.c
++++ b/src/replacements/getopt.c
+@@ -1,164 +1,1055 @@
+-/*	$NetBSD: getopt.c,v 1.27 2005/11/29 03:12:00 christos Exp $	*/
+-
+-/*
+- * Copyright (c) 1987, 1993, 1994
+- *	The Regents of the University of California.  All rights reserved.
+- *
+- * Redistribution and use in source and binary forms, with or without
+- * modification, are permitted provided that the following conditions
+- * are met:
+- * 1. Redistributions of source code must retain the above copyright
+- *    notice, this list of conditions and the following disclaimer.
+- * 2. Redistributions in binary form must reproduce the above copyright
+- *    notice, this list of conditions and the following disclaimer in the
+- *    documentation and/or other materials provided with the distribution.
+- * 3. Neither the name of the University nor the names of its contributors
+- *    may be used to endorse or promote products derived from this software
+- *    without specific prior written permission.
+- *
+- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+- * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+- * SUCH DAMAGE.
+- */
+-
+-#undef LIBC_SCCS
+-
+-#if !defined(_WIN32)
+-# include <sys/cdefs.h>
++/* Getopt for GNU.
++   NOTE: getopt is now part of the C library, so if you don't know what
++   "Keep this file name-space clean" means, talk to drepper@gnu.org
++   before changing it!
++   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
++   	Free Software Foundation, Inc.
++   This file is part of the GNU C Library.
++
++   The GNU C Library is free software; you can redistribute it and/or
++   modify it under the terms of the GNU Lesser General Public
++   License as published by the Free Software Foundation; either
++   version 2.1 of the License, or (at your option) any later version.
++
++   The GNU C Library is distributed in the hope that it will be useful,
++   but WITHOUT ANY WARRANTY; without even the implied warranty of
++   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++   Lesser General Public License for more details.
++
++   You should have received a copy of the GNU Lesser General Public
++   License along with the GNU C Library; if not, write to the Free
++   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
++   02111-1307 USA.  */
++
++/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
++   Ditto for AIX 3.2 and <stdlib.h>.  */
++#ifndef _NO_PROTO
++# define _NO_PROTO
++#endif
++
++#ifdef HAVE_CONFIG_H
++# include <config.h>
++#endif
++
++#if !defined __STDC__ || !__STDC__
++/* This is a separate conditional since some stdc systems
++   reject `defined (const)'.  */
++# ifndef const
++#  define const
++# endif
++#endif
++
++#include <stdio.h>
++
++/* Comment out all this code if we are using the GNU C Library, and are not
++   actually compiling the library itself.  This code is part of the GNU C
++   Library, but also included in many other GNU distributions.  Compiling
++   and linking in this code is a waste when using the GNU C library
++   (especially if it is a shared library).  Rather than having every GNU
++   program understand `configure --with-gnu-libc' and omit the object files,
++   it is simpler to just do this in the source for each such file.  */
++
++#define GETOPT_INTERFACE_VERSION 2
++#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
++# include <gnu-versions.h>
++# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
++#  define ELIDE_CODE
++# endif
++#endif
++
++#ifndef ELIDE_CODE
++
++
++/* This needs to come after some library #include
++   to get __GNU_LIBRARY__ defined.  */
++#ifdef	__GNU_LIBRARY__
++/* Don't include stdlib.h for non-GNU C libraries because some of them
++   contain conflicting prototypes for getopt.  */
++# include <stdlib.h>
++# include <unistd.h>
++#endif	/* GNU C library.  */
++
++#ifdef VMS
++# include <unixlib.h>
++# if HAVE_STRING_H - 0
++#  include <string.h>
++# endif
++#endif
++
++#ifndef _
++/* This is for other GNU distributions with internationalized messages.  */
++# if defined HAVE_LIBINTL_H || defined _LIBC
++#  include <libintl.h>
++#  ifndef _
++#   define _(msgid)	gettext (msgid)
++#  endif
++# else
++#  define _(msgid)	(msgid)
++# endif
++#endif
++
++/* This version of `getopt' appears to the caller like standard Unix `getopt'
++   but it behaves differently for the user, since it allows the user
++   to intersperse the options with the other arguments.
++
++   As `getopt' works, it permutes the elements of ARGV so that,
++   when it is done, all the options precede everything else.  Thus
++   all application programs are extended to handle flexible argument order.
++
++   Setting the environment variable POSIXLY_CORRECT disables permutation.
++   Then the behavior is completely standard.
++
++   GNU application programs can use a third alternative mode in which
++   they can distinguish the relative order of options and other arguments.  */
++
++#include "getopt.h"
++
++/* For communication from `getopt' to the caller.
++   When `getopt' finds an option that takes an argument,
++   the argument value is returned here.
++   Also, when `ordering' is RETURN_IN_ORDER,
++   each non-option ARGV-element is returned here.  */
++
++char *optarg;
++
++/* Index in ARGV of the next element to be scanned.
++   This is used for communication to and from the caller
++   and for communication between successive calls to `getopt'.
++
++   On entry to `getopt', zero means this is the first call; initialize.
++
++   When `getopt' returns -1, this is the index of the first of the
++   non-option elements that the caller should itself scan.
++
++   Otherwise, `optind' communicates from one call to the next
++   how much of ARGV has been scanned so far.  */
++
++/* 1003.2 says this must be 1 before any call.  */
++int optind = 1;
++
++/* Formerly, initialization of getopt depended on optind==0, which
++   causes problems with re-calling getopt as programs generally don't
++   know that. */
++
++int __getopt_initialized;
++
++/* The next char to be scanned in the option-element
++   in which the last option character we returned was found.
++   This allows us to pick up the scan where we left off.
++
++   If this is zero, or a null string, it means resume the scan
++   by advancing to the next ARGV-element.  */
++
++static char *nextchar;
++
++/* Callers store zero here to inhibit the error message
++   for unrecognized options.  */
++
++int opterr = 1;
++
++/* Set to an option character which was unrecognized.
++   This must be initialized on some systems to avoid linking in the
++   system's own getopt implementation.  */
++
++int optopt = '?';
++
++/* Describe how to deal with options that follow non-option ARGV-elements.
++
++   If the caller did not specify anything,
++   the default is REQUIRE_ORDER if the environment variable
++   POSIXLY_CORRECT is defined, PERMUTE otherwise.
++
++   REQUIRE_ORDER means don't recognize them as options;
++   stop option processing when the first non-option is seen.
++   This is what Unix does.
++   This mode of operation is selected by either setting the environment
++   variable POSIXLY_CORRECT, or using `+' as the first character
++   of the list of option characters.
++
++   PERMUTE is the default.  We permute the contents of ARGV as we scan,
++   so that eventually all the non-options are at the end.  This allows options
++   to be given in any order, even with programs that were not written to
++   expect this.
++
++   RETURN_IN_ORDER is an option available to programs that were written
++   to expect options and other ARGV-elements in any order and that care about
++   the ordering of the two.  We describe each non-option ARGV-element
++   as if it were the argument of an option with character code 1.
++   Using `-' as the first character of the list of option characters
++   selects this mode of operation.
++
++   The special argument `--' forces an end of option-scanning regardless
++   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
++   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
++
++static enum
++{
++  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
++} ordering;
++
++/* Value of POSIXLY_CORRECT environment variable.  */
++static char *posixly_correct;
++
++#ifdef	__GNU_LIBRARY__
++/* We want to avoid inclusion of string.h with non-GNU libraries
++   because there are many ways it can cause trouble.
++   On some systems, it contains special magic macros that don't work
++   in GCC.  */
++# include <string.h>
++# define my_index	strchr
+ #else
+-# define __UNCONST(x) ((char*)(x)) 
+-# define getprogname() (nargv[0])
+-# define _DIAGASSERT(x) assert((x))
++
++# if HAVE_STRING_H
++#  include <string.h>
++# else
++#  include <strings.h>
++# endif
++
++/* Avoid depending on library functions or files
++   whose names are inconsistent.  */
++
++#ifndef getenv
++extern char *getenv ();
+ #endif
+ 
+-#ifdef _FREETDS_LIBRARY_SOURCE
+-# include "tds_sysdep_private.h"
+-#endif /* _FREETDS_LIBRARY_SOURCE */
++static char *
++my_index (str, chr)
++     const char *str;
++     int chr;
++{
++  while (*str)
++    {
++      if (*str == chr)
++	return (char *) str;
++      str++;
++    }
++  return 0;
++}
++
++/* If using GCC, we can safely declare strlen this way.
++   If not using GCC, it is ok not to declare it.  */
++#ifdef __GNUC__
++/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
++   That was relevant to code that was here before.  */
++# if (!defined __STDC__ || !__STDC__) && !defined strlen
++/* gcc with -traditional declares the built-in strlen to return int,
++   and has done so at least since version 2.4.5. -- rms.  */
++extern int strlen (const char *);
++# endif /* not __STDC__ */
++#endif /* __GNUC__ */
++
++#endif /* not __GNU_LIBRARY__ */
++
++/* Handle permutation of arguments.  */
++
++/* Describe the part of ARGV that contains non-options that have
++   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
++   `last_nonopt' is the index after the last of them.  */
++
++static int first_nonopt;
++static int last_nonopt;
++
++#ifdef _LIBC
++/* Stored original parameters.
++   XXX This is no good solution.  We should rather copy the args so
++   that we can compare them later.  But we must not use malloc(3).  */
++extern int __libc_argc;
++extern char **__libc_argv;
++
++/* Bash 2.0 gives us an environment variable containing flags
++   indicating ARGV elements that should not be considered arguments.  */
+ 
+-#if defined(LIBC_SCCS) && !defined(lint)
+-# if 0
+-  static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
++# ifdef USE_NONOPTION_FLAGS
++/* Defined in getopt_init.c  */
++extern char *__getopt_nonoption_flags;
++
++static int nonoption_flags_max_len;
++static int nonoption_flags_len;
++# endif
++
++# ifdef USE_NONOPTION_FLAGS
++#  define SWAP_FLAGS(ch1, ch2) \
++  if (nonoption_flags_len > 0)						      \
++    {									      \
++      char __tmp = __getopt_nonoption_flags[ch1];			      \
++      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
++      __getopt_nonoption_flags[ch2] = __tmp;				      \
++    }
+ # else
+-  __RCSID("$NetBSD: getopt.c,v 1.27 2005/11/29 03:12:00 christos Exp $");
++#  define SWAP_FLAGS(ch1, ch2)
+ # endif
+-#else 
+- TDS_RCSID(var, "$Id: getopt.c,v 1.1 2010/01/12 15:43:17 jklowden Exp $");
+-#endif /* LIBC_SCCS and not lint */
++#else	/* !_LIBC */
++# define SWAP_FLAGS(ch1, ch2)
++#endif	/* _LIBC */
+ 
+-#if !defined(_WIN32)
+-# include "namespace.h"
++/* Exchange two adjacent subsequences of ARGV.
++   One subsequence is elements [first_nonopt,last_nonopt)
++   which contains all the non-options that have been skipped so far.
++   The other is elements [last_nonopt,optind), which contains all
++   the options processed since those non-options were skipped.
++
++   `first_nonopt' and `last_nonopt' are relocated so that they describe
++   the new indices of the non-options in ARGV after they are moved.  */
++
++#if defined __STDC__ && __STDC__
++static void exchange (char **);
+ #endif
+ 
+-#include <assert.h>
+-#include <errno.h>
+-#include <stdio.h>
+-#include <stdlib.h>
+-#include <string.h>
+-#if !defined(_WIN32)
+-# include <unistd.h>
++static void
++exchange (argv)
++     char **argv;
++{
++  int bottom = first_nonopt;
++  int middle = last_nonopt;
++  int top = optind;
++  char *tem;
++
++  /* Exchange the shorter segment with the far end of the longer segment.
++     That puts the shorter segment into the right place.
++     It leaves the longer segment in the right place overall,
++     but it consists of two parts that need to be swapped next.  */
++
++#if defined _LIBC && defined USE_NONOPTION_FLAGS
++  /* First make sure the handling of the `__getopt_nonoption_flags'
++     string can work normally.  Our top argument must be in the range
++     of the string.  */
++  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
++    {
++      /* We must extend the array.  The user plays games with us and
++	 presents new arguments.  */
++      char *new_str = malloc (top + 1);
++      if (new_str == NULL)
++	nonoption_flags_len = nonoption_flags_max_len = 0;
++      else
++	{
++	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
++			     nonoption_flags_max_len),
++		  '\0', top + 1 - nonoption_flags_max_len);
++	  nonoption_flags_max_len = top + 1;
++	  __getopt_nonoption_flags = new_str;
++	}
++    }
+ #endif
+ 
+-#ifdef __weak_alias
+-__weak_alias(getopt,_getopt)
++  while (top > middle && middle > bottom)
++    {
++      if (top - middle > middle - bottom)
++	{
++	  /* Bottom segment is the short one.  */
++	  int len = middle - bottom;
++	  register int i;
++
++	  /* Swap it with the top part of the top segment.  */
++	  for (i = 0; i < len; i++)
++	    {
++	      tem = argv[bottom + i];
++	      argv[bottom + i] = argv[top - (middle - bottom) + i];
++	      argv[top - (middle - bottom) + i] = tem;
++	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
++	    }
++	  /* Exclude the moved bottom segment from further swapping.  */
++	  top -= len;
++	}
++      else
++	{
++	  /* Top segment is the short one.  */
++	  int len = top - middle;
++	  register int i;
++
++	  /* Swap it with the bottom part of the bottom segment.  */
++	  for (i = 0; i < len; i++)
++	    {
++	      tem = argv[bottom + i];
++	      argv[bottom + i] = argv[middle + i];
++	      argv[middle + i] = tem;
++	      SWAP_FLAGS (bottom + i, middle + i);
++	    }
++	  /* Exclude the moved top segment from further swapping.  */
++	  bottom += len;
++	}
++    }
++
++  /* Update records for the slots the non-options now occupy.  */
++
++  first_nonopt += (optind - last_nonopt);
++  last_nonopt = optind;
++}
++
++/* Initialize the internal data when the first call is made.  */
++
++#if defined __STDC__ && __STDC__
++static const char *_getopt_initialize (int, char *const *, const char *);
+ #endif
++static const char *
++_getopt_initialize (argc, argv, optstring)
++     int argc;
++     char *const *argv;
++     const char *optstring;
++{
++  /* Start processing options with ARGV-element 1 (since ARGV-element 0
++     is the program name); the sequence of previously skipped
++     non-option ARGV-elements is empty.  */
++
++  first_nonopt = last_nonopt = optind;
+ 
+-int	opterr = 1,		/* if error message should be printed */
+-	optind = 1,		/* index into parent argv vector */
+-	optopt,			/* character checked for validity */
+-	optreset;		/* reset getopt */
+-char	*optarg;		/* argument associated with option */
++  nextchar = NULL;
+ 
+-#define	BADCH	(int)'?'
+-#define	BADARG	(int)':'
+-#define	EMSG	""
++  posixly_correct = getenv ("POSIXLY_CORRECT");
++
++  /* Determine how to handle the ordering of options and nonoptions.  */
++
++  if (optstring[0] == '-')
++    {
++      ordering = RETURN_IN_ORDER;
++      ++optstring;
++    }
++  else if (optstring[0] == '+')
++    {
++      ordering = REQUIRE_ORDER;
++      ++optstring;
++    }
++  else if (posixly_correct != NULL)
++    ordering = REQUIRE_ORDER;
++  else
++    ordering = PERMUTE;
++
++#if defined _LIBC && defined USE_NONOPTION_FLAGS
++  if (posixly_correct == NULL
++      && argc == __libc_argc && argv == __libc_argv)
++    {
++      if (nonoption_flags_max_len == 0)
++	{
++	  if (__getopt_nonoption_flags == NULL
++	      || __getopt_nonoption_flags[0] == '\0')
++	    nonoption_flags_max_len = -1;
++	  else
++	    {
++	      const char *orig_str = __getopt_nonoption_flags;
++	      int len = nonoption_flags_max_len = strlen (orig_str);
++	      if (nonoption_flags_max_len < argc)
++		nonoption_flags_max_len = argc;
++	      __getopt_nonoption_flags =
++		(char *) malloc (nonoption_flags_max_len);
++	      if (__getopt_nonoption_flags == NULL)
++		nonoption_flags_max_len = -1;
++	      else
++		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
++			'\0', nonoption_flags_max_len - len);
++	    }
++	}
++      nonoption_flags_len = nonoption_flags_max_len;
++    }
++  else
++    nonoption_flags_len = 0;
++#endif
++
++  return optstring;
++}
++
++/* Scan elements of ARGV (whose length is ARGC) for option characters
++   given in OPTSTRING.
++
++   If an element of ARGV starts with '-', and is not exactly "-" or "--",
++   then it is an option element.  The characters of this element
++   (aside from the initial '-') are option characters.  If `getopt'
++   is called repeatedly, it returns successively each of the option characters
++   from each of the option elements.
++
++   If `getopt' finds another option character, it returns that character,
++   updating `optind' and `nextchar' so that the next call to `getopt' can
++   resume the scan with the following option character or ARGV-element.
++
++   If there are no more option characters, `getopt' returns -1.
++   Then `optind' is the index in ARGV of the first ARGV-element
++   that is not an option.  (The ARGV-elements have been permuted
++   so that those that are not options now come last.)
++
++   OPTSTRING is a string containing the legitimate option characters.
++   If an option character is seen that is not listed in OPTSTRING,
++   return '?' after printing an error message.  If you set `opterr' to
++   zero, the error message is suppressed but we still return '?'.
++
++   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
++   so the following text in the same ARGV-element, or the text of the following
++   ARGV-element, is returned in `optarg'.  Two colons mean an option that
++   wants an optional arg; if there is text in the current ARGV-element,
++   it is returned in `optarg', otherwise `optarg' is set to zero.
++
++   If OPTSTRING starts with `-' or `+', it requests different methods of
++   handling the non-option ARGV-elements.
++   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
++
++   Long-named options begin with `--' instead of `-'.
++   Their names may be abbreviated as long as the abbreviation is unique
++   or is an exact match for some defined option.  If they have an
++   argument, it follows the option name in the same ARGV-element, separated
++   from the option name by a `=', or else the in next ARGV-element.
++   When `getopt' finds a long-named option, it returns 0 if that option's
++   `flag' field is nonzero, the value of the option's `val' field
++   if the `flag' field is zero.
++
++   The elements of ARGV aren't really const, because we permute them.
++   But we pretend they're const in the prototype to be compatible
++   with other systems.
++
++   LONGOPTS is a vector of `struct option' terminated by an
++   element containing a name which is zero.
++
++   LONGIND returns the index in LONGOPT of the long-named option found.
++   It is only valid when a long-named option has been found by the most
++   recent call.
++
++   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
++   long-named options.  */
+ 
+-/*
+- * getopt --
+- *	Parse argc/argv argument vector.
+- */
+ int
+-getopt(nargc, nargv, ostr)
+-	int nargc;
+-	char * const nargv[];
+-	const char *ostr;
++_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
++     int argc;
++     char *const *argv;
++     const char *optstring;
++     const struct option *longopts;
++     int *longind;
++     int long_only;
+ {
+-	static const char *place = EMSG;	/* option letter processing */
+-	char *oli;				/* option letter list index */
+-
+-	_DIAGASSERT(nargv != NULL);
+-	_DIAGASSERT(ostr != NULL);
+-
+-	if (optreset || *place == 0) {		/* update scanning pointer */
+-		optreset = 0;
+-		place = nargv[optind];
+-		if (optind >= nargc || *place++ != '-') {
+-			/* Argument is absent or is not an option */
+-			place = EMSG;
+-			return (-1);
+-		}
+-		optopt = *place++;
+-		if (optopt == '-' && *place == 0) {
+-			/* "--" => end of options */
+-			++optind;
+-			place = EMSG;
+-			return (-1);
++  int print_errors = opterr;
++  if (optstring[0] == ':')
++    print_errors = 0;
++
++  if (argc < 1)
++    return -1;
++
++  optarg = NULL;
++
++  if (optind == 0 || !__getopt_initialized)
++    {
++      if (optind == 0)
++	optind = 1;	/* Don't scan ARGV[0], the program name.  */
++      optstring = _getopt_initialize (argc, argv, optstring);
++      __getopt_initialized = 1;
++    }
++
++  /* Test whether ARGV[optind] points to a non-option argument.
++     Either it does not have option syntax, or there is an environment flag
++     from the shell indicating it is not an option.  The later information
++     is only used when the used in the GNU libc.  */
++#if defined _LIBC && defined USE_NONOPTION_FLAGS
++# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
++		      || (optind < nonoption_flags_len			      \
++			  && __getopt_nonoption_flags[optind] == '1'))
++#else
++# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
++#endif
++
++  if (nextchar == NULL || *nextchar == '\0')
++    {
++      /* Advance to the next ARGV-element.  */
++
++      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
++	 moved back by the user (who may also have changed the arguments).  */
++      if (last_nonopt > optind)
++	last_nonopt = optind;
++      if (first_nonopt > optind)
++	first_nonopt = optind;
++
++      if (ordering == PERMUTE)
++	{
++	  /* If we have just processed some options following some non-options,
++	     exchange them so that the options come first.  */
++
++	  if (first_nonopt != last_nonopt && last_nonopt != optind)
++	    exchange ((char **) argv);
++	  else if (last_nonopt != optind)
++	    first_nonopt = optind;
++
++	  /* Skip any additional non-options
++	     and extend the range of non-options previously skipped.  */
++
++	  while (optind < argc && NONOPTION_P)
++	    optind++;
++	  last_nonopt = optind;
++	}
++
++      /* The special ARGV-element `--' means premature end of options.
++	 Skip it like a null option,
++	 then exchange with previous non-options as if it were an option,
++	 then skip everything else like a non-option.  */
++
++      if (optind != argc && !strcmp (argv[optind], "--"))
++	{
++	  optind++;
++
++	  if (first_nonopt != last_nonopt && last_nonopt != optind)
++	    exchange ((char **) argv);
++	  else if (first_nonopt == last_nonopt)
++	    first_nonopt = optind;
++	  last_nonopt = argc;
++
++	  optind = argc;
++	}
++
++      /* If we have done all the ARGV-elements, stop the scan
++	 and back over any non-options that we skipped and permuted.  */
++
++      if (optind == argc)
++	{
++	  /* Set the next-arg-index to point at the non-options
++	     that we previously skipped, so the caller will digest them.  */
++	  if (first_nonopt != last_nonopt)
++	    optind = first_nonopt;
++	  return -1;
++	}
++
++      /* If we have come to a non-option and did not permute it,
++	 either stop the scan or describe it to the caller and pass it by.  */
++
++      if (NONOPTION_P)
++	{
++	  if (ordering == REQUIRE_ORDER)
++	    return -1;
++	  optarg = argv[optind++];
++	  return 1;
++	}
++
++      /* We have found another option-ARGV-element.
++	 Skip the initial punctuation.  */
++
++      nextchar = (argv[optind] + 1
++		  + (longopts != NULL && argv[optind][1] == '-'));
++    }
++
++  /* Decode the current option-ARGV-element.  */
++
++  /* Check whether the ARGV-element is a long option.
++
++     If long_only and the ARGV-element has the form "-f", where f is
++     a valid short option, don't consider it an abbreviated form of
++     a long option that starts with f.  Otherwise there would be no
++     way to give the -f short option.
++
++     On the other hand, if there's a long option "fubar" and
++     the ARGV-element is "-fu", do consider that an abbreviation of
++     the long option, just like "--fu", and not "-f" with arg "u".
++
++     This distinction seems to be the most useful approach.  */
++
++  if (longopts != NULL
++      && (argv[optind][1] == '-'
++	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
++    {
++      char *nameend;
++      const struct option *p;
++      const struct option *pfound = NULL;
++      int exact = 0;
++      int ambig = 0;
++      int indfound = -1;
++      int option_index;
++
++      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
++	/* Do nothing.  */ ;
++
++      /* Test all long options for either exact match
++	 or abbreviated matches.  */
++      for (p = longopts, option_index = 0; p->name; p++, option_index++)
++	if (!strncmp (p->name, nextchar, nameend - nextchar))
++	  {
++	    if ((unsigned int) (nameend - nextchar)
++		== (unsigned int) strlen (p->name))
++	      {
++		/* Exact match found.  */
++		pfound = p;
++		indfound = option_index;
++		exact = 1;
++		break;
++	      }
++	    else if (pfound == NULL)
++	      {
++		/* First nonexact match found.  */
++		pfound = p;
++		indfound = option_index;
++	      }
++	    else if (long_only
++		     || pfound->has_arg != p->has_arg
++		     || pfound->flag != p->flag
++		     || pfound->val != p->val)
++	      /* Second or later nonexact match found.  */
++	      ambig = 1;
++	  }
++
++      if (ambig && !exact)
++	{
++	  if (print_errors)
++	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
++		     argv[0], argv[optind]);
++	  nextchar += strlen (nextchar);
++	  optind++;
++	  optopt = 0;
++	  return '?';
++	}
++
++      if (pfound != NULL)
++	{
++	  option_index = indfound;
++	  optind++;
++	  if (*nameend)
++	    {
++	      /* Don't test has_arg with >, because some C compilers don't
++		 allow it to be used on enums.  */
++	      if (pfound->has_arg)
++		optarg = nameend + 1;
++	      else
++		{
++		  if (print_errors)
++		    {
++		      if (argv[optind - 1][1] == '-')
++			/* --option */
++			fprintf (stderr,
++				 _("%s: option `--%s' doesn't allow an argument\n"),
++				 argv[0], pfound->name);
++		      else
++			/* +option or -option */
++			fprintf (stderr,
++				 _("%s: option `%c%s' doesn't allow an argument\n"),
++				 argv[0], argv[optind - 1][0], pfound->name);
++		    }
++
++		  nextchar += strlen (nextchar);
++
++		  optopt = pfound->val;
++		  return '?';
+ 		}
+-		if (optopt == 0) {
+-			/* Solitary '-', treat as a '-' option
+-			   if the program (eg su) is looking for it. */
+-			place = EMSG;
+-			if (strchr(ostr, '-') == NULL)
+-				return -1;
+-			optopt = '-';
++	    }
++	  else if (pfound->has_arg == 1)
++	    {
++	      if (optind < argc)
++		optarg = argv[optind++];
++	      else
++		{
++		  if (print_errors)
++		    fprintf (stderr,
++			   _("%s: option `%s' requires an argument\n"),
++			   argv[0], argv[optind - 1]);
++		  nextchar += strlen (nextchar);
++		  optopt = pfound->val;
++		  return optstring[0] == ':' ? ':' : '?';
+ 		}
+-	} else
+-		optopt = *place++;
+-
+-	/* See if option letter is one the caller wanted... */
+-	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
+-		if (*place == 0)
+-			++optind;
+-		if (opterr && *ostr != ':')
+-			(void)fprintf(stderr,
+-			    "%s: unknown option -- %c\n", getprogname(),
+-			    optopt);
+-		return (BADCH);
++	    }
++	  nextchar += strlen (nextchar);
++	  if (longind != NULL)
++	    *longind = option_index;
++	  if (pfound->flag)
++	    {
++	      *(pfound->flag) = pfound->val;
++	      return 0;
++	    }
++	  return pfound->val;
++	}
++
++      /* Can't find it as a long option.  If this is not getopt_long_only,
++	 or the option starts with '--' or is not a valid short
++	 option, then it's an error.
++	 Otherwise interpret it as a short option.  */
++      if (!long_only || argv[optind][1] == '-'
++	  || my_index (optstring, *nextchar) == NULL)
++	{
++	  if (print_errors)
++	    {
++	      if (argv[optind][1] == '-')
++		/* --option */
++		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
++			 argv[0], nextchar);
++	      else
++		/* +option or -option */
++		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
++			 argv[0], argv[optind][0], nextchar);
++	    }
++	  nextchar = (char *) "";
++	  optind++;
++	  optopt = 0;
++	  return '?';
+ 	}
++    }
++
++  /* Look at and handle the next short option-character.  */
++
++  {
++    char c = *nextchar++;
++    char *temp = my_index (optstring, c);
++
++    /* Increment `optind' when we start to process its last character.  */
++    if (*nextchar == '\0')
++      ++optind;
+ 
+-	/* Does this option need an argument? */
+-	if (oli[1] != ':') {
+-		/* don't need argument */
+-		optarg = NULL;
+-		if (*place == 0)
+-			++optind;
+-	} else {
+-		/* Option-argument is either the rest of this argument or the
+-		   entire next argument. */
+-		if (*place)
+-			optarg = __UNCONST(place);
+-		else if (nargc > ++optind)
+-			optarg = nargv[optind];
+-		else {
+-			/* option-argument absent */
+-			place = EMSG;
+-			if (*ostr == ':')
+-				return (BADARG);
+-			if (opterr)
+-				(void)fprintf(stderr,
+-				    "%s: option requires an argument -- %c\n",
+-				    getprogname(), optopt);
+-			return (BADCH);
++    if (temp == NULL || c == ':')
++      {
++	if (print_errors)
++	  {
++	    if (posixly_correct)
++	      /* 1003.2 specifies the format of this message.  */
++	      fprintf (stderr, _("%s: illegal option -- %c\n"),
++		       argv[0], c);
++	    else
++	      fprintf (stderr, _("%s: invalid option -- %c\n"),
++		       argv[0], c);
++	  }
++	optopt = c;
++	return '?';
++      }
++    /* Convenience. Treat POSIX -W foo same as long option --foo */
++    if (temp[0] == 'W' && temp[1] == ';')
++      {
++	char *nameend;
++	const struct option *p;
++	const struct option *pfound = NULL;
++	int exact = 0;
++	int ambig = 0;
++	int indfound = 0;
++	int option_index;
++
++	/* This is an option that requires an argument.  */
++	if (*nextchar != '\0')
++	  {
++	    optarg = nextchar;
++	    /* If we end this ARGV-element by taking the rest as an arg,
++	       we must advance to the next element now.  */
++	    optind++;
++	  }
++	else if (optind == argc)
++	  {
++	    if (print_errors)
++	      {
++		/* 1003.2 specifies the format of this message.  */
++		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
++			 argv[0], c);
++	      }
++	    optopt = c;
++	    if (optstring[0] == ':')
++	      c = ':';
++	    else
++	      c = '?';
++	    return c;
++	  }
++	else
++	  /* We already incremented `optind' once;
++	     increment it again when taking next ARGV-elt as argument.  */
++	  optarg = argv[optind++];
++
++	/* optarg is now the argument, see if it's in the
++	   table of longopts.  */
++
++	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
++	  /* Do nothing.  */ ;
++
++	/* Test all long options for either exact match
++	   or abbreviated matches.  */
++	for (p = longopts, option_index = 0; p->name; p++, option_index++)
++	  if (!strncmp (p->name, nextchar, nameend - nextchar))
++	    {
++	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
++		{
++		  /* Exact match found.  */
++		  pfound = p;
++		  indfound = option_index;
++		  exact = 1;
++		  break;
++		}
++	      else if (pfound == NULL)
++		{
++		  /* First nonexact match found.  */
++		  pfound = p;
++		  indfound = option_index;
+ 		}
+-		place = EMSG;
+-		++optind;
++	      else
++		/* Second or later nonexact match found.  */
++		ambig = 1;
++	    }
++	if (ambig && !exact)
++	  {
++	    if (print_errors)
++	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
++		       argv[0], argv[optind]);
++	    nextchar += strlen (nextchar);
++	    optind++;
++	    return '?';
++	  }
++	if (pfound != NULL)
++	  {
++	    option_index = indfound;
++	    if (*nameend)
++	      {
++		/* Don't test has_arg with >, because some C compilers don't
++		   allow it to be used on enums.  */
++		if (pfound->has_arg)
++		  optarg = nameend + 1;
++		else
++		  {
++		    if (print_errors)
++		      fprintf (stderr, _("\
++%s: option `-W %s' doesn't allow an argument\n"),
++			       argv[0], pfound->name);
++
++		    nextchar += strlen (nextchar);
++		    return '?';
++		  }
++	      }
++	    else if (pfound->has_arg == 1)
++	      {
++		if (optind < argc)
++		  optarg = argv[optind++];
++		else
++		  {
++		    if (print_errors)
++		      fprintf (stderr,
++			       _("%s: option `%s' requires an argument\n"),
++			       argv[0], argv[optind - 1]);
++		    nextchar += strlen (nextchar);
++		    return optstring[0] == ':' ? ':' : '?';
++		  }
++	      }
++	    nextchar += strlen (nextchar);
++	    if (longind != NULL)
++	      *longind = option_index;
++	    if (pfound->flag)
++	      {
++		*(pfound->flag) = pfound->val;
++		return 0;
++	      }
++	    return pfound->val;
++	  }
++	  nextchar = NULL;
++	  return 'W';	/* Let the application handle it.   */
++      }
++    if (temp[1] == ':')
++      {
++	if (temp[2] == ':')
++	  {
++	    /* This is an option that accepts an argument optionally.  */
++	    if (*nextchar != '\0')
++	      {
++		optarg = nextchar;
++		optind++;
++	      }
++	    else
++	      optarg = NULL;
++	    nextchar = NULL;
++	  }
++	else
++	  {
++	    /* This is an option that requires an argument.  */
++	    if (*nextchar != '\0')
++	      {
++		optarg = nextchar;
++		/* If we end this ARGV-element by taking the rest as an arg,
++		   we must advance to the next element now.  */
++		optind++;
++	      }
++	    else if (optind == argc)
++	      {
++		if (print_errors)
++		  {
++		    /* 1003.2 specifies the format of this message.  */
++		    fprintf (stderr,
++			     _("%s: option requires an argument -- %c\n"),
++			     argv[0], c);
++		  }
++		optopt = c;
++		if (optstring[0] == ':')
++		  c = ':';
++		else
++		  c = '?';
++	      }
++	    else
++	      /* We already incremented `optind' once;
++		 increment it again when taking next ARGV-elt as argument.  */
++	      optarg = argv[optind++];
++	    nextchar = NULL;
++	  }
++      }
++    return c;
++  }
++}
++
++int
++getopt (argc, argv, optstring)
++     int argc;
++     char *const *argv;
++     const char *optstring;
++{
++  return _getopt_internal (argc, argv, optstring,
++			   (const struct option *) 0,
++			   (int *) 0,
++			   0);
++}
++
++#endif	/* Not ELIDE_CODE.  */
++
++#ifdef TEST
++
++/* Compile with -DTEST to make an executable for use in testing
++   the above definition of `getopt'.  */
++
++int
++main (argc, argv)
++     int argc;
++     char **argv;
++{
++  int c;
++  int digit_optind = 0;
++
++  while (1)
++    {
++      int this_option_optind = optind ? optind : 1;
++
++      c = getopt (argc, argv, "abc:d:0123456789");
++      if (c == -1)
++	break;
++
++      switch (c)
++	{
++	case '0':
++	case '1':
++	case '2':
++	case '3':
++	case '4':
++	case '5':
++	case '6':
++	case '7':
++	case '8':
++	case '9':
++	  if (digit_optind != 0 && digit_optind != this_option_optind)
++	    printf ("digits occur in two different argv-elements.\n");
++	  digit_optind = this_option_optind;
++	  printf ("option %c\n", c);
++	  break;
++
++	case 'a':
++	  printf ("option a\n");
++	  break;
++
++	case 'b':
++	  printf ("option b\n");
++	  break;
++
++	case 'c':
++	  printf ("option c with value `%s'\n", optarg);
++	  break;
++
++	case '?':
++	  break;
++
++	default:
++	  printf ("?? getopt returned character code 0%o ??\n", c);
+ 	}
+-	return (optopt);			/* return option letter */
++    }
++
++  if (optind < argc)
++    {
++      printf ("non-option ARGV-elements: ");
++      while (optind < argc)
++	printf ("%s ", argv[optind++]);
++      printf ("\n");
++    }
++
++  exit (0);
+ }
++
++#endif /* TEST */
+
+commit bcfd62c0d6c8697421b31ad6fc4c2685fe75afe3
+Author: jklowden <jklowden>
+Date:   Fri Feb 5 22:09:30 2010 +0000
+
+    use SQLGetDescField for nchar buffer size.
+
+diff --git a/ChangeLog b/ChangeLog
+index ec71d0b..33a2a29 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Feb  5 17:06:14 EST 2010	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqlodbc.c use SQLGetDescField for nchar buffer size.
++
+ Tue Feb  2 10:47:26 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/getopt.c: replaced getopt with LGPL version
+ 
+@@ -2283,4 +2286,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2981 2010/02/02 09:48:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2982 2010/02/05 22:09:30 jklowden Exp $
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index 63cd677..d9cd56a 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.12 2008/11/15 09:57:06 freddy77 Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.13 2010/02/05 22:09:31 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -69,6 +69,7 @@ struct METADATA
+ 	char *name, *format_string;
+ 	const char *source;
+ 	SQLSMALLINT type;
++	SQLINTEGER nchars;
+ 	SQLULEN size, width;
+ };
+ struct DATA { char *buffer; SQLLEN len; int status; };
+@@ -462,6 +463,20 @@ prtype(SQLSMALLINT type)
+ 	return buffer;
+ }
+ 
++#define is_character_data(x)   (x==SQL_CHAR	    || \
++				x==SQL_VARCHAR	    || \
++				x==SQL_LONGVARCHAR  || \
++				x==SQL_WCHAR	    || \
++				x==SQL_WVARCHAR     || \
++				x==SQL_WLONGVARCHAR)
++
++static SQLLEN 
++bufsize(const struct METADATA *meta)
++{
++	assert(meta);
++	return meta->size > meta->width? meta->size : meta->width;
++}
++
+ static void
+ print_results(SQLHSTMT hStmt) 
+ {
+@@ -509,8 +524,10 @@ print_results(SQLHSTMT hStmt)
+ 		 */
+ 
+ 		fprintf(options.verbose, "Metadata\n");
+-		fprintf(options.verbose, "%-6s  %-30s  %-10s  %-18s  %-6s  %-6s  \n", "col", "name", "type value", "type name", "size", "varies");
+-		fprintf(options.verbose, "%.6s  %.30s  %.10s  %.18s  %.6s  %.6s  \n", dashes, dashes, dashes, dashes, dashes, dashes);
++		fprintf(options.verbose, "%-6s  %-30s  %-10s  %-18s  %-6s  %-6s  \n", 
++					 "col", "name", "type value", "type name", "size", "varies");
++		fprintf(options.verbose, "%.6s  %.30s  %.10s  %.18s  %.6s  %.6s  \n", 
++					 dashes, dashes, dashes, dashes, dashes, dashes);
+ 		for (c=0; c < ncols; c++) {
+ 			/* Get and print the metadata.  Optional: get only what you need. */
+ 			SQLCHAR name[512];
+@@ -526,6 +543,29 @@ print_results(SQLHSTMT hStmt)
+ 			name[namelen] = '\0';
+ 			metadata[c].name = strdup((char *) name);
+ 			metadata[c].width = (ndigits > metadata[c].size)? ndigits : metadata[c].size;
++			
++			if (is_character_data(metadata[c].type)) {
++				SQLHDESC hDesc;
++				SQLINTEGER buflen;
++				
++				metadata[c].nchars = metadata[c].size;
++				
++				if ((erc = SQLAllocHandle(SQL_HANDLE_DESC, hStmt, &hDesc)) != SQL_SUCCESS) {
++					odbc_perror(hStmt, erc, "SQLAllocHandle", "failed");
++					exit(EXIT_FAILURE);
++				} 
++				if ((erc = SQLGetDescField(hDesc, c+1, SQL_DESC_OCTET_LENGTH, 
++								&metadata[c].size, sizeof(metadata[c].size), 
++								&buflen)) != SQL_SUCCESS) {
++					odbc_perror(hStmt, erc, "SQLGetDescField", "failed");
++					exit(EXIT_FAILURE);
++				} 
++				
++				if ((erc = SQLFreeHandle(SQL_HANDLE_DESC, hStmt)) != SQL_SUCCESS) {
++					odbc_perror(hStmt, erc, "SQLFreeHandle", "failed");
++					exit(EXIT_FAILURE);
++				} 
++			}
+ 
+ 			fprintf(options.verbose, "%6d  %30s  %10d  %18s  %6lu  %6d  \n", 
+ 				c+1, metadata[c].name, (int)metadata[c].type, prtype(metadata[c].type), 
+@@ -561,11 +601,11 @@ print_results(SQLHSTMT hStmt)
+ 			 * inaccesible to the application.  
+ 			 */
+ 
+-			data[c].buffer = calloc(1, metadata[c].width);
++			data[c].buffer = calloc(1, bufsize(&metadata[c]));
+ 			assert(data[c].buffer);
+ 
+ 			if ((erc = SQLBindCol(hStmt, c+1, SQL_C_CHAR, (SQLPOINTER)data[c].buffer, 
+-						metadata[c].width, &data[c].len)) != SQL_SUCCESS){
++						bufsize(&metadata[c]), &data[c].len)) != SQL_SUCCESS){
+ 				odbc_perror(hStmt, erc, "SQLBindCol", "failed");
+ 				exit(EXIT_FAILURE);
+ 			} 
+@@ -696,12 +736,6 @@ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+  * Build the column header format string, based on the column width. 
+  * This is just one solution to the question, "How wide should my columns be when I print them out?"
+  */
+-#define is_character_data(x)   (x==SQL_CHAR	    || \
+-				x==SQL_VARCHAR	    || \
+-				x==SQL_LONGVARCHAR  || \
+-				x==SQL_WCHAR	    || \
+-				x==SQL_WVARCHAR     || \
+-				x==SQL_WLONGVARCHAR)
+ static int
+ set_format_string(struct METADATA * meta, const char separator[])
+ {
+
+commit 53775f51fef8ef7111d9c1d0ee729937274015e3
+Author: freddy77 <freddy77>
+Date:   Sun Feb 7 00:33:54 2010 +0000
+
+    reverted getopt LGPL patch
+
+diff --git a/ChangeLog b/ChangeLog
+index 33a2a29..23588f3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Feb  7 01:33:47 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/getopt.c: reverted getopt LGPL patch
++
+ Fri Feb  5 17:06:14 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/bsqlodbc.c use SQLGetDescField for nchar buffer size.
+ 
+@@ -2286,4 +2289,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2982 2010/02/05 22:09:30 jklowden Exp $
++$Id: ChangeLog,v 1.2983 2010/02/07 00:33:54 freddy77 Exp $
+diff --git a/src/replacements/getopt.c b/src/replacements/getopt.c
+index 9bafa45..1958051 100644
+--- a/src/replacements/getopt.c
++++ b/src/replacements/getopt.c
+@@ -1,1055 +1,164 @@
+-/* Getopt for GNU.
+-   NOTE: getopt is now part of the C library, so if you don't know what
+-   "Keep this file name-space clean" means, talk to drepper@gnu.org
+-   before changing it!
+-   Copyright (C) 1987,88,89,90,91,92,93,94,95,96,98,99,2000,2001
+-   	Free Software Foundation, Inc.
+-   This file is part of the GNU C Library.
+-
+-   The GNU C Library is free software; you can redistribute it and/or
+-   modify it under the terms of the GNU Lesser General Public
+-   License as published by the Free Software Foundation; either
+-   version 2.1 of the License, or (at your option) any later version.
+-
+-   The GNU C Library is distributed in the hope that it will be useful,
+-   but WITHOUT ANY WARRANTY; without even the implied warranty of
+-   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+-   Lesser General Public License for more details.
+-
+-   You should have received a copy of the GNU Lesser General Public
+-   License along with the GNU C Library; if not, write to the Free
+-   Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+-   02111-1307 USA.  */
+-
+-/* This tells Alpha OSF/1 not to define a getopt prototype in <stdio.h>.
+-   Ditto for AIX 3.2 and <stdlib.h>.  */
+-#ifndef _NO_PROTO
+-# define _NO_PROTO
+-#endif
+-
+-#ifdef HAVE_CONFIG_H
+-# include <config.h>
+-#endif
+-
+-#if !defined __STDC__ || !__STDC__
+-/* This is a separate conditional since some stdc systems
+-   reject `defined (const)'.  */
+-# ifndef const
+-#  define const
+-# endif
+-#endif
+-
+-#include <stdio.h>
+-
+-/* Comment out all this code if we are using the GNU C Library, and are not
+-   actually compiling the library itself.  This code is part of the GNU C
+-   Library, but also included in many other GNU distributions.  Compiling
+-   and linking in this code is a waste when using the GNU C library
+-   (especially if it is a shared library).  Rather than having every GNU
+-   program understand `configure --with-gnu-libc' and omit the object files,
+-   it is simpler to just do this in the source for each such file.  */
+-
+-#define GETOPT_INTERFACE_VERSION 2
+-#if !defined _LIBC && defined __GLIBC__ && __GLIBC__ >= 2
+-# include <gnu-versions.h>
+-# if _GNU_GETOPT_INTERFACE_VERSION == GETOPT_INTERFACE_VERSION
+-#  define ELIDE_CODE
+-# endif
+-#endif
+-
+-#ifndef ELIDE_CODE
+-
+-
+-/* This needs to come after some library #include
+-   to get __GNU_LIBRARY__ defined.  */
+-#ifdef	__GNU_LIBRARY__
+-/* Don't include stdlib.h for non-GNU C libraries because some of them
+-   contain conflicting prototypes for getopt.  */
+-# include <stdlib.h>
+-# include <unistd.h>
+-#endif	/* GNU C library.  */
+-
+-#ifdef VMS
+-# include <unixlib.h>
+-# if HAVE_STRING_H - 0
+-#  include <string.h>
+-# endif
+-#endif
+-
+-#ifndef _
+-/* This is for other GNU distributions with internationalized messages.  */
+-# if defined HAVE_LIBINTL_H || defined _LIBC
+-#  include <libintl.h>
+-#  ifndef _
+-#   define _(msgid)	gettext (msgid)
+-#  endif
+-# else
+-#  define _(msgid)	(msgid)
+-# endif
+-#endif
+-
+-/* This version of `getopt' appears to the caller like standard Unix `getopt'
+-   but it behaves differently for the user, since it allows the user
+-   to intersperse the options with the other arguments.
+-
+-   As `getopt' works, it permutes the elements of ARGV so that,
+-   when it is done, all the options precede everything else.  Thus
+-   all application programs are extended to handle flexible argument order.
+-
+-   Setting the environment variable POSIXLY_CORRECT disables permutation.
+-   Then the behavior is completely standard.
+-
+-   GNU application programs can use a third alternative mode in which
+-   they can distinguish the relative order of options and other arguments.  */
+-
+-#include "getopt.h"
+-
+-/* For communication from `getopt' to the caller.
+-   When `getopt' finds an option that takes an argument,
+-   the argument value is returned here.
+-   Also, when `ordering' is RETURN_IN_ORDER,
+-   each non-option ARGV-element is returned here.  */
+-
+-char *optarg;
+-
+-/* Index in ARGV of the next element to be scanned.
+-   This is used for communication to and from the caller
+-   and for communication between successive calls to `getopt'.
+-
+-   On entry to `getopt', zero means this is the first call; initialize.
+-
+-   When `getopt' returns -1, this is the index of the first of the
+-   non-option elements that the caller should itself scan.
+-
+-   Otherwise, `optind' communicates from one call to the next
+-   how much of ARGV has been scanned so far.  */
+-
+-/* 1003.2 says this must be 1 before any call.  */
+-int optind = 1;
+-
+-/* Formerly, initialization of getopt depended on optind==0, which
+-   causes problems with re-calling getopt as programs generally don't
+-   know that. */
+-
+-int __getopt_initialized;
+-
+-/* The next char to be scanned in the option-element
+-   in which the last option character we returned was found.
+-   This allows us to pick up the scan where we left off.
+-
+-   If this is zero, or a null string, it means resume the scan
+-   by advancing to the next ARGV-element.  */
+-
+-static char *nextchar;
+-
+-/* Callers store zero here to inhibit the error message
+-   for unrecognized options.  */
+-
+-int opterr = 1;
+-
+-/* Set to an option character which was unrecognized.
+-   This must be initialized on some systems to avoid linking in the
+-   system's own getopt implementation.  */
+-
+-int optopt = '?';
+-
+-/* Describe how to deal with options that follow non-option ARGV-elements.
+-
+-   If the caller did not specify anything,
+-   the default is REQUIRE_ORDER if the environment variable
+-   POSIXLY_CORRECT is defined, PERMUTE otherwise.
+-
+-   REQUIRE_ORDER means don't recognize them as options;
+-   stop option processing when the first non-option is seen.
+-   This is what Unix does.
+-   This mode of operation is selected by either setting the environment
+-   variable POSIXLY_CORRECT, or using `+' as the first character
+-   of the list of option characters.
+-
+-   PERMUTE is the default.  We permute the contents of ARGV as we scan,
+-   so that eventually all the non-options are at the end.  This allows options
+-   to be given in any order, even with programs that were not written to
+-   expect this.
+-
+-   RETURN_IN_ORDER is an option available to programs that were written
+-   to expect options and other ARGV-elements in any order and that care about
+-   the ordering of the two.  We describe each non-option ARGV-element
+-   as if it were the argument of an option with character code 1.
+-   Using `-' as the first character of the list of option characters
+-   selects this mode of operation.
+-
+-   The special argument `--' forces an end of option-scanning regardless
+-   of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
+-   `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
+-
+-static enum
+-{
+-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+-} ordering;
+-
+-/* Value of POSIXLY_CORRECT environment variable.  */
+-static char *posixly_correct;
+-
+-#ifdef	__GNU_LIBRARY__
+-/* We want to avoid inclusion of string.h with non-GNU libraries
+-   because there are many ways it can cause trouble.
+-   On some systems, it contains special magic macros that don't work
+-   in GCC.  */
+-# include <string.h>
+-# define my_index	strchr
++/*	$NetBSD: getopt.c,v 1.27 2005/11/29 03:12:00 christos Exp $	*/
++
++/*
++ * Copyright (c) 1987, 1993, 1994
++ *	The Regents of the University of California.  All rights reserved.
++ *
++ * Redistribution and use in source and binary forms, with or without
++ * modification, are permitted provided that the following conditions
++ * are met:
++ * 1. Redistributions of source code must retain the above copyright
++ *    notice, this list of conditions and the following disclaimer.
++ * 2. Redistributions in binary form must reproduce the above copyright
++ *    notice, this list of conditions and the following disclaimer in the
++ *    documentation and/or other materials provided with the distribution.
++ * 3. Neither the name of the University nor the names of its contributors
++ *    may be used to endorse or promote products derived from this software
++ *    without specific prior written permission.
++ *
++ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
++ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
++ * SUCH DAMAGE.
++ */
++
++#undef LIBC_SCCS
++
++#if !defined(_WIN32)
++# include <sys/cdefs.h>
+ #else
+-
+-# if HAVE_STRING_H
+-#  include <string.h>
+-# else
+-#  include <strings.h>
+-# endif
+-
+-/* Avoid depending on library functions or files
+-   whose names are inconsistent.  */
+-
+-#ifndef getenv
+-extern char *getenv ();
++# define __UNCONST(x) ((char*)(x))
++# define getprogname() (nargv[0])
++# define _DIAGASSERT(x) assert((x))
+ #endif
+ 
+-static char *
+-my_index (str, chr)
+-     const char *str;
+-     int chr;
+-{
+-  while (*str)
+-    {
+-      if (*str == chr)
+-	return (char *) str;
+-      str++;
+-    }
+-  return 0;
+-}
+-
+-/* If using GCC, we can safely declare strlen this way.
+-   If not using GCC, it is ok not to declare it.  */
+-#ifdef __GNUC__
+-/* Note that Motorola Delta 68k R3V7 comes with GCC but not stddef.h.
+-   That was relevant to code that was here before.  */
+-# if (!defined __STDC__ || !__STDC__) && !defined strlen
+-/* gcc with -traditional declares the built-in strlen to return int,
+-   and has done so at least since version 2.4.5. -- rms.  */
+-extern int strlen (const char *);
+-# endif /* not __STDC__ */
+-#endif /* __GNUC__ */
+-
+-#endif /* not __GNU_LIBRARY__ */
+-
+-/* Handle permutation of arguments.  */
+-
+-/* Describe the part of ARGV that contains non-options that have
+-   been skipped.  `first_nonopt' is the index in ARGV of the first of them;
+-   `last_nonopt' is the index after the last of them.  */
+-
+-static int first_nonopt;
+-static int last_nonopt;
+-
+-#ifdef _LIBC
+-/* Stored original parameters.
+-   XXX This is no good solution.  We should rather copy the args so
+-   that we can compare them later.  But we must not use malloc(3).  */
+-extern int __libc_argc;
+-extern char **__libc_argv;
+-
+-/* Bash 2.0 gives us an environment variable containing flags
+-   indicating ARGV elements that should not be considered arguments.  */
++#ifdef _FREETDS_LIBRARY_SOURCE
++# include "tds_sysdep_private.h"
++#endif /* _FREETDS_LIBRARY_SOURCE */
+ 
+-# ifdef USE_NONOPTION_FLAGS
+-/* Defined in getopt_init.c  */
+-extern char *__getopt_nonoption_flags;
+-
+-static int nonoption_flags_max_len;
+-static int nonoption_flags_len;
+-# endif
+-
+-# ifdef USE_NONOPTION_FLAGS
+-#  define SWAP_FLAGS(ch1, ch2) \
+-  if (nonoption_flags_len > 0)						      \
+-    {									      \
+-      char __tmp = __getopt_nonoption_flags[ch1];			      \
+-      __getopt_nonoption_flags[ch1] = __getopt_nonoption_flags[ch2];	      \
+-      __getopt_nonoption_flags[ch2] = __tmp;				      \
+-    }
++#if defined(LIBC_SCCS) && !defined(lint)
++# if 0
++  static char sccsid[] = "@(#)getopt.c	8.3 (Berkeley) 4/27/95";
+ # else
+-#  define SWAP_FLAGS(ch1, ch2)
++  __RCSID("$NetBSD: getopt.c,v 1.27 2005/11/29 03:12:00 christos Exp $");
+ # endif
+-#else	/* !_LIBC */
+-# define SWAP_FLAGS(ch1, ch2)
+-#endif	/* _LIBC */
+-
+-/* Exchange two adjacent subsequences of ARGV.
+-   One subsequence is elements [first_nonopt,last_nonopt)
+-   which contains all the non-options that have been skipped so far.
+-   The other is elements [last_nonopt,optind), which contains all
+-   the options processed since those non-options were skipped.
+-
+-   `first_nonopt' and `last_nonopt' are relocated so that they describe
+-   the new indices of the non-options in ARGV after they are moved.  */
+-
+-#if defined __STDC__ && __STDC__
+-static void exchange (char **);
+-#endif
+-
+-static void
+-exchange (argv)
+-     char **argv;
+-{
+-  int bottom = first_nonopt;
+-  int middle = last_nonopt;
+-  int top = optind;
+-  char *tem;
+-
+-  /* Exchange the shorter segment with the far end of the longer segment.
+-     That puts the shorter segment into the right place.
+-     It leaves the longer segment in the right place overall,
+-     but it consists of two parts that need to be swapped next.  */
++#else
++ TDS_RCSID(var, "$Id: getopt.c,v 1.3 2010/02/07 00:33:54 freddy77 Exp $");
++#endif /* LIBC_SCCS and not lint */
+ 
+-#if defined _LIBC && defined USE_NONOPTION_FLAGS
+-  /* First make sure the handling of the `__getopt_nonoption_flags'
+-     string can work normally.  Our top argument must be in the range
+-     of the string.  */
+-  if (nonoption_flags_len > 0 && top >= nonoption_flags_max_len)
+-    {
+-      /* We must extend the array.  The user plays games with us and
+-	 presents new arguments.  */
+-      char *new_str = malloc (top + 1);
+-      if (new_str == NULL)
+-	nonoption_flags_len = nonoption_flags_max_len = 0;
+-      else
+-	{
+-	  memset (__mempcpy (new_str, __getopt_nonoption_flags,
+-			     nonoption_flags_max_len),
+-		  '\0', top + 1 - nonoption_flags_max_len);
+-	  nonoption_flags_max_len = top + 1;
+-	  __getopt_nonoption_flags = new_str;
+-	}
+-    }
++#if !defined(_WIN32)
++# include "namespace.h"
+ #endif
+ 
+-  while (top > middle && middle > bottom)
+-    {
+-      if (top - middle > middle - bottom)
+-	{
+-	  /* Bottom segment is the short one.  */
+-	  int len = middle - bottom;
+-	  register int i;
+-
+-	  /* Swap it with the top part of the top segment.  */
+-	  for (i = 0; i < len; i++)
+-	    {
+-	      tem = argv[bottom + i];
+-	      argv[bottom + i] = argv[top - (middle - bottom) + i];
+-	      argv[top - (middle - bottom) + i] = tem;
+-	      SWAP_FLAGS (bottom + i, top - (middle - bottom) + i);
+-	    }
+-	  /* Exclude the moved bottom segment from further swapping.  */
+-	  top -= len;
+-	}
+-      else
+-	{
+-	  /* Top segment is the short one.  */
+-	  int len = top - middle;
+-	  register int i;
+-
+-	  /* Swap it with the bottom part of the bottom segment.  */
+-	  for (i = 0; i < len; i++)
+-	    {
+-	      tem = argv[bottom + i];
+-	      argv[bottom + i] = argv[middle + i];
+-	      argv[middle + i] = tem;
+-	      SWAP_FLAGS (bottom + i, middle + i);
+-	    }
+-	  /* Exclude the moved top segment from further swapping.  */
+-	  bottom += len;
+-	}
+-    }
+-
+-  /* Update records for the slots the non-options now occupy.  */
+-
+-  first_nonopt += (optind - last_nonopt);
+-  last_nonopt = optind;
+-}
+-
+-/* Initialize the internal data when the first call is made.  */
+-
+-#if defined __STDC__ && __STDC__
+-static const char *_getopt_initialize (int, char *const *, const char *);
++#include <assert.h>
++#include <errno.h>
++#include <stdio.h>
++#include <stdlib.h>
++#include <string.h>
++#if !defined(_WIN32)
++# include <unistd.h>
+ #endif
+-static const char *
+-_getopt_initialize (argc, argv, optstring)
+-     int argc;
+-     char *const *argv;
+-     const char *optstring;
+-{
+-  /* Start processing options with ARGV-element 1 (since ARGV-element 0
+-     is the program name); the sequence of previously skipped
+-     non-option ARGV-elements is empty.  */
+-
+-  first_nonopt = last_nonopt = optind;
+-
+-  nextchar = NULL;
+-
+-  posixly_correct = getenv ("POSIXLY_CORRECT");
+-
+-  /* Determine how to handle the ordering of options and nonoptions.  */
+ 
+-  if (optstring[0] == '-')
+-    {
+-      ordering = RETURN_IN_ORDER;
+-      ++optstring;
+-    }
+-  else if (optstring[0] == '+')
+-    {
+-      ordering = REQUIRE_ORDER;
+-      ++optstring;
+-    }
+-  else if (posixly_correct != NULL)
+-    ordering = REQUIRE_ORDER;
+-  else
+-    ordering = PERMUTE;
+-
+-#if defined _LIBC && defined USE_NONOPTION_FLAGS
+-  if (posixly_correct == NULL
+-      && argc == __libc_argc && argv == __libc_argv)
+-    {
+-      if (nonoption_flags_max_len == 0)
+-	{
+-	  if (__getopt_nonoption_flags == NULL
+-	      || __getopt_nonoption_flags[0] == '\0')
+-	    nonoption_flags_max_len = -1;
+-	  else
+-	    {
+-	      const char *orig_str = __getopt_nonoption_flags;
+-	      int len = nonoption_flags_max_len = strlen (orig_str);
+-	      if (nonoption_flags_max_len < argc)
+-		nonoption_flags_max_len = argc;
+-	      __getopt_nonoption_flags =
+-		(char *) malloc (nonoption_flags_max_len);
+-	      if (__getopt_nonoption_flags == NULL)
+-		nonoption_flags_max_len = -1;
+-	      else
+-		memset (__mempcpy (__getopt_nonoption_flags, orig_str, len),
+-			'\0', nonoption_flags_max_len - len);
+-	    }
+-	}
+-      nonoption_flags_len = nonoption_flags_max_len;
+-    }
+-  else
+-    nonoption_flags_len = 0;
++#ifdef __weak_alias
++__weak_alias(getopt,_getopt)
+ #endif
+ 
+-  return optstring;
+-}
+-
+-/* Scan elements of ARGV (whose length is ARGC) for option characters
+-   given in OPTSTRING.
+-
+-   If an element of ARGV starts with '-', and is not exactly "-" or "--",
+-   then it is an option element.  The characters of this element
+-   (aside from the initial '-') are option characters.  If `getopt'
+-   is called repeatedly, it returns successively each of the option characters
+-   from each of the option elements.
+-
+-   If `getopt' finds another option character, it returns that character,
+-   updating `optind' and `nextchar' so that the next call to `getopt' can
+-   resume the scan with the following option character or ARGV-element.
+-
+-   If there are no more option characters, `getopt' returns -1.
+-   Then `optind' is the index in ARGV of the first ARGV-element
+-   that is not an option.  (The ARGV-elements have been permuted
+-   so that those that are not options now come last.)
++int	opterr = 1,		/* if error message should be printed */
++	optind = 1,		/* index into parent argv vector */
++	optopt,			/* character checked for validity */
++	optreset;		/* reset getopt */
++char	*optarg;		/* argument associated with option */
+ 
+-   OPTSTRING is a string containing the legitimate option characters.
+-   If an option character is seen that is not listed in OPTSTRING,
+-   return '?' after printing an error message.  If you set `opterr' to
+-   zero, the error message is suppressed but we still return '?'.
+-
+-   If a char in OPTSTRING is followed by a colon, that means it wants an arg,
+-   so the following text in the same ARGV-element, or the text of the following
+-   ARGV-element, is returned in `optarg'.  Two colons mean an option that
+-   wants an optional arg; if there is text in the current ARGV-element,
+-   it is returned in `optarg', otherwise `optarg' is set to zero.
+-
+-   If OPTSTRING starts with `-' or `+', it requests different methods of
+-   handling the non-option ARGV-elements.
+-   See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above.
+-
+-   Long-named options begin with `--' instead of `-'.
+-   Their names may be abbreviated as long as the abbreviation is unique
+-   or is an exact match for some defined option.  If they have an
+-   argument, it follows the option name in the same ARGV-element, separated
+-   from the option name by a `=', or else the in next ARGV-element.
+-   When `getopt' finds a long-named option, it returns 0 if that option's
+-   `flag' field is nonzero, the value of the option's `val' field
+-   if the `flag' field is zero.
+-
+-   The elements of ARGV aren't really const, because we permute them.
+-   But we pretend they're const in the prototype to be compatible
+-   with other systems.
+-
+-   LONGOPTS is a vector of `struct option' terminated by an
+-   element containing a name which is zero.
+-
+-   LONGIND returns the index in LONGOPT of the long-named option found.
+-   It is only valid when a long-named option has been found by the most
+-   recent call.
+-
+-   If LONG_ONLY is nonzero, '-' as well as '--' can introduce
+-   long-named options.  */
++#define	BADCH	(int)'?'
++#define	BADARG	(int)':'
++#define	EMSG	""
+ 
++/*
++ * getopt --
++ *	Parse argc/argv argument vector.
++ */
+ int
+-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
+-     int argc;
+-     char *const *argv;
+-     const char *optstring;
+-     const struct option *longopts;
+-     int *longind;
+-     int long_only;
++getopt(nargc, nargv, ostr)
++	int nargc;
++	char * const nargv[];
++	const char *ostr;
+ {
+-  int print_errors = opterr;
+-  if (optstring[0] == ':')
+-    print_errors = 0;
+-
+-  if (argc < 1)
+-    return -1;
+-
+-  optarg = NULL;
+-
+-  if (optind == 0 || !__getopt_initialized)
+-    {
+-      if (optind == 0)
+-	optind = 1;	/* Don't scan ARGV[0], the program name.  */
+-      optstring = _getopt_initialize (argc, argv, optstring);
+-      __getopt_initialized = 1;
+-    }
+-
+-  /* Test whether ARGV[optind] points to a non-option argument.
+-     Either it does not have option syntax, or there is an environment flag
+-     from the shell indicating it is not an option.  The later information
+-     is only used when the used in the GNU libc.  */
+-#if defined _LIBC && defined USE_NONOPTION_FLAGS
+-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'	      \
+-		      || (optind < nonoption_flags_len			      \
+-			  && __getopt_nonoption_flags[optind] == '1'))
+-#else
+-# define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
+-#endif
+-
+-  if (nextchar == NULL || *nextchar == '\0')
+-    {
+-      /* Advance to the next ARGV-element.  */
+-
+-      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+-	 moved back by the user (who may also have changed the arguments).  */
+-      if (last_nonopt > optind)
+-	last_nonopt = optind;
+-      if (first_nonopt > optind)
+-	first_nonopt = optind;
+-
+-      if (ordering == PERMUTE)
+-	{
+-	  /* If we have just processed some options following some non-options,
+-	     exchange them so that the options come first.  */
+-
+-	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+-	    exchange ((char **) argv);
+-	  else if (last_nonopt != optind)
+-	    first_nonopt = optind;
+-
+-	  /* Skip any additional non-options
+-	     and extend the range of non-options previously skipped.  */
+-
+-	  while (optind < argc && NONOPTION_P)
+-	    optind++;
+-	  last_nonopt = optind;
+-	}
+-
+-      /* The special ARGV-element `--' means premature end of options.
+-	 Skip it like a null option,
+-	 then exchange with previous non-options as if it were an option,
+-	 then skip everything else like a non-option.  */
+-
+-      if (optind != argc && !strcmp (argv[optind], "--"))
+-	{
+-	  optind++;
+-
+-	  if (first_nonopt != last_nonopt && last_nonopt != optind)
+-	    exchange ((char **) argv);
+-	  else if (first_nonopt == last_nonopt)
+-	    first_nonopt = optind;
+-	  last_nonopt = argc;
+-
+-	  optind = argc;
+-	}
+-
+-      /* If we have done all the ARGV-elements, stop the scan
+-	 and back over any non-options that we skipped and permuted.  */
+-
+-      if (optind == argc)
+-	{
+-	  /* Set the next-arg-index to point at the non-options
+-	     that we previously skipped, so the caller will digest them.  */
+-	  if (first_nonopt != last_nonopt)
+-	    optind = first_nonopt;
+-	  return -1;
+-	}
+-
+-      /* If we have come to a non-option and did not permute it,
+-	 either stop the scan or describe it to the caller and pass it by.  */
+-
+-      if (NONOPTION_P)
+-	{
+-	  if (ordering == REQUIRE_ORDER)
+-	    return -1;
+-	  optarg = argv[optind++];
+-	  return 1;
+-	}
+-
+-      /* We have found another option-ARGV-element.
+-	 Skip the initial punctuation.  */
+-
+-      nextchar = (argv[optind] + 1
+-		  + (longopts != NULL && argv[optind][1] == '-'));
+-    }
+-
+-  /* Decode the current option-ARGV-element.  */
+-
+-  /* Check whether the ARGV-element is a long option.
+-
+-     If long_only and the ARGV-element has the form "-f", where f is
+-     a valid short option, don't consider it an abbreviated form of
+-     a long option that starts with f.  Otherwise there would be no
+-     way to give the -f short option.
+-
+-     On the other hand, if there's a long option "fubar" and
+-     the ARGV-element is "-fu", do consider that an abbreviation of
+-     the long option, just like "--fu", and not "-f" with arg "u".
+-
+-     This distinction seems to be the most useful approach.  */
+-
+-  if (longopts != NULL
+-      && (argv[optind][1] == '-'
+-	  || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
+-    {
+-      char *nameend;
+-      const struct option *p;
+-      const struct option *pfound = NULL;
+-      int exact = 0;
+-      int ambig = 0;
+-      int indfound = -1;
+-      int option_index;
+-
+-      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+-	/* Do nothing.  */ ;
+-
+-      /* Test all long options for either exact match
+-	 or abbreviated matches.  */
+-      for (p = longopts, option_index = 0; p->name; p++, option_index++)
+-	if (!strncmp (p->name, nextchar, nameend - nextchar))
+-	  {
+-	    if ((unsigned int) (nameend - nextchar)
+-		== (unsigned int) strlen (p->name))
+-	      {
+-		/* Exact match found.  */
+-		pfound = p;
+-		indfound = option_index;
+-		exact = 1;
+-		break;
+-	      }
+-	    else if (pfound == NULL)
+-	      {
+-		/* First nonexact match found.  */
+-		pfound = p;
+-		indfound = option_index;
+-	      }
+-	    else if (long_only
+-		     || pfound->has_arg != p->has_arg
+-		     || pfound->flag != p->flag
+-		     || pfound->val != p->val)
+-	      /* Second or later nonexact match found.  */
+-	      ambig = 1;
+-	  }
+-
+-      if (ambig && !exact)
+-	{
+-	  if (print_errors)
+-	    fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
+-		     argv[0], argv[optind]);
+-	  nextchar += strlen (nextchar);
+-	  optind++;
+-	  optopt = 0;
+-	  return '?';
+-	}
+-
+-      if (pfound != NULL)
+-	{
+-	  option_index = indfound;
+-	  optind++;
+-	  if (*nameend)
+-	    {
+-	      /* Don't test has_arg with >, because some C compilers don't
+-		 allow it to be used on enums.  */
+-	      if (pfound->has_arg)
+-		optarg = nameend + 1;
+-	      else
+-		{
+-		  if (print_errors)
+-		    {
+-		      if (argv[optind - 1][1] == '-')
+-			/* --option */
+-			fprintf (stderr,
+-				 _("%s: option `--%s' doesn't allow an argument\n"),
+-				 argv[0], pfound->name);
+-		      else
+-			/* +option or -option */
+-			fprintf (stderr,
+-				 _("%s: option `%c%s' doesn't allow an argument\n"),
+-				 argv[0], argv[optind - 1][0], pfound->name);
+-		    }
+-
+-		  nextchar += strlen (nextchar);
+-
+-		  optopt = pfound->val;
+-		  return '?';
++	static const char *place = EMSG;	/* option letter processing */
++	char *oli;				/* option letter list index */
++
++	_DIAGASSERT(nargv != NULL);
++	_DIAGASSERT(ostr != NULL);
++
++	if (optreset || *place == 0) {		/* update scanning pointer */
++		optreset = 0;
++		place = nargv[optind];
++		if (optind >= nargc || *place++ != '-') {
++			/* Argument is absent or is not an option */
++			place = EMSG;
++			return (-1);
+ 		}
+-	    }
+-	  else if (pfound->has_arg == 1)
+-	    {
+-	      if (optind < argc)
+-		optarg = argv[optind++];
+-	      else
+-		{
+-		  if (print_errors)
+-		    fprintf (stderr,
+-			   _("%s: option `%s' requires an argument\n"),
+-			   argv[0], argv[optind - 1]);
+-		  nextchar += strlen (nextchar);
+-		  optopt = pfound->val;
+-		  return optstring[0] == ':' ? ':' : '?';
++		optopt = *place++;
++		if (optopt == '-' && *place == 0) {
++			/* "--" => end of options */
++			++optind;
++			place = EMSG;
++			return (-1);
+ 		}
+-	    }
+-	  nextchar += strlen (nextchar);
+-	  if (longind != NULL)
+-	    *longind = option_index;
+-	  if (pfound->flag)
+-	    {
+-	      *(pfound->flag) = pfound->val;
+-	      return 0;
+-	    }
+-	  return pfound->val;
+-	}
+-
+-      /* Can't find it as a long option.  If this is not getopt_long_only,
+-	 or the option starts with '--' or is not a valid short
+-	 option, then it's an error.
+-	 Otherwise interpret it as a short option.  */
+-      if (!long_only || argv[optind][1] == '-'
+-	  || my_index (optstring, *nextchar) == NULL)
+-	{
+-	  if (print_errors)
+-	    {
+-	      if (argv[optind][1] == '-')
+-		/* --option */
+-		fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
+-			 argv[0], nextchar);
+-	      else
+-		/* +option or -option */
+-		fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
+-			 argv[0], argv[optind][0], nextchar);
+-	    }
+-	  nextchar = (char *) "";
+-	  optind++;
+-	  optopt = 0;
+-	  return '?';
++		if (optopt == 0) {
++			/* Solitary '-', treat as a '-' option
++			   if the program (eg su) is looking for it. */
++			place = EMSG;
++			if (strchr(ostr, '-') == NULL)
++				return -1;
++			optopt = '-';
++		}
++	} else
++		optopt = *place++;
++
++	/* See if option letter is one the caller wanted... */
++	if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
++		if (*place == 0)
++			++optind;
++		if (opterr && *ostr != ':')
++			(void)fprintf(stderr,
++			    "%s: unknown option -- %c\n", getprogname(),
++			    optopt);
++		return (BADCH);
+ 	}
+-    }
+-
+-  /* Look at and handle the next short option-character.  */
+-
+-  {
+-    char c = *nextchar++;
+-    char *temp = my_index (optstring, c);
+-
+-    /* Increment `optind' when we start to process its last character.  */
+-    if (*nextchar == '\0')
+-      ++optind;
+ 
+-    if (temp == NULL || c == ':')
+-      {
+-	if (print_errors)
+-	  {
+-	    if (posixly_correct)
+-	      /* 1003.2 specifies the format of this message.  */
+-	      fprintf (stderr, _("%s: illegal option -- %c\n"),
+-		       argv[0], c);
+-	    else
+-	      fprintf (stderr, _("%s: invalid option -- %c\n"),
+-		       argv[0], c);
+-	  }
+-	optopt = c;
+-	return '?';
+-      }
+-    /* Convenience. Treat POSIX -W foo same as long option --foo */
+-    if (temp[0] == 'W' && temp[1] == ';')
+-      {
+-	char *nameend;
+-	const struct option *p;
+-	const struct option *pfound = NULL;
+-	int exact = 0;
+-	int ambig = 0;
+-	int indfound = 0;
+-	int option_index;
+-
+-	/* This is an option that requires an argument.  */
+-	if (*nextchar != '\0')
+-	  {
+-	    optarg = nextchar;
+-	    /* If we end this ARGV-element by taking the rest as an arg,
+-	       we must advance to the next element now.  */
+-	    optind++;
+-	  }
+-	else if (optind == argc)
+-	  {
+-	    if (print_errors)
+-	      {
+-		/* 1003.2 specifies the format of this message.  */
+-		fprintf (stderr, _("%s: option requires an argument -- %c\n"),
+-			 argv[0], c);
+-	      }
+-	    optopt = c;
+-	    if (optstring[0] == ':')
+-	      c = ':';
+-	    else
+-	      c = '?';
+-	    return c;
+-	  }
+-	else
+-	  /* We already incremented `optind' once;
+-	     increment it again when taking next ARGV-elt as argument.  */
+-	  optarg = argv[optind++];
+-
+-	/* optarg is now the argument, see if it's in the
+-	   table of longopts.  */
+-
+-	for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
+-	  /* Do nothing.  */ ;
+-
+-	/* Test all long options for either exact match
+-	   or abbreviated matches.  */
+-	for (p = longopts, option_index = 0; p->name; p++, option_index++)
+-	  if (!strncmp (p->name, nextchar, nameend - nextchar))
+-	    {
+-	      if ((unsigned int) (nameend - nextchar) == strlen (p->name))
+-		{
+-		  /* Exact match found.  */
+-		  pfound = p;
+-		  indfound = option_index;
+-		  exact = 1;
+-		  break;
+-		}
+-	      else if (pfound == NULL)
+-		{
+-		  /* First nonexact match found.  */
+-		  pfound = p;
+-		  indfound = option_index;
++	/* Does this option need an argument? */
++	if (oli[1] != ':') {
++		/* don't need argument */
++		optarg = NULL;
++		if (*place == 0)
++			++optind;
++	} else {
++		/* Option-argument is either the rest of this argument or the
++		   entire next argument. */
++		if (*place)
++			optarg = __UNCONST(place);
++		else if (nargc > ++optind)
++			optarg = nargv[optind];
++		else {
++			/* option-argument absent */
++			place = EMSG;
++			if (*ostr == ':')
++				return (BADARG);
++			if (opterr)
++				(void)fprintf(stderr,
++				    "%s: option requires an argument -- %c\n",
++				    getprogname(), optopt);
++			return (BADCH);
+ 		}
+-	      else
+-		/* Second or later nonexact match found.  */
+-		ambig = 1;
+-	    }
+-	if (ambig && !exact)
+-	  {
+-	    if (print_errors)
+-	      fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
+-		       argv[0], argv[optind]);
+-	    nextchar += strlen (nextchar);
+-	    optind++;
+-	    return '?';
+-	  }
+-	if (pfound != NULL)
+-	  {
+-	    option_index = indfound;
+-	    if (*nameend)
+-	      {
+-		/* Don't test has_arg with >, because some C compilers don't
+-		   allow it to be used on enums.  */
+-		if (pfound->has_arg)
+-		  optarg = nameend + 1;
+-		else
+-		  {
+-		    if (print_errors)
+-		      fprintf (stderr, _("\
+-%s: option `-W %s' doesn't allow an argument\n"),
+-			       argv[0], pfound->name);
+-
+-		    nextchar += strlen (nextchar);
+-		    return '?';
+-		  }
+-	      }
+-	    else if (pfound->has_arg == 1)
+-	      {
+-		if (optind < argc)
+-		  optarg = argv[optind++];
+-		else
+-		  {
+-		    if (print_errors)
+-		      fprintf (stderr,
+-			       _("%s: option `%s' requires an argument\n"),
+-			       argv[0], argv[optind - 1]);
+-		    nextchar += strlen (nextchar);
+-		    return optstring[0] == ':' ? ':' : '?';
+-		  }
+-	      }
+-	    nextchar += strlen (nextchar);
+-	    if (longind != NULL)
+-	      *longind = option_index;
+-	    if (pfound->flag)
+-	      {
+-		*(pfound->flag) = pfound->val;
+-		return 0;
+-	      }
+-	    return pfound->val;
+-	  }
+-	  nextchar = NULL;
+-	  return 'W';	/* Let the application handle it.   */
+-      }
+-    if (temp[1] == ':')
+-      {
+-	if (temp[2] == ':')
+-	  {
+-	    /* This is an option that accepts an argument optionally.  */
+-	    if (*nextchar != '\0')
+-	      {
+-		optarg = nextchar;
+-		optind++;
+-	      }
+-	    else
+-	      optarg = NULL;
+-	    nextchar = NULL;
+-	  }
+-	else
+-	  {
+-	    /* This is an option that requires an argument.  */
+-	    if (*nextchar != '\0')
+-	      {
+-		optarg = nextchar;
+-		/* If we end this ARGV-element by taking the rest as an arg,
+-		   we must advance to the next element now.  */
+-		optind++;
+-	      }
+-	    else if (optind == argc)
+-	      {
+-		if (print_errors)
+-		  {
+-		    /* 1003.2 specifies the format of this message.  */
+-		    fprintf (stderr,
+-			     _("%s: option requires an argument -- %c\n"),
+-			     argv[0], c);
+-		  }
+-		optopt = c;
+-		if (optstring[0] == ':')
+-		  c = ':';
+-		else
+-		  c = '?';
+-	      }
+-	    else
+-	      /* We already incremented `optind' once;
+-		 increment it again when taking next ARGV-elt as argument.  */
+-	      optarg = argv[optind++];
+-	    nextchar = NULL;
+-	  }
+-      }
+-    return c;
+-  }
+-}
+-
+-int
+-getopt (argc, argv, optstring)
+-     int argc;
+-     char *const *argv;
+-     const char *optstring;
+-{
+-  return _getopt_internal (argc, argv, optstring,
+-			   (const struct option *) 0,
+-			   (int *) 0,
+-			   0);
+-}
+-
+-#endif	/* Not ELIDE_CODE.  */
+-
+-#ifdef TEST
+-
+-/* Compile with -DTEST to make an executable for use in testing
+-   the above definition of `getopt'.  */
+-
+-int
+-main (argc, argv)
+-     int argc;
+-     char **argv;
+-{
+-  int c;
+-  int digit_optind = 0;
+-
+-  while (1)
+-    {
+-      int this_option_optind = optind ? optind : 1;
+-
+-      c = getopt (argc, argv, "abc:d:0123456789");
+-      if (c == -1)
+-	break;
+-
+-      switch (c)
+-	{
+-	case '0':
+-	case '1':
+-	case '2':
+-	case '3':
+-	case '4':
+-	case '5':
+-	case '6':
+-	case '7':
+-	case '8':
+-	case '9':
+-	  if (digit_optind != 0 && digit_optind != this_option_optind)
+-	    printf ("digits occur in two different argv-elements.\n");
+-	  digit_optind = this_option_optind;
+-	  printf ("option %c\n", c);
+-	  break;
+-
+-	case 'a':
+-	  printf ("option a\n");
+-	  break;
+-
+-	case 'b':
+-	  printf ("option b\n");
+-	  break;
+-
+-	case 'c':
+-	  printf ("option c with value `%s'\n", optarg);
+-	  break;
+-
+-	case '?':
+-	  break;
+-
+-	default:
+-	  printf ("?? getopt returned character code 0%o ??\n", c);
++		place = EMSG;
++		++optind;
+ 	}
+-    }
+-
+-  if (optind < argc)
+-    {
+-      printf ("non-option ARGV-elements: ");
+-      while (optind < argc)
+-	printf ("%s ", argv[optind++]);
+-      printf ("\n");
+-    }
+-
+-  exit (0);
++	return (optopt);			/* return option letter */
+ }
+-
+-#endif /* TEST */
+
+commit b180254ec9403e8ed4ceba75b4953f5dcdf5c764
+Author: jklowden <jklowden>
+Date:   Sun Feb 7 21:55:48 2010 +0000
+
+    preparing for release
+
+diff --git a/ChangeLog b/ChangeLog
+index 23588f3..bddf737 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,12 @@
++Sun Feb  7 16:50:58 EST 2010	JK Lowden <jklowden@freetds.org>
++	* doc/userguide.sgml preparing for release
++	* src/apps/bsqlodbc.c use hdesc to detmine octet count
++	* include/sybdb.h src/dblib/dblib.c src/tds/config.c
++	* src/tds/iconv.c src/tds/login.c src/tds/util.c
++	- Default bad client charset name to ISO 8859-1, 
++	- and avoid TDSEPORTINSTANCE when one of port/instance
++	- came from the [default] section. 
++
+ Sun Feb  7 01:33:47 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/getopt.c: reverted getopt LGPL patch
+ 
+@@ -2289,4 +2298,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2983 2010/02/07 00:33:54 freddy77 Exp $
++$Id: ChangeLog,v 1.2984 2010/02/07 21:55:48 jklowden Exp $
+diff --git a/doc/userguide.sgml b/doc/userguide.sgml
+index 4de1756..39ed977 100644
+--- a/doc/userguide.sgml
++++ b/doc/userguide.sgml
+@@ -9,8 +9,8 @@
+ ]>
+ <book>
+ 	<bookinfo>
+-		<date>$Date: 2010/02/02 09:37:39 $</date>
+-		<releaseinfo>$Revision: 1.128 $</releaseinfo>
++		<date>$Date: 2010/02/07 21:55:49 $</date>
++		<releaseinfo>$Revision: 1.129 $</releaseinfo>
+ 		<title>&freetds; User Guide</title>
+ 		<subtitle>A Guide to Installing, Configuring, and Running &freetds;</subtitle>
+ 		<author>
+@@ -62,9 +62,9 @@ This guide is here for you, and we hope that you will be here for it, that other
+ The version you're reading is:
+ 			</para> 
+   			<simplelist type='vert'>
+-<member>$Revision: 1.128 $</>
+-<member>$Date: 2010/02/02 09:37:39 $</>
+-<member>CVS control number $Id: userguide.sgml,v 1.128 2010/02/02 09:37:39 freddy77 Exp $.</>
++<member>$Revision: 1.129 $</>
++<member>$Date: 2010/02/07 21:55:49 $</>
++<member>CVS control number $Id: userguide.sgml,v 1.129 2010/02/07 21:55:49 jklowden Exp $.</>
+   			</simplelist>
+ 			</footnote>
+ can be found on the &freetds; 
+@@ -617,7 +617,7 @@ url="http://www.madgoat.com">www.madgoat.com</ulink>).</para>
+ 		</sect3>
+ 		</sect2>
+ 		<sect2 id="osx"><title>OS X&reg;</title>
+-  			<para>As of this writing ($Date: 2010/02/02 09:37:39 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
++  			<para>As of this writing ($Date: 2010/02/07 21:55:49 $), the regular distribution compiles on OS X.  Releases prior to 0.63 either did not compile or required patching.  </para>
+ 
+ 		<sect3 id="OSX.Build.Update">
+ 			<title>Alternative build procedure</title>
+@@ -796,18 +796,19 @@ and 7.0.  Version 7.0 is recommended for compatibility with SQL Server tools.
+ 				<member>listens for an answer from the server</member>
+ 			</simplelist>
+ 		-->	
+-			<para>&freetds; tries the following steps, in order, to convert the servername to an IP address, stopping when it succeeds. 
++			<para>&freetds; converts the servername to an IP address by following the steps below, stopping when it succeeds. 
+ 			<orderedlist><title>Name lookup sequence
+ 				<footnote><para>This description applies to db-lib and ct-lib.  ODBC lookup is different.  </para></footnote>
+ 				</title>
+ 				<listitem><para>Find <replaceable>servername</> in &freetdsconf;.  If a section with that name exists, use the hostname, port, and TDS version specified therein.  </para></listitem>
+-				<listitem><para>Attempt to convert <replaceable>servername</> to an IP address with <function>inet_addr(3)</>.  If successful, use the compiled-in default port and TDS version.  </para></listitem>
+-				<listitem><para>Request name-lookup from the operating system via <function>gethostbyname(3)</> or similar.  If successful, use the compiled-in default port and TDS version.  </para></listitem>
++				<listitem><para>Attempt to convert <replaceable>servername</> to an IP address with <function>inet_addr(3)</>.   </para></listitem>
++				<listitem><para>Request name-lookup from the operating system via <function>gethostbyname(3)</> or similar.   </para></listitem>
+ 			</orderedlist>
+-
+-			As you can see, if most of your servers use the same TDS version and answer to the default port, then you don't need to list them all in &freetdsconf;.  You can simply compile in the right defaults &mdash; or set the <envar>TDSPORT</envar> and <envar>TDSVER</envar> environment variables &mdash; and rely on DNS for name resolution.  
+ 			
++			If the TDS version and port are not read from &freetdsconf;, they are derived from the compiled-in defaults and overridden by applicable environment variables.  
++			</para>
+ 			
++			<para>As you can see, if most of your servers use the same TDS version and answer to the default port, then you don't need to list them all in &freetdsconf;.  You can simply compile in the right defaults &mdash; or set the <envar>TDSPORT</envar> and <envar>TDSVER</envar> environment variables &mdash; and rely on DNS for name resolution.  
+ 			</para>
+ 		</sect1>
+ 
+@@ -1213,7 +1214,7 @@ In a typical system, no environment variables need be used.  They're sometimes h
+ 	<varlistentry>
+ 		<term id="FREETDS"><envar>FREETDS</envar></term>
+ 		<listitem>
+-			<para>may be used to specify the name and location of the &freetdsconf; file.  In prior versions of &freetds;, this variable was known as <envar>FREETDSCONF</envar>. </para>
++			<para>may be used to specify the name and location of the &freetdsconf; file.  In prior versions of &freetds; this variable was known as <envar>FREETDSCONF</envar>. </para>
+ 		</listitem>
+ 	</varlistentry>	
+ 	<varlistentry>
+@@ -1350,11 +1351,7 @@ When you're done, you should see something very like this:
+ 			
+ 			<sect2 id="tsql"><title><application>tsql</application></title>
+ 
+-			<para>The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  For details on the use of <command>tsql</>, consult its man page. </para>
+-			<para><command>tsql</> can either use or bypass the configuration files.  By trying both options, you can usually determine if it's your server that's not responding, or your configuration files that are messed up. </para> 
+-
+-			<sect3 id="tsql.freetds.conf"><title><replaceable>servername</> Lookup</title>
+-			<para><application>tsql</> reports where it looks for &freetdsconf; and other compile-time settings with <command>tsql -C</>.  
++			<para>The <firstterm>tsql</> utility is provided as part of FreeTDS expressly for troubleshooting.  <command>tsql</> is superficially similar to an <command>isql</>, but uses <filename>libtds</filename> directly, bypassing the client libraries (e.g., <systemitem class="library">db-lib</systemitem>).  It can also  report where it looks for &freetdsconf; and other compile-time settings (with <command>tsql -C</>).  
+ 			</para>
+ <example id="e.g.tsqlShowsettings">
+ <title>Show compile-time settings with <command>tsql</></title>
+@@ -1378,6 +1375,10 @@ Compile-time settings (established with the "configure" script):
+ </screen>
+ </example>
+ 
++			<para>For details on the use of <command>tsql</>, consult its man page. </para>
++
++			<sect3 id="tsql.freetds.conf"><title><replaceable>servername</> Lookup</title>
++			<para>If all goes well, the first time you fire up <command>tsql</> it connects and you can issue your first query.  More often, though, the result is less joyous.  Listed below for your troubleshooting pleasure are a variety of <replaceable>servername</> lookup failures and their corresponding messages.  </para>
+ 			<para>When <replaceable>servername</> cannot be converted to an address, up to two messages may result.  Successful conversion (by any means) never produces an error message.  
+ 			
+ <example id="e.g.notfound">
+@@ -1394,7 +1395,7 @@ Msg 20013, Level 2, State -1, Server OpenClient, Line -1
+ Unknown host machine name.
+ There was a problem connecting to the server
+ </computeroutput>
+-<prompt>$ </prompt><userinput>host emforester</userinput>
++<prompt>$ </prompt><userinput>host nobox</userinput>
+ <computeroutput>
+ Host not found.
+ </computeroutput>
+@@ -1420,7 +1421,7 @@ There was a problem connecting to the server
+ </computeroutput>
+ </screen>
+ </example>	
+-			Unfortunately, the <quote>host machine name</quote> isn't mentioned in the error message.  Fortunately, this kind of setup problem is rarely encountered by users.  
++			Unfortunately, the <quote>host machine name</quote> (the right side of the <literal>host</> line in &freetdsconf;) isn't mentioned in the error message.  Fortunately, this kind of setup problem is rarely encountered by users.  
+ 			</para>
+ 			<para>If name lookup succeeds, &freetds; next attempts to connect to the server.  <emphasis>To connect</> means to form at TCP connection by calling <function>connect(2)</>.  A valid connection must exist before any information can be exchanged with the server.  Specifically, we need a connection before we can log in.  
+ 			</para>
+
+commit 07eec7a461faaa177525532119f4ab83415990cb
+Author: jklowden <jklowden>
+Date:   Sun Feb 7 21:55:54 2010 +0000
+
+    use hdesc to detmine octet count
+
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index d9cd56a..bac6bda 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.13 2010/02/05 22:09:31 jklowden Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.14 2010/02/07 21:55:54 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -628,11 +628,10 @@ print_results(SQLHSTMT hStmt)
+ 		 */
+ 		while (ncols > 0 && (erc = SQLFetch(hStmt)) != SQL_NO_DATA) {
+ 			switch(erc) {
+-			case SQL_SUCCESS:
+-				break;
+ 			case SQL_SUCCESS_WITH_INFO:
+ 				print_error_message(SQL_HANDLE_STMT, hStmt);
+-				continue;
++			case SQL_SUCCESS:
++				break;
+ 			default:
+ 				odbc_perror(hStmt, erc, "SQLFetch", "failed");
+ 				exit(EXIT_FAILURE);
+
+commit 501021256aacc432d237fc4767cb378cd535d7b5
+Author: jklowden <jklowden>
+Date:   Sun Feb 7 21:56:09 2010 +0000
+
+    Default bad client charset name to ISO 8859-1,  and avoid TDSEPORTINSTANCE when one of port/instance came from the [default] section.
+
+diff --git a/include/sybdb.h b/include/sybdb.h
+index 8f0cb20..9f849a8 100644
+--- a/include/sybdb.h
++++ b/include/sybdb.h
+@@ -41,7 +41,7 @@ extern "C"
+ #define TDS_STATIC_CAST(type, a) ((type)(a))
+ #endif
+ 
+-static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.91 2009/08/25 14:25:35 freddy77 Exp $";
++static const char rcsid_sybdb_h[] = "$Id: sybdb.h,v 1.92 2010/02/07 21:56:09 jklowden Exp $";
+ static const void *const no_unused_sybdb_h_warn[] = { rcsid_sybdb_h, no_unused_sybdb_h_warn };
+ 
+ #ifdef FALSE
+@@ -786,6 +786,7 @@ DBINT dbvarylen(DBPROCESS * dbproc, int column);
+ 				/* cf. doc/dblib_errors.txt for more iconv error values. */
+ 				/* Reserve a few slots for other iconv-related issues. */
+ #define SYBETDSVER	 2410 	/* Cannot bcp with TDSVER < 5.0 */
++#define SYBEPORT	 2500	/* Both port and instance specified */
+ #define SYBESYNC        20001	/* Read attempted while out of synchronization with SQL Server. */
+ #define SYBEFCON        20002	/* SQL Server connection failed. */
+ #define SYBETIME        20003	/* SQL Server connection timed out. */
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 035d17f..00f6e44 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.362 2010/01/28 05:35:55 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.363 2010/02/07 21:56:09 jklowden Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -7477,6 +7477,9 @@ static const DBLIB_ERROR_MESSAGE dblib_error_messages[] =
+ 	, { SYBEICONVI,      EXCONVERSION,	"Some character(s) could not be converted into client's character set.  Unconverted "
+ 						"bytes were changed to question marks ('?')\0" }
+ 	, { SYBEICONV2BIG,   EXCONVERSION,	"Buffer overflow converting characters from client into server's character set\0" }
++	
++	
++	, { SYBEPORT, 	   	   EXUSER,	"Both port and instance specified\0" }
+ 	, { SYBETDSVER, 	   EXUSER,	"Cannot bcp with TDSVER < 5.0\0" }
+ 	, { SYBEAAMT,           EXPROGRAM,	"User attempted a dbaltbind with mismatched column and variable types\0" }
+ 	, { SYBEABMT,           EXPROGRAM,	"User attempted a dbbind with mismatched column and variable types\0" }
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 96cbd9c..678f35a 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -36,6 +36,10 @@
+ #include <stdlib.h>
+ #endif /* HAVE_STDLIB_H */
+ 
++#if HAVE_LIMITS_H
++#include <limits.h>
++#endif 
++
+ #if HAVE_STRING_H
+ #include <string.h>
+ #endif /* HAVE_STRING_H */
+@@ -76,7 +80,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.157 2010/01/29 18:57:03 freddy77 Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.158 2010/02/07 21:56:10 jklowden Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -376,11 +380,30 @@ tds_read_conf_file(TDSCONNECTION * connection, const char *server)
+ static int
+ tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection)
+ {
++	TDSCONNECTION defaults;
++	int found;
++
+ 	tds_read_conf_section(in, "global", tds_parse_conf_section, connection);
++
+ 	if (!server[0])
+ 		return 0;
+ 	rewind(in);
+-	return tds_read_conf_section(in, server, tds_parse_conf_section, connection);
++	defaults = *connection;
++
++	found = tds_read_conf_section(in, server, tds_parse_conf_section, connection);
++	
++	/* 
++	 * If both instance and port are specified and neither one came from the default, it's an error 
++	 * TODO: If port/instance is specified in the non-default, it has priority over the default setting. 
++	 * TODO: test this. 
++	 */
++	if (!tds_dstr_isempty(&connection->instance_name) && connection->port && 
++	  !(!tds_dstr_isempty(   &defaults.instance_name) ||    defaults.port)) {
++		tdsdump_log(TDS_DBG_ERROR, "error: cannot specify both port %d and instance %s.\n", 
++						connection->port, tds_dstr_cstr(&connection->instance_name));
++		/* tdserror(tds->tds_ctx, tds, TDSEPORTINSTANCE, 0); */
++	}
++	return found;
+ }
+ 
+ static const struct {
+@@ -539,11 +562,10 @@ tds_parse_conf_section(const char *option, const char *value, void *param)
+ 		tds_dstr_copy(&connection->dump_file, value);
+ 	} else if (!strcmp(option, TDS_STR_DEBUGFLAGS)) {
+ 		char *end;
+-		long l;
+-		errno = 0;
+-		l = strtol(value, &end, 0);
+-		if (errno == 0 && *end == 0)
+-			connection->debug_flags = l;
++		long flags;
++		flags = strtol(value, &end, 0);
++		if (*value != '\0' && *end == '\0' && flags != LONG_MIN && flags != LONG_MAX)
++			connection->debug_flags = flags;
+ 	} else if (!strcmp(option, TDS_STR_TIMEOUT) || !strcmp(option, TDS_STR_QUERY_TIMEOUT)) {
+ 		if (atoi(value))
+ 			connection->query_timeout = atoi(value);
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index ae34f98..7620f5f 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.141 2009/10/01 09:48:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.142 2010/02/07 21:56:10 jklowden Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -204,8 +204,8 @@ tds_iconv_init(void)
+ /**
+  * Get iconv name given canonic
+  */
+-static void
+-tds_get_iconv_name(int charset)
++static const char *
++tds_set_iconv_name(int charset)
+ {
+ 	int i;
+ 	iconv_t cd;
+@@ -217,13 +217,13 @@ tds_get_iconv_name(int charset)
+ 	if (cd != (iconv_t) -1) {
+ 		iconv_names[charset] = canonic_charsets[charset].name;
+ 		tds_sys_iconv_close(cd);
+-		return;
++		return iconv_names[charset];
+ 	}
+ 	cd = tds_sys_iconv_open(ucs2name, canonic_charsets[charset].name);
+ 	if (cd != (iconv_t) -1) {
+ 		iconv_names[charset] = canonic_charsets[charset].name;
+ 		tds_sys_iconv_close(cd);
+-		return;
++		return iconv_names[charset];
+ 	}
+ 
+ 	/* try all alternatives */
+@@ -235,19 +235,20 @@ tds_get_iconv_name(int charset)
+ 		if (cd != (iconv_t) -1) {
+ 			iconv_names[charset] = iconv_aliases[i].alias;
+ 			tds_sys_iconv_close(cd);
+-			return;
++			return iconv_names[charset];
+ 		}
+ 
+ 		cd = tds_sys_iconv_open(ucs2name, iconv_aliases[i].alias);
+ 		if (cd != (iconv_t) -1) {
+ 			iconv_names[charset] = iconv_aliases[i].alias;
+ 			tds_sys_iconv_close(cd);
+-			return;
++			return iconv_names[charset];
+ 		}
+ 	}
+ 
+-	/* charset not found, use memcpy */
+-	iconv_names[charset] = "";
++	/* charset not found, pretend it's ISO 8859-1 */
++	iconv_names[charset] = canonic_charsets[POS_ISO1].name;
++	return NULL;
+ }
+ 
+ static void
+@@ -474,19 +475,19 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 	}
+ 
+ 	/* get iconv names */
+-	if (!iconv_names[client_canonical])
+-		tds_get_iconv_name(client_canonical);
+-	if (!iconv_names[server_canonical])
+-		tds_get_iconv_name(server_canonical);
+-
+-	/* names available ?? */
+-	if (!iconv_names[client_canonical][0] || !iconv_names[server_canonical][0]) {
+-		char_conv->to_wire = (iconv_t) -1;
+-		char_conv->from_wire = (iconv_t) -1;
+-		char_conv->flags = TDS_ENCODING_MEMCPY;
+-		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: use memcpy to convert \"%s\"->\"%s\"\n", client->name,
+-			    server->name);
+-		return 0;
++	if (!iconv_names[client_canonical]) {
++		if (!tds_set_iconv_name(client_canonical)) {
++			tdsdump_log(TDS_DBG_FUNC, "\"%s\" not supported by iconv, using \"%s\" instead\n",
++						  client_name, iconv_names[client_canonical]);
++		}
++	}
++	
++	assert(iconv_names[server_canonical]);
++	if (!iconv_names[server_canonical]) {
++		if (!tds_set_iconv_name(server_canonical)) {
++			tdsdump_log(TDS_DBG_FUNC, "\"%s\" not supported by iconv, using \"%s\" instead\n",
++						  server_name, iconv_names[server_canonical]);
++		}
+ 	}
+ 
+ 	char_conv->to_wire = tds_sys_iconv_open(iconv_names[server_canonical], iconv_names[client_canonical]);
+diff --git a/src/tds/login.c b/src/tds/login.c
+index ccca13c..3cbcaf9 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.194 2010/01/26 11:21:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.195 2010/02/07 21:56:10 jklowden Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -427,11 +427,6 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		return TDSECONN;
+ 	}
+ 
+-	if (connection->port && !tds_dstr_isempty(&connection->instance_name)) {
+-		tdserror(tds->tds_ctx, tds, TDSEPORTINSTANCE, 0);
+-		return TDSECONN;
+-	}
+-
+ 	if (!IS_TDS50(tds) && !tds_dstr_isempty(&connection->instance_name))
+ 		connection->port = tds7_get_instance_port(tds_dstr_cstr(&connection->ip_addr), tds_dstr_cstr(&connection->instance_name));
+ 
+diff --git a/src/tds/util.c b/src/tds/util.c
+index 45bdb7e..20935be 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.89 2010/01/11 18:14:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.90 2010/02/07 21:56:10 jklowden Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -255,7 +255,7 @@ static const TDS_ERROR_MESSAGE tds_error_messages[] =
+ 	, { TDSEICONVI,      EXCONVERSION,	"Some character(s) could not be converted into client's character set.  "
+ 						"Unconverted bytes were changed to question marks ('?')" }
+ 	, { TDSEICONV2BIG,   EXCONVERSION,	"Some character(s) could not be converted into client's character set" }
+-	, { TDSEPORTINSTANCE,      EXCOMM,      "Both port and instance specified" }
++	, { TDSEPORTINSTANCE,      EXUSER,      "Both port and instance specified" }
+ 	, { TDSERPND,           EXPROGRAM,	"Attempt to initiate a new Adaptive Server operation with results pending" }
+ 	, { TDSEBTOK,              EXCOMM,	"Bad token from the server: Datastream processing out of sync" }
+ 	, { TDSECAP,               EXCOMM,	"DB-Library capabilities not accepted by the Server" }
+
+commit 106110289c2021edb9fd6ffae4945fedbbd43d7b
+Author: freddy77 <freddy77>
+Date:   Mon Feb 8 09:48:08 2010 +0000
+
+    fix some memory problems
+
+diff --git a/ChangeLog b/ChangeLog
+index bddf737..4599d6e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Feb  8 10:46:55 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/config.c: fix some memory problems
++
+ Sun Feb  7 16:50:58 EST 2010	JK Lowden <jklowden@freetds.org>
+ 	* doc/userguide.sgml preparing for release
+ 	* src/apps/bsqlodbc.c use hdesc to detmine octet count
+@@ -2298,4 +2301,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2984 2010/02/07 21:55:48 jklowden Exp $
++$Id: ChangeLog,v 1.2985 2010/02/08 09:48:08 freddy77 Exp $
+diff --git a/src/tds/config.c b/src/tds/config.c
+index 678f35a..4b81e64 100644
+--- a/src/tds/config.c
++++ b/src/tds/config.c
+@@ -80,7 +80,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: config.c,v 1.158 2010/02/07 21:56:10 jklowden Exp $");
++TDS_RCSID(var, "$Id: config.c,v 1.159 2010/02/08 09:48:09 freddy77 Exp $");
+ 
+ static void tds_config_login(TDSCONNECTION * connection, TDSLOGIN * login);
+ static void tds_config_env_tdsdump(TDSCONNECTION * connection);
+@@ -380,7 +380,9 @@ tds_read_conf_file(TDSCONNECTION * connection, const char *server)
+ static int
+ tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection)
+ {
+-	TDSCONNECTION defaults;
++	DSTR default_instance;
++	int default_port;
++
+ 	int found;
+ 
+ 	tds_read_conf_section(in, "global", tds_parse_conf_section, connection);
+@@ -388,21 +390,25 @@ tds_read_conf_sections(FILE * in, const char *server, TDSCONNECTION * connection
+ 	if (!server[0])
+ 		return 0;
+ 	rewind(in);
+-	defaults = *connection;
++
++	tds_dstr_init(&default_instance);
++	tds_dstr_dup(&default_instance, &connection->instance_name);
++	default_port = connection->port;
+ 
+ 	found = tds_read_conf_section(in, server, tds_parse_conf_section, connection);
+-	
++
+ 	/* 
+ 	 * If both instance and port are specified and neither one came from the default, it's an error 
+ 	 * TODO: If port/instance is specified in the non-default, it has priority over the default setting. 
+ 	 * TODO: test this. 
+ 	 */
+-	if (!tds_dstr_isempty(&connection->instance_name) && connection->port && 
+-	  !(!tds_dstr_isempty(   &defaults.instance_name) ||    defaults.port)) {
++	if (!tds_dstr_isempty(&connection->instance_name) && connection->port &&
++	    !(!tds_dstr_isempty(&default_instance) || default_port)) {
+ 		tdsdump_log(TDS_DBG_ERROR, "error: cannot specify both port %d and instance %s.\n", 
+ 						connection->port, tds_dstr_cstr(&connection->instance_name));
+ 		/* tdserror(tds->tds_ctx, tds, TDSEPORTINSTANCE, 0); */
+ 	}
++	tds_dstr_free(&default_instance);
+ 	return found;
+ }
+ 
+
+commit 24a3f1d0fc10d2e90aeff7cf1fb63b1fd2dc291f
+Author: freddy77 <freddy77>
+Date:   Mon Feb 8 12:16:43 2010 +0000
+
+    remove wrong assert
+
+diff --git a/ChangeLog b/ChangeLog
+index 4599d6e..b202557 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Feb  8 13:15:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/iconv.c: remove wrong assert
++
+ Mon Feb  8 10:46:55 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/config.c: fix some memory problems
+ 
+@@ -2301,4 +2304,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2985 2010/02/08 09:48:08 freddy77 Exp $
++$Id: ChangeLog,v 1.2986 2010/02/08 12:16:43 freddy77 Exp $
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 7620f5f..ff53b8a 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.142 2010/02/07 21:56:10 jklowden Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.143 2010/02/08 12:16:43 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -482,7 +482,6 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 		}
+ 	}
+ 	
+-	assert(iconv_names[server_canonical]);
+ 	if (!iconv_names[server_canonical]) {
+ 		if (!tds_set_iconv_name(server_canonical)) {
+ 			tdsdump_log(TDS_DBG_FUNC, "\"%s\" not supported by iconv, using \"%s\" instead\n",
+
+commit fac0376ca1f1fdd777fbcc661e200ebc00e64c16
+Author: freddy77 <freddy77>
+Date:   Mon Feb 8 16:12:35 2010 +0000
+
+    added Visual C++ project for CTLib (patch from David Dick)
+
+diff --git a/ChangeLog b/ChangeLog
+index b202557..3382276 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Feb  8 17:09:49 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/msvc6/FreeTDS.dsw win32/msvc6/Makefile.am:
++	* win32/msvc6/libct.dsp:
++	- added Visual C++ project for CTLib (patch from David Dick)
++
+ Mon Feb  8 13:15:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/iconv.c: remove wrong assert
+ 
+@@ -2304,4 +2309,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2986 2010/02/08 12:16:43 freddy77 Exp $
++$Id: ChangeLog,v 1.2987 2010/02/08 16:12:35 freddy77 Exp $
+diff --git a/win32/msvc6/FreeTDS.dsw b/win32/msvc6/FreeTDS.dsw
+index 8f3341f..db86aef 100644
+--- a/win32/msvc6/FreeTDS.dsw
++++ b/win32/msvc6/FreeTDS.dsw
+@@ -45,6 +45,21 @@ Package=<4>
+ 
+ ###############################################################################
+ 
++Project: "libct"=".\libct.dsp" - Package Owner=<4>
++
++Package=<5>
++{{{
++}}}
++
++Package=<4>
++{{{
++    Begin Project Dependency
++    Project_Dep_Name libTDS
++    End Project Dependency
++}}}
++
++###############################################################################
++
+ Global:
+ 
+ Package=<5>
+diff --git a/win32/msvc6/Makefile.am b/win32/msvc6/Makefile.am
+index 8950e5a..39aefda 100644
+--- a/win32/msvc6/Makefile.am
++++ b/win32/msvc6/Makefile.am
+@@ -1,3 +1,3 @@
+ EXTRA_DIST	= FreeTDS.dsp FreeTDS.dsw iconv_replacement.c \
+-		libTDS.dsp dblib.dsp
++		libTDS.dsp dblib.dsp libct.dsp
+ 
+diff --git a/win32/msvc6/libct.dsp b/win32/msvc6/libct.dsp
+new file mode 100644
+index 0000000..1b070a8
+--- /dev/null
++++ b/win32/msvc6/libct.dsp
+@@ -0,0 +1,108 @@
++# Microsoft Developer Studio Project File - Name="libct" - Package Owner=<4>
++# Microsoft Developer Studio Generated Build File, Format Version 6.00
++# ** DO NOT EDIT **
++
++# TARGTYPE "Win32 (x86) Static Library" 0x0104
++
++CFG=libct - Win32 Debug
++!MESSAGE This is not a valid makefile. To build this project using NMAKE,
++!MESSAGE use the Export Makefile command and run
++!MESSAGE 
++!MESSAGE NMAKE /f "libct.mak".
++!MESSAGE 
++!MESSAGE You can specify a configuration when running NMAKE
++!MESSAGE by defining the macro CFG on the command line. For example:
++!MESSAGE 
++!MESSAGE NMAKE /f "libct.mak" CFG="libct - Win32 Debug"
++!MESSAGE 
++!MESSAGE Possible choices for configuration are:
++!MESSAGE 
++!MESSAGE "libct - Win32 Release" (based on "Win32 (x86) Static Library")
++!MESSAGE "libct - Win32 Debug" (based on "Win32 (x86) Static Library")
++!MESSAGE 
++
++# Begin Project
++# PROP AllowPerConfigDependencies 0
++# PROP Scc_ProjName ""
++# PROP Scc_LocalPath ""
++CPP=cl.exe
++RSC=rc.exe
++
++!IF  "$(CFG)" == "libct - Win32 Release"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 0
++# PROP BASE Output_Dir "ct_Release"
++# PROP BASE Intermediate_Dir "ct_Release"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 0
++# PROP Output_Dir "ct_Release"
++# PROP Intermediate_Dir "ct_Release"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_MBCS" /D "_LIB" /Yu"stdafx.h" /FD /c
++# ADD CPP /nologo /MD /W3 /GX /O2 /I ".." /I "../../include" /I "../../src" /D "HAVE_CONFIG_H" /D "UNIXODBC" /D "_FREETDS_LIBRARY_SOURCE" /D "WIN32" /D "NDEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FREETDS_EXPORTS" /D "HAVE_SQLGETPRIVATEPROFILESTRING" /FR"ct_Release/" /Fp"ct_Release/libct.pch" /YX /Fo"ct_Release/" /Fd"ct_Release/" /FD /c
++# ADD BASE RSC /l 0xc09 /d "NDEBUG"
++# ADD RSC /l 0xc09 /d "NDEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LIB32=link.exe -lib
++# ADD BASE LIB32 /nologo
++# ADD LIB32 /nologo
++
++!ELSEIF  "$(CFG)" == "libct - Win32 Debug"
++
++# PROP BASE Use_MFC 0
++# PROP BASE Use_Debug_Libraries 1
++# PROP BASE Output_Dir "Debug"
++# PROP BASE Intermediate_Dir "Debug"
++# PROP BASE Target_Dir ""
++# PROP Use_MFC 0
++# PROP Use_Debug_Libraries 1
++# PROP Output_Dir "ct_Debug"
++# PROP Intermediate_Dir "ct_Debug"
++# PROP Target_Dir ""
++# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_MBCS" /D "_LIB" /Yu"stdafx.h" /FD /GZ /c
++# ADD CPP /nologo /MTd /W3 /Gm /GX /ZI /Od /I ".." /I "../../include" /D "HAVE_CONFIG_H" /D "UNIXODBC" /D "_FREETDS_LIBRARY_SOURCE" /D "WIN32" /D "_DEBUG" /D "_WINDOWS" /D "_MBCS" /D "_USRDLL" /D "FREETDS_EXPORTS" /D "HAVE_SQLGETPRIVATEPROFILESTRING" /FR /Fp"ct_Debug/ctlib.pch" /YX /FD /GZ /c
++# ADD BASE RSC /l 0xc09 /d "_DEBUG"
++# ADD RSC /l 0xc09 /d "_DEBUG"
++BSC32=bscmake.exe
++# ADD BASE BSC32 /nologo
++# ADD BSC32 /nologo
++LIB32=link.exe -lib
++# ADD BASE LIB32 /nologo
++# ADD LIB32 /nologo
++
++!ENDIF 
++
++# Begin Target
++
++# Name "libct - Win32 Release"
++# Name "libct - Win32 Debug"
++# Begin Group "Source Files"
++
++# PROP Default_Filter "cpp;c;cxx;rc;def;r;odl;idl;hpj;bat"
++# Begin Source File
++
++SOURCE=..\..\src\ctlib\blk.c
++# End Source File
++# Begin Source File
++
++SOURCE=..\..\src\ctlib\cs.c
++# End Source File
++# Begin Source File
++
++SOURCE=..\..\src\ctlib\ct.c
++# End Source File
++# Begin Source File
++
++SOURCE=..\..\src\ctlib\ctutil.c
++# End Source File
++# End Group
++# Begin Group "Header Files"
++
++# PROP Default_Filter "h;hpp;hxx;hm;inl"
++# End Group
++# End Target
++# End Project
+
+commit 3e6908f3cc7765303380c39293fde42279a226e0
+Author: freddy77 <freddy77>
+Date:   Tue Feb 9 08:40:07 2010 +0000
+
+    add _snprintf define for windows (patch from David Dick)
+
+diff --git a/ChangeLog b/ChangeLog
+index 3382276..6f62bc4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Feb  9 09:39:15 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h:
++	- add _snprintf define for windows (patch from David Dick)
++
+ Mon Feb  8 17:09:49 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/msvc6/FreeTDS.dsw win32/msvc6/Makefile.am:
+ 	* win32/msvc6/libct.dsp:
+@@ -2309,4 +2313,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2987 2010/02/08 16:12:35 freddy77 Exp $
++$Id: ChangeLog,v 1.2988 2010/02/09 08:40:07 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index b711448..dbe30e2 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.31 2010/01/09 23:41:52 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.32 2010/02/09 08:40:07 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -94,6 +94,7 @@ typedef DWORD pid_t;
+ #define strncasecmp strnicmp
+ #define atoll _atoi64
+ #define vsnprintf _vsnprintf
++#define snprintf _snprintf
+ 
+ #ifndef WIN32
+ #define WIN32 1
+
+commit 8dafd508bb0b4d02ce082e57dab83c46c21ac79f
+Author: freddy77 <freddy77>
+Date:   Fri Feb 12 08:57:01 2010 +0000
+
+    restrict some describecol checks to mssql only
+
+diff --git a/ChangeLog b/ChangeLog
+index 6f62bc4..7dafb0c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Feb 12 09:56:42 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/describecol.in:
++	- restrict some describecol checks to mssql only
++
+ Tue Feb  9 09:39:15 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h:
+ 	- add _snprintf define for windows (patch from David Dick)
+@@ -2313,4 +2317,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2988 2010/02/09 08:40:07 freddy77 Exp $
++$Id: ChangeLog,v 1.2989 2010/02/12 08:57:01 freddy77 Exp $
+diff --git a/src/odbc/unittests/describecol.in b/src/odbc/unittests/describecol.in
+index d4ae363..f8217c1 100644
+--- a/src/odbc/unittests/describecol.in
++++ b/src/odbc/unittests/describecol.in
+@@ -152,7 +152,7 @@ attr SQL_DESC_PRECISION 11
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 11
+ 
+-select nchar(12) 'hi!'
++select nchar(12) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 24
+ attr SQL_COLUMN_PRECISION 12
+ attr SQL_COLUMN_SCALE 0
+@@ -162,7 +162,7 @@ attr SQL_DESC_PRECISION 12
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 12
+ 
+-select nvarchar(13) 'hi!'
++select nvarchar(13) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 26
+ attr SQL_COLUMN_PRECISION 13
+ attr SQL_COLUMN_SCALE 0
+@@ -378,7 +378,7 @@ attr SQL_DESC_PRECISION 11
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 11
+ 
+-select nchar(12) 'hi!'
++select nchar(12) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 24
+ attr SQL_COLUMN_PRECISION 12
+ attr SQL_COLUMN_SCALE 0
+@@ -388,7 +388,7 @@ attr SQL_DESC_PRECISION 12
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 12
+ 
+-select nvarchar(13) 'hi!'
++select nvarchar(13) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 26
+ attr SQL_COLUMN_PRECISION 13
+ attr SQL_COLUMN_SCALE 0
+
+commit 57bf45694e0e64f3b7332197fc03ca8cfe31d35d
+Author: freddy77 <freddy77>
+Date:   Fri Feb 12 09:04:58 2010 +0000
+
+    additional check for SQLDescribeCol length
+
+diff --git a/ChangeLog b/ChangeLog
+index 7dafb0c..6cee56c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Feb 12 10:04:15 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/describecol.c:
++	- additional check for SQLDescribeCol length
++
+ Fri Feb 12 09:56:42 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/describecol.in:
+ 	- restrict some describecol checks to mssql only
+@@ -2317,4 +2321,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2989 2010/02/12 08:57:01 freddy77 Exp $
++$Id: ChangeLog,v 1.2990 2010/02/12 09:04:58 freddy77 Exp $
+diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c
+index b521dd5..0fad864 100644
+--- a/src/odbc/unittests/describecol.c
++++ b/src/odbc/unittests/describecol.c
+@@ -6,7 +6,7 @@
+  * test what say SQLDescribeCol about precision using some type
+  */
+ 
+-static char software_version[] = "$Id: describecol.c,v 1.16 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: describecol.c,v 1.17 2010/02/12 09:04:58 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -152,6 +152,14 @@ get_attr_ird(ATTR_PARAMS)
+ 	ret = SQLColAttribute(Statement, 1, attr->value, NULL, SQL_IS_INTEGER, NULL, &i);
+ 	if (!SQL_SUCCEEDED(ret))
+ 		fatal("Line %u: failure not expected\n", line_num);
++	/* SQL_DESC_LENGTH is the same of SQLDescribeCol len */
++	if (attr->value == SQL_DESC_LENGTH) {
++		SQLSMALLINT si;
++		SQLULEN li;
++		CHKDescribeCol(1, NULL, 0, NULL, &si, &li, &si, &si, "S");
++		if (i != li)
++			fatal("Line %u: attr %s SQLDescribeCol len %ld != SQLColAttribute len %ld\n", line_num, attr->name, (long) li, (long) i);
++	}
+ 	return i;
+ }
+ 
+
+commit e80da3c958bf2636abfb4e0e2b1874836f976531
+Author: freddy77 <freddy77>
+Date:   Fri Feb 12 10:16:16 2010 +0000
+
+    remove some warnings compiling for windows
+
+diff --git a/ChangeLog b/ChangeLog
+index 6cee56c..29d0c45 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Feb 12 11:15:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsthread.h src/dblib/bcp.c src/tds/sspi.c:
++	* src/tds/win_mutex.c:
++	- remove some warnings compiling for windows
++
+ Fri Feb 12 10:04:15 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/describecol.c:
+ 	- additional check for SQLDescribeCol length
+@@ -2321,4 +2326,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2990 2010/02/12 09:04:58 freddy77 Exp $
++$Id: ChangeLog,v 1.2991 2010/02/12 10:16:16 freddy77 Exp $
+diff --git a/include/tdsthread.h b/include/tdsthread.h
+index b4249f1..92a17b8 100644
+--- a/include/tdsthread.h
++++ b/include/tdsthread.h
+@@ -22,7 +22,7 @@
+ #ifndef TDSTHREAD_H
+ #define TDSTHREAD_H 1
+ 
+-/* $Id: tdsthread.h,v 1.6 2010/01/28 13:31:51 freddy77 Exp $ */
++/* $Id: tdsthread.h,v 1.7 2010/02/12 10:16:17 freddy77 Exp $ */
+ 
+ #undef TDS_HAVE_MUTEX
+ 
+@@ -38,8 +38,10 @@
+ 
+ #elif defined(_WIN32)
+ 
++struct ptw32_mcs_node_t_;
++
+ typedef struct tds_win_mutex_t_ {
+-	void *lock;
++	struct ptw32_mcs_node_t_ *lock;
+ 	LONG done;
+ 	CRITICAL_SECTION crit;
+ } tds_win_mutex_t;
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index 76bc931..c0c4a30 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -62,7 +62,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.193 2010/01/27 23:15:39 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.194 2010/02/12 10:16:17 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -70,10 +70,10 @@ typedef off_t offset_type;
+ /* win32 version */
+ typedef __int64 offset_type;
+ # if defined(HAVE__FSEEKI64) && defined(HAVE__FTELLI64)
+-#  define fseeko(f,o,w) (_fseeki64((f),o,w) == -1)
++#  define fseeko(f,o,w) _fseeki64((f),o,w)
+ #  define ftello(f) _ftelli64((f))
+ # else
+-#  define fseeko(f,o,w) (_lseeki64(fileno(f),o,w) == -1)
++#  define fseeko(f,o,w) (_lseeki64(fileno(f),o,w) == -1 ? -1 : 0)
+ #  define ftello(f) _telli64(fileno(f))
+ # endif
+ #else
+diff --git a/src/tds/sspi.c b/src/tds/sspi.c
+index 89c4222..d20dbfa 100644
+--- a/src/tds/sspi.c
++++ b/src/tds/sspi.c
+@@ -46,7 +46,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sspi.c,v 1.7 2010/01/28 10:07:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sspi.c,v 1.8 2010/02/12 10:16:17 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -251,10 +251,7 @@ tds_sspi_get_auth(TDSSOCKET * tds)
+ 	/* build SPN */
+ 	server_name = tds_dstr_cstr(&connection->server_host_name);
+ 	if (strchr(server_name, '.') == NULL) {
+-		struct hostent result;
+-		int h_errnop;
+-
+-		struct hostent *host = tds_gethostbyname_r(server_name, &result, auth->tds_auth.packet, NTLMBUF_LEN, &h_errnop);
++		struct hostent *host = gethostbyname(server_name);
+ 		if (host && strchr(host->h_name, '.') != NULL)
+ 			server_name = host->h_name;
+ 	}
+diff --git a/src/tds/win_mutex.c b/src/tds/win_mutex.c
+index c1bba58..98be970 100644
+--- a/src/tds/win_mutex.c
++++ b/src/tds/win_mutex.c
+@@ -34,7 +34,7 @@
+ #include "tds.h"
+ #include "tdsthread.h"
+ 
+-TDS_RCSID(var, "$Id: win_mutex.c,v 1.1 2010/01/27 15:32:04 freddy77 Exp $");
++TDS_RCSID(var, "$Id: win_mutex.c,v 1.2 2010/02/12 10:16:17 freddy77 Exp $");
+ 
+ #include "ptw32_MCS_lock.c"
+ 
+@@ -44,7 +44,7 @@ tds_win_mutex_lock(tds_win_mutex_t * mutex)
+ 	if (!InterlockedExchangeAdd(&mutex->done, 0)) {	/* MBR fence */
+ 		ptw32_mcs_local_node_t node;
+ 
+-		ptw32_mcs_lock_acquire((ptw32_mcs_lock_t *) &mutex->lock, &node);
++		ptw32_mcs_lock_acquire(&mutex->lock, &node);
+ 		if (!mutex->done) {
+ 			InitializeCriticalSection(&mutex->crit);
+ 			mutex->done = 1;
+
+commit 081e5be0ba2c31e3cd8e0c69bdfbc9079debdc16
+Author: freddy77 <freddy77>
+Date:   Mon Mar 1 12:38:09 2010 +0000
+
+    remove some exit calls (original patch from David Dick)
+
+diff --git a/ChangeLog b/ChangeLog
+index 29d0c45..1c2b201 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Mar  1 13:37:28 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/login.c src/tds/net.c src/tds/token.c:
++	- remove some exit calls (original patch from David Dick)
++
+ Fri Feb 12 11:15:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsthread.h src/dblib/bcp.c src/tds/sspi.c:
+ 	* src/tds/win_mutex.c:
+@@ -2326,4 +2330,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2991 2010/02/12 10:16:16 freddy77 Exp $
++$Id: ChangeLog,v 1.2992 2010/03/01 12:38:09 freddy77 Exp $
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 3cbcaf9..6fa7650 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.195 2010/02/07 21:56:10 jklowden Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.196 2010/03/01 12:38:10 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -573,7 +573,7 @@ tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		memcpy(program_version, "\005\000\000\000", 4);
+ 	} else {
+ 		tdsdump_log(TDS_DBG_SEVERE, "Unknown protocol version!\n");
+-		exit(1);
++		return TDS_FAIL;
+ 	}
+ 	/*
+ 	 * the following code is adapted from  Arno Pedusaar's 
+diff --git a/src/tds/net.c b/src/tds/net.c
+index f1f1b76..953f576 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.101 2010/01/28 13:15:21 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.102 2010/03/01 12:38:10 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -464,8 +464,7 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 			default:
+ 				tdsdump_log(TDS_DBG_NETWORK, 
+ 					"tds_select: invalid interupt handler return code: %d\n", timeout_action);
+-				exit(EXIT_FAILURE);
+-				break;
++				return -1;
+ 			}
+ 		}
+ 		/* 
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 22ad851..54a2b50 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.379 2010/01/22 10:43:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.380 2010/03/01 12:38:10 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -3280,10 +3280,10 @@ tds5_process_optioncmd(TDSSOCKET * tds)
+ 		arg = tds_get_int(tds);
+ 		break;
+ 	default:
+-		tdsdump_log(TDS_DBG_INFO1, "oops: cannot process option of size %d\n", argsize);
+-		assert(argsize <= 4);
+-		exit(1);	 /* FIXME: stream would become desynchronized */
+-		break;
++		tdsdump_log(TDS_DBG_INFO1, "oops: cannot process option %d of size %d\n", option, argsize);
++		/* ignore argument */
++		tds_get_n(tds, NULL, argsize);
++		return TDS_FAIL;
+ 	}
+ 	tdsdump_log(TDS_DBG_INFO1, "received option %d value %d\n", option, arg);
+ 
+
+commit 28729f16743ef229b9213584463e932a21f27016
+Author: freddy77 <freddy77>
+Date:   Mon Mar 1 14:33:04 2010 +0000
+
+    ported freeclose test to Windows
+
+diff --git a/ChangeLog b/ChangeLog
+index 1c2b201..924e458 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar  1 15:32:43 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c: ported freeclose test to Windows
++
+ Mon Mar  1 13:37:28 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/login.c src/tds/net.c src/tds/token.c:
+ 	- remove some exit calls (original patch from David Dick)
+@@ -2330,4 +2333,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2992 2010/03/01 12:38:09 freddy77 Exp $
++$Id: ChangeLog,v 1.2993 2010/03/01 14:33:04 freddy77 Exp $
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 1098546..8c96e81 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -43,18 +43,21 @@
+ #include <netinet/in.h>
+ #endif /* HAVE_NETINET_IN_H */
+ 
+-#if defined(TDS_HAVE_PTHREAD_MUTEX) && HAVE_ALARM && HAVE_FSTAT && defined(S_IFSOCK)
++#if (defined(TDS_HAVE_PTHREAD_MUTEX) && HAVE_ALARM && HAVE_FSTAT && defined(S_IFSOCK)) || defined(_WIN32)
+ 
+ #include <ctype.h>
++#if HAVE_PTHREAD
+ #include <pthread.h>
++#endif
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.10 2009/02/27 10:11:42 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.11 2010/03/01 14:33:04 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+ 
++#ifndef _WIN32
+ static int
+ find_last_socket(void)
+ {
+@@ -69,21 +72,47 @@ find_last_socket(void)
+ 	}
+ 	return max_socket;
+ }
++#else
++static TDS_SYS_SOCKET
++find_last_socket(void)
++{
++	TDS_SYS_SOCKET max_socket = INVALID_SOCKET;
++	int i;
++
++	for (i = 4; i <= (4096*4); i += 4) {
++		struct sockaddr addr;
++		socklen_t addr_len;
++
++		if (tds_getpeername((TDS_SYS_SOCKET) i, &addr, &addr_len))
++			continue;
++		max_socket = (TDS_SYS_SOCKET) i;
++	}
++	
++	return max_socket;
++}
++#endif
+ 
+ static struct sockaddr remote_addr;
+-socklen_t remote_addr_len;
++static socklen_t remote_addr_len;
+ 
+-static pthread_t      fake_thread;
+ static TDS_SYS_SOCKET fake_sock;
+ 
+-static void *fake_thread_proc(void * arg);
++#ifndef _WIN32
++static pthread_t      fake_thread;
++#define THREADAPI
++#else
++static HANDLE fake_thread;
++#define THREADAPI WINAPI
++#define pthread_join(th,fl) WaitForSingleObject(th,INFINITE)
++#define alarm(n) do { ; } while(0)
++#endif
++static void* THREADAPI fake_thread_proc(void *arg);
+ 
+ static int
+ init_fake_server(int ip_port)
+ {
+ 	struct sockaddr_in sin;
+ 	TDS_SYS_SOCKET s;
+-	int err;
+ 
+ 	memset(&sin, 0, sizeof(sin));
+ 	sin.sin_addr.s_addr = INADDR_ANY;
+@@ -100,11 +129,18 @@ init_fake_server(int ip_port)
+ 		return 1;
+ 	}
+ 	listen(s, 5);
+-	err = pthread_create(&fake_thread, NULL, fake_thread_proc, int2ptr(s));
+-	if (err != 0) {
++#ifndef _WIN32
++	if (pthread_create(&fake_thread, NULL, fake_thread_proc, int2ptr(s)) != 0) {
+ 		perror("pthread_create");
+ 		exit(1);
+ 	}
++#else
++	fake_thread = CreateThread(NULL, 0, fake_thread_proc, int2ptr(s), 0, NULL);
++	if (!fake_thread) {
++		fprintf(stderr, "CreateThread error %u\n", (unsigned) GetLastError());
++		exit(1);
++	}
++#endif
+ 	return 0;
+ }
+ 
+@@ -175,7 +211,7 @@ count_insert(const char* buf, size_t len)
+ static unsigned int round_trips = 0;
+ static enum { sending, receiving } flow = sending;
+ 
+-static void *
++static void *THREADAPI
+ fake_thread_proc(void * arg)
+ {
+ 	TDS_SYS_SOCKET s = ptr2int(arg), server_sock;
+@@ -225,7 +261,7 @@ fake_thread_proc(void * arg)
+ 		res = select(max_fd + 1, &fds_read, &fds_write, &fds_error, NULL);
+ 		alarm(0);
+ 		if (res < 0) {
+-			if (errno == EINTR)
++			if (sock_errno == TDSSOCK_EINTR)
+ 				continue;
+ 			perror("select");
+ 			exit(1);
+@@ -276,13 +312,19 @@ main(int argc, char **argv)
+ 	const char *query;
+ 	SQLINTEGER id = 0;
+ 	char string[64];
+-	int last_socket, port;
++	TDS_SYS_SOCKET last_socket;
++	int port;
+ 	const int num_inserts = 20;
+ 
++#ifdef _WIN32
++	WSADATA wsaData;
++	WSAStartup(MAKEWORD(1, 1), &wsaData);
++#endif
++
+ 	Connect();
+ 
+ 	last_socket = find_last_socket();
+-	if (last_socket < 0) {
++	if (TDS_IS_SOCKET_INVALID(last_socket)) {
+ 		fprintf(stderr, "Error finding last socket opened\n");
+ 		return 1;
+ 	}
+@@ -306,11 +348,23 @@ main(int argc, char **argv)
+ 	printf("Fake server binded at port %d\n", port);
+ 
+ 	/* override connections */
+-	setenv("TDSHOST", "127.0.0.1", 1);
+-	sprintf(string, "%d", port);
+-	setenv("TDSPORT", string, 1);
+-
+-	Connect();
++	if (driver_is_freetds()) {
++		setenv("TDSHOST", "127.0.0.1", 1);
++		sprintf(string, "%d", port);
++		setenv("TDSPORT", string, 1);
++
++		Connect();
++	} else {
++		char tmp[2048];
++		SQLSMALLINT len;
++
++		CHKAllocEnv(&Environment, "S");
++		CHKAllocConnect(&Connection, "S");
++		sprintf(tmp, "DRIVER={SQL Server};SERVER=127.0.0.1,%d;UID=%s;PWD=%s;DATABASE=%s;Network=DBMSSOCN;", port, USER, PASSWORD, DATABASE);
++		printf("connection string: %s\n", tmp);
++		CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
++		CHKAllocStmt(&Statement, "S");
++	}
+ 
+ 	/* real test */
+ 	Command("CREATE TABLE #test(i int, c varchar(40))");
+
+commit 7f9e807234aef812d1ce1fdc7356e53ec22874dc
+Author: freddy77 <freddy77>
+Date:   Mon Mar 1 14:50:55 2010 +0000
+
+    update for future implementations
+
+diff --git a/ChangeLog b/ChangeLog
+index 924e458..997d25b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Mar  1 15:50:06 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/prepclose.c src/odbc/unittests/timeout3.c:
++	* src/odbc/unittests/timeout4.c:
++	- update for future implementations
++
+ Mon Mar  1 15:32:43 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/freeclose.c: ported freeclose test to Windows
+ 
+@@ -2333,4 +2338,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2993 2010/03/01 14:33:04 freddy77 Exp $
++$Id: ChangeLog,v 1.2994 2010/03/01 14:50:55 freddy77 Exp $
+diff --git a/src/odbc/unittests/prepclose.c b/src/odbc/unittests/prepclose.c
+index 8fa19ba..c68edb9 100644
+--- a/src/odbc/unittests/prepclose.c
++++ b/src/odbc/unittests/prepclose.c
+@@ -26,7 +26,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: prepclose.c,v 1.5 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: prepclose.c,v 1.6 2010/03/01 14:50:55 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -75,10 +75,14 @@ Test(int direct)
+ 	}
+ 
+ 	/* force disconnection closing socket */
+-	if (direct)
++	if (direct) {
+ 		CHKExecDirect((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
+-	else
+-		CHKPrepare((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
++	} else {
++		SQLSMALLINT cols;
++		/* use prepare, force dialog with server */
++		if (CHKPrepare((SQLCHAR *) "SELECT 1", SQL_NTS, "SE") == SQL_SUCCESS)
++			CHKNumResultCols(&cols, "E");
++	}
+ 
+ 	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	sqlstate[5] = 0;
+diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c
+index b10e03e..5f87079 100644
+--- a/src/odbc/unittests/timeout3.c
++++ b/src/odbc/unittests/timeout3.c
+@@ -40,7 +40,7 @@
+ 	test connection timeout
+ */
+ 
+-static char software_version[] = "$Id: timeout3.c,v 1.10 2009/02/27 10:11:42 freddy77 Exp $";
++static char software_version[] = "$Id: timeout3.c,v 1.11 2010/03/01 14:50:55 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -99,7 +99,7 @@ fake_thread_proc(void * arg)
+ 	memset(&sin, 0, sizeof(sin));
+ 	len = sizeof(sin);
+ 	alarm(30);
+-	if ((fake_sock = tds_accept(s, (struct sockaddr *) &sin, &len)) < 0) {
++	if (TDS_IS_SOCKET_INVALID(fake_sock = tds_accept(s, (struct sockaddr *) &sin, &len))) {
+ 		perror("accept");
+ 		exit(1);
+ 	}
+diff --git a/src/odbc/unittests/timeout4.c b/src/odbc/unittests/timeout4.c
+index cb0cbea..2bafe7d 100644
+--- a/src/odbc/unittests/timeout4.c
++++ b/src/odbc/unittests/timeout4.c
+@@ -39,7 +39,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: timeout4.c,v 1.4 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: timeout4.c,v 1.5 2010/03/01 14:50:55 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -94,10 +94,14 @@ Test(int direct)
+ 
+ 	alarm(30);
+ 	start_time = time(NULL);
+-	if (direct)
++	if (direct) {
+ 		CHKExecDirect((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
+-	else
+-		CHKPrepare((SQLCHAR *) "SELECT 1", SQL_NTS, "E");
++	} else {
++		SQLSMALLINT cols;
++		/* force dialog with server */
++		if (CHKPrepare((SQLCHAR *) "SELECT 1", SQL_NTS, "SE") == SQL_SUCCESS)
++			CHKNumResultCols(&cols, "E");
++	}
+ 	end_time = time(NULL);
+ 	alarm(0);
+ 
+
+commit 64a02a09f672c870a36961b23ccbbeb00ff227ba
+Author: freddy77 <freddy77>
+Date:   Mon Mar 1 14:52:52 2010 +0000
+
+    fix FreeTDS detection
+
+diff --git a/ChangeLog b/ChangeLog
+index 997d25b..c7aafc9 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar  1 15:52:14 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/freeclose.c: fix FreeTDS detection
++
+ Mon Mar  1 15:50:06 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/prepclose.c src/odbc/unittests/timeout3.c:
+ 	* src/odbc/unittests/timeout4.c:
+@@ -2338,4 +2341,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2994 2010/03/01 14:50:55 freddy77 Exp $
++$Id: ChangeLog,v 1.2995 2010/03/01 14:52:52 freddy77 Exp $
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 8c96e81..3367912 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -52,7 +52,7 @@
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.11 2010/03/01 14:33:04 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.12 2010/03/01 14:52:52 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+@@ -315,6 +315,7 @@ main(int argc, char **argv)
+ 	TDS_SYS_SOCKET last_socket;
+ 	int port;
+ 	const int num_inserts = 20;
++	int is_freetds;
+ 
+ #ifdef _WIN32
+ 	WSADATA wsaData;
+@@ -335,6 +336,7 @@ main(int argc, char **argv)
+ 		return 1;
+ 	}
+ 
++	is_freetds = driver_is_freetds();
+ 	Disconnect();
+ 
+ 	/* init fake server, behave like a proxy */
+@@ -348,7 +350,7 @@ main(int argc, char **argv)
+ 	printf("Fake server binded at port %d\n", port);
+ 
+ 	/* override connections */
+-	if (driver_is_freetds()) {
++	if (is_freetds) {
+ 		setenv("TDSHOST", "127.0.0.1", 1);
+ 		sprintf(string, "%d", port);
+ 		setenv("TDSPORT", string, 1);
+
+commit 31d73e474f4acd348a3d424c1d21b7471e8ea500
+Author: freddy77 <freddy77>
+Date:   Tue Mar 2 08:32:36 2010 +0000
+
+    remove last exit calls (original patch from David Dick)
+
+diff --git a/ChangeLog b/ChangeLog
+index c7aafc9..a09665d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Mar  2 09:32:02 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/util.c:
++	- remove last exit calls (original patch from David Dick)
++
+ Mon Mar  1 15:52:14 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/freeclose.c: fix FreeTDS detection
+ 
+@@ -2341,4 +2345,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2995 2010/03/01 14:52:52 freddy77 Exp $
++$Id: ChangeLog,v 1.2996 2010/03/02 08:32:36 freddy77 Exp $
+diff --git a/src/tds/util.c b/src/tds/util.c
+index 20935be..fffe149 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.90 2010/02/07 21:56:10 jklowden Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.91 2010/03/02 08:32:36 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -374,18 +374,12 @@ tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum)
+ 	}
+ 
+   
+-  	assert(!(msgno != TDSETIME && rc == TDS_INT_TIMEOUT));   /* client library should prevent */
+-	assert(!(msgno != TDSETIME && rc == TDS_INT_CONTINUE));  /* client library should prevent */
+-	
+-	if (msgno != TDSETIME) {
+-		switch(rc) {
+-		case TDS_INT_TIMEOUT:
+-		case TDS_INT_CONTINUE:
+-		 	tdsdump_log(TDS_DBG_FUNC, "exit: %s(%d) valid only for TDSETIME\n", retname(rc), rc);
+-			exit(1);
+-		default:
+-			break;
+-		}
++  	assert(msgno == TDSETIME || rc != TDS_INT_TIMEOUT);   /* client library should prevent */
++	assert(msgno == TDSETIME || rc != TDS_INT_CONTINUE);  /* client library should prevent */
++
++	if (msgno != TDSETIME && rc != TDS_INT_CANCEL) {
++		tdsdump_log(TDS_DBG_SEVERE, "exit: %s(%d) valid only for TDSETIME\n", retname(rc), rc);
++		rc = TDS_INT_CANCEL;
+ 	}
+ 
+  	if (rc == TDS_INT_TIMEOUT) {
+
+commit 01494d245d8c197788c34c96e4af62ab1a9e7ed1
+Author: freddy77 <freddy77>
+Date:   Tue Mar 2 15:07:00 2010 +0000
+
+    add ReadError and reuse it
+
+diff --git a/ChangeLog b/ChangeLog
+index a09665d..ca587e0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Tue Mar  2 16:06:34 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
++	* src/odbc/unittests/error.c src/odbc/unittests/getdata.c:
++	* src/odbc/unittests/paramcore.c src/odbc/unittests/print.c:
++	* src/odbc/unittests/rowset.c src/odbc/unittests/transaction2.c:
++	- add ReadError and reuse it
++
+ Tue Mar  2 09:32:02 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/util.c:
+ 	- remove last exit calls (original patch from David Dick)
+@@ -2345,4 +2352,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2996 2010/03/02 08:32:36 freddy77 Exp $
++$Id: ChangeLog,v 1.2997 2010/03/02 15:07:00 freddy77 Exp $
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index cb75715..a2f7f70 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -12,7 +12,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.56 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.57 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -441,3 +441,15 @@ CommandProc(HSTMT stmt, const char *command, const char *file, int line, const c
+ 	return CheckRes(file, line, SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS), SQL_HANDLE_STMT, stmt, "Command", res);
+ }
+ 
++char odbc_err[512];
++char odbc_sqlstate[6];
++
++void
++ReadError(void)
++{
++	memset(odbc_err, 0, sizeof(odbc_err));
++	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
++	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
++	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
++}
++
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 22382b7..8c449cd 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.30 2010/01/10 14:43:11 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.31 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -38,6 +38,9 @@ extern HDBC Connection;
+ extern HSTMT Statement;
+ extern int use_odbc_version3;
+ extern void (*odbc_set_conn_attr)(void);
++extern char odbc_err[512];
++extern char odbc_sqlstate[6];
++
+ 
+ extern char USER[512];
+ extern char SERVER[512];
+@@ -47,6 +50,8 @@ extern char DRIVER[1024];
+ 
+ int read_login_info(void);
+ void ReportError(const char *msg, int line, const char *file);
++void ReadError(void);
++
+ 
+ void CheckCols(int n, int line, const char * file);
+ void CheckRows(int n, int line, const char * file);
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index f7d8e76..5a8785d 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,19 +2,9 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.9 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.10 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static SQLCHAR output[256];
+-static void ReadError(void);
+-
+-static void
+-ReadError(void)
+-{
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
+-	printf("Message: %s\n", output);
+-}
+-
+ int
+ main(int argc, char *argv[])
+ {
+@@ -44,7 +34,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	ReadError();
+-	if (!strstr((char *) output, "zero")) {
++	if (!strstr(odbc_err, "zero")) {
+ 		fprintf(stderr, "Message invalid\n");
+ 		return 1;
+ 	}
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index 032a73a..b9b2daa 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,22 +1,9 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.16 2009/12/28 13:30:31 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.17 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static char odbc_err[256];
+-static char odbc_sqlstate[6];
+-
+-static void
+-ReadError(void)
+-{
+-	memset(odbc_err, 0, sizeof(odbc_err));
+-	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate,
+-		      NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+-	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+-}
+-
+ static void
+ test_err(const char *data, int c_type, const char *state)
+ {
+diff --git a/src/odbc/unittests/paramcore.c b/src/odbc/unittests/paramcore.c
+index b179b1a..e23db83 100644
+--- a/src/odbc/unittests/paramcore.c
++++ b/src/odbc/unittests/paramcore.c
+@@ -4,28 +4,12 @@
+  * Try to make core dump using SQLBindParameter
+  */
+ 
+-static char software_version[] = "$Id: paramcore.c,v 1.6 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: paramcore.c,v 1.7 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{call sp_paramcore_test(?)}"
+ #define OUTSTRING_LEN 20
+ 
+-static char MessageText[1000];
+-static SQLSMALLINT TextLength;
+-static SQLCHAR SqlState[6];
+-
+-
+-static void
+-ReadError(void)
+-{
+-	if (SQL_SUCCEEDED(SQLGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, NULL, (SQLCHAR*) MessageText, sizeof(MessageText), &TextLength))) {
+-		SqlState[sizeof(SqlState) - 1] = 0;
+-		fprintf(stderr, "State %s Message: %s\n", SqlState, MessageText);
+-	}
+-}
+-
+-
+-
+ int
+ main(int argc, char *argv[])
+ {
+@@ -39,21 +23,17 @@ main(int argc, char *argv[])
+ 	Command("create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");
+ 
+ 	/* here we pass a NULL buffer for input SQL_NTS */
+-	SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb);
+-	ReadError();
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb, "S");
+ 
+ 	cb = SQL_NTS;
+-	CommandWithResult(Statement, SP_TEXT);
+-	ReadError();
++	CHKExecDirect((SQLCHAR*) SP_TEXT, SQL_NTS, "E");
+ 	ResetStatement();
+ 
+ 	/* here we pass a NULL buffer for input */
+-	SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_VARCHAR, 18, 0, NULL, OUTSTRING_LEN, &cb);
+-	ReadError();
++	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_VARCHAR, 18, 0, NULL, OUTSTRING_LEN, &cb, "S");
+ 
+ 	cb = 1;
+-	CommandWithResult(Statement, SP_TEXT);
+-	ReadError();
++	CHKExecDirect((SQLCHAR*) SP_TEXT, SQL_NTS, "E");
+ 	ResetStatement();
+ 
+ 	Command("drop proc sp_paramcore_test");
+diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c
+index 9deb9c8..4702db7 100644
+--- a/src/odbc/unittests/print.c
++++ b/src/odbc/unittests/print.c
+@@ -1,10 +1,9 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: print.c,v 1.22 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: print.c,v 1.23 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+-static void ReadError(void);
+ 
+ #ifdef TDS_NO_DM
+ static const int tds_no_dm = 1;
+@@ -12,13 +11,6 @@ static const int tds_no_dm = 1;
+ static const int tds_no_dm = 0;
+ #endif
+ 
+-static void
+-ReadError(void)
+-{
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
+-	printf("Message: %s\n", output);
+-}
+-
+ static int
+ test(int odbc3)
+ {
+@@ -34,11 +26,11 @@ test(int odbc3)
+ 	query = "print 'START' select count(*) from sysobjects where name='sysobjects' print 'END'";
+ 	Command2(query, "I");
+ 	ReadError();
+-	if (!strstr((char *) output, "START")) {
++	if (!strstr(odbc_err, "START")) {
+ 		printf("Message invalid\n");
+ 		return 1;
+ 	}
+-	output[0] = 0;
++	odbc_err[0] = 0;
+ 
+ 	if (odbc3) {
+ 		CHECK_COLS(0);
+@@ -71,13 +63,12 @@ test(int odbc3)
+ 	 * (unixODBC till 2.2.11 do not read errors on NO DATA, skip test)
+ 	 */
+ 	if (tds_no_dm || odbc3) {
+-		output[0] = 0;
+ 		ReadError();
+-		if (!strstr((char *) output, "END")) {
++		if (!strstr(odbc_err, "END")) {
+ 			printf("Message invalid\n");
+ 			return 1;
+ 		}
+-		output[0] = 0;
++		odbc_err[0] = 0;
+ 	}
+ 
+ 	if (!odbc3) {
+diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c
+index 215fbe0..aec052e 100644
+--- a/src/odbc/unittests/rowset.c
++++ b/src/odbc/unittests/rowset.c
+@@ -1,20 +1,8 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rowset.c,v 1.5 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: rowset.c,v 1.6 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static char odbc_err[256];
+-static char odbc_sqlstate[6];
+-
+-static void
+-ReadError(void)
+-{
+-	memset(odbc_err, 0, sizeof(odbc_err));
+-	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+-	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+-}
+-
+ static void
+ test_err(int n)
+ {
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index b297b1a..a59b7d7 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,14 +3,11 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.8 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.9 2010/03/02 15:07:00 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-static char odbc_err[256];
+-static char odbc_sqlstate[6];
+-
+ static void
+-ReadError(void)
++ReadErrorConn(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+@@ -203,7 +200,7 @@ main(int argc, char *argv[])
+ 
+ 	/* Invalid argument value */
+ 	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0, "E");
+-	ReadError();
++	ReadErrorConn();
+ 	if (strcmp(odbc_sqlstate, "HY024") != 0) {
+ 		Disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+@@ -222,7 +219,7 @@ main(int argc, char *argv[])
+ #ifdef ENABLE_DEVELOPING
+ 	/* test setting with active transaction "Operation invalid at this time" */
+ 	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E");
+-	ReadError();
++	ReadErrorConn();
+ 	if (strcmp(odbc_sqlstate, "HY011") != 0) {
+ 		Disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+@@ -236,7 +233,7 @@ main(int argc, char *argv[])
+ 
+ 	/* test setting with pending data */
+ 	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E");
+-	ReadError();
++	ReadErrorConn();
+ 	if (strcmp(odbc_sqlstate, "HY011") != 0) {
+ 		Disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+
+commit 2a6bcfc2f141b9c3885cc18fe07e59becc09653e
+Author: freddy77 <freddy77>
+Date:   Tue Mar 2 15:41:37 2010 +0000
+
+    add a test for SQLGetDescRec/SQLSetDescRec and fix a small issue in SQLGetDescRec
+
+diff --git a/ChangeLog b/ChangeLog
+index ca587e0..59b0344 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Tue Mar  2 16:40:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/common.h:
++	* src/odbc/unittests/descrec.c:
++	- add a test for SQLGetDescRec/SQLSetDescRec and fix a small issue
++	  in SQLGetDescRec
++
+ Tue Mar  2 16:06:34 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/common.c src/odbc/unittests/common.h:
+ 	* src/odbc/unittests/error.c src/odbc/unittests/getdata.c:
+@@ -2352,4 +2359,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2997 2010/03/02 15:07:00 freddy77 Exp $
++$Id: ChangeLog,v 1.2998 2010/03/02 15:41:37 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0ef13fd..0546599 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.529 2010/02/01 10:16:05 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.530 2010/03/02 15:41:37 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -2268,16 +2268,19 @@ SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALL
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDescRec(%p, %d, %p, %d, %p, %p, %p, %p, %p, %p, %p)\n", 
+ 			hdesc, RecordNumber, Name, BufferLength, StringLength, Type, SubType, Length, Precision, Scale, Nullable);
+ 
+-	if (desc->type == DESC_IRD && desc->header.sql_desc_count) {
+-		odbc_errs_add(&desc->errs, "HY007", NULL);
++	if (RecordNumber <= 0) {
++		odbc_errs_add(&desc->errs, "07009", NULL);
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	if (RecordNumber > desc->header.sql_desc_count || RecordNumber <= 0) {
+-		odbc_errs_add(&desc->errs, "07009", NULL);
++	if (desc->type == DESC_IRD && desc->header.sql_desc_count) {
++		odbc_errs_add(&desc->errs, "HY007", NULL);
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
++	if (RecordNumber > desc->header.sql_desc_count)
++		ODBC_RETURN(desc, SQL_NO_DATA);
++
+ 	drec = &desc->records[RecordNumber - 1];
+ 
+ 	if ((rc = odbc_set_string(Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1)) != SQL_SUCCESS)
+diff --git a/src/odbc/unittests/.cvsignore b/src/odbc/unittests/.cvsignore
+index 37692f5..6fcba10 100644
+--- a/src/odbc/unittests/.cvsignore
++++ b/src/odbc/unittests/.cvsignore
+@@ -74,3 +74,4 @@ transaction2
+ utf8
+ utf8_2
+ stats
++descrec
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 5edf080..8675be9 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.81 2009/12/15 11:23:47 freddy77 Exp $
++# $Id: Makefile.am,v 1.82 2010/03/02 15:41:37 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -23,7 +23,7 @@ TESTS		=	\
+ 			attributes$(EXEEXT) hidden$(EXEEXT) blob1$(EXEEXT) \
+ 			cancel$(EXEEXT) wchar$(EXEEXT) rowset$(EXEEXT) transaction2$(EXEEXT) \
+ 			cursor6$(EXEEXT) cursor7$(EXEEXT) utf8$(EXEEXT) utf8_2$(EXEEXT) \
+-			stats$(EXEEXT)
++			stats$(EXEEXT) descrec$(EXEEXT)
+ 
+ check_PROGRAMS	=	$(TESTS)
+ 
+@@ -91,6 +91,7 @@ cursor7_SOURCES	= cursor7.c common.c common.h
+ utf8_SOURCES	= utf8.c common.c common.h
+ utf8_2_SOURCES	= utf8_2.c common.c common.h
+ stats_SOURCES	= stats.c common.c common.h
++descrec_SOURCES	= descrec.c common.c common.h
+ 
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC) -DFREETDS_SRCDIR=\"$(srcdir)\"
+ if MINGW32
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 8c449cd..4b246f2 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.31 2010/03/02 15:07:00 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.32 2010/03/02 15:41:37 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -149,6 +149,8 @@ SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
+ 	CHKR2(SQLProcedureColumns, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
+ #define CHKColumns(a,b,c,d,e,f,g,h,res) \
+ 	CHKR2(SQLColumns, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++#define CHKGetDescRec(a,b,c,d,e,f,g,h,i,j,res) \
++	CHKR2(SQLGetDescRec, (Descriptor,a,b,c,d,e,f,g,h,i,j), SQL_HANDLE_STMT, Descriptor, res)
+ 
+ int Connect(void);
+ int Disconnect(void);
+diff --git a/src/odbc/unittests/descrec.c b/src/odbc/unittests/descrec.c
+new file mode 100644
+index 0000000..ed7a1b7
+--- /dev/null
++++ b/src/odbc/unittests/descrec.c
+@@ -0,0 +1,37 @@
++/* test SQLGetDescRec */
++#include "common.h"
++
++static char software_version[] = "$Id: descrec.c,v 1.1 2010/03/02 15:41:37 freddy77 Exp $";
++static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
++
++int
++main(void)
++{
++	SQLHDESC Descriptor;
++	SQLINTEGER ind;
++	SQLCHAR name[128];
++	SQLSMALLINT si;
++
++	use_odbc_version3 = 1;
++	Connect();
++
++	Command("create table #tmp1 (i int)");
++
++	/* get IRD */
++	CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &Descriptor, sizeof(Descriptor), &ind, "S");
++
++	CHKGetDescRec(-1, name, sizeof(name), &si, NULL, NULL, NULL, NULL, NULL, NULL, "E");
++	/* TODO here should be NO_DATA cause we are requesting bookmark */
++	/* CHKGetDescRec(0, name, sizeof(name), &si, NULL, NULL, NULL, NULL, NULL, NULL, "No"); */
++	CHKGetDescRec(1, name, sizeof(name), &si, NULL /*Type*/, NULL /*SubType*/, NULL /*Length*/, NULL/*Precision*/,
++		      NULL /*Scale*/, NULL /*Nullable*/, "No");
++
++	Command("SELECT name FROM sysobjects");
++
++	CHKGetDescRec(1, name, sizeof(name), &si, NULL /*Type*/, NULL /*SubType*/, NULL /*Length*/, NULL/*Precision*/,
++		      NULL /*Scale*/, NULL /*Nullable*/, "S");
++
++	Disconnect();
++	return 0;
++}
++
+
+commit 1846c30223a60f1422c339f5c7e28d8a143526b0
+Author: freddy77 <freddy77>
+Date:   Wed Mar 3 08:08:56 2010 +0000
+
+    compute length supporting all character sets
+
+diff --git a/ChangeLog b/ChangeLog
+index 59b0344..ca9f089 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Mar  3 09:08:14 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/write.c: compute length supporting all character sets
++
+ Tue Mar  2 16:40:46 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/.cvsignore:
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/common.h:
+@@ -2359,4 +2362,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2998 2010/03/02 15:41:37 freddy77 Exp $
++$Id: ChangeLog,v 1.2999 2010/03/03 08:08:56 freddy77 Exp $
+diff --git a/src/tds/write.c b/src/tds/write.c
+index 1eb1d1a..57396d0 100644
+--- a/src/tds/write.c
++++ b/src/tds/write.c
+@@ -49,7 +49,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: write.c,v 1.78 2009/01/23 10:37:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: write.c,v 1.79 2010/03/03 08:08:57 freddy77 Exp $");
+ 
+ /**
+  * \addtogroup network
+@@ -107,13 +107,19 @@ tds_put_string(TDSSOCKET * tds, const char *s, int len)
+ 	if (len < 0) {
+ 		if (client->min_bytes_per_char == 1) {	/* ascii or UTF-8 */
+ 			len = (int)strlen(s);
+-		} else if (client->min_bytes_per_char == 2 && client->max_bytes_per_char == 2) {	/* UCS-2 or variant */
++		} else if (client->min_bytes_per_char == 2) {	/* UCS-2 or variant */
+ 			const char *p = s;
+ 
+ 			while (p[0] || p[1])
+ 				p += 2;
+ 			len = (int)(p - s);
+ 
++		} else if (client->min_bytes_per_char == 4) {	/* UCS-4 or variant */
++			const char *p = s;
++
++			while (p[0] || p[1] || p[2] || p[3])
++				p += 4;
++			len = (int)(p - s);
+ 		} else {
+ 			assert(client->min_bytes_per_char < 3);	/* FIXME */
+ 		}
+
+commit 23f6af8d0df7278f3532a3c16afb6512dc1d0dfb
+Author: freddy77 <freddy77>
+Date:   Mon Mar 22 14:42:16 2010 +0000
+
+    fix descrec test
+
+diff --git a/ChangeLog b/ChangeLog
+index ca9f089..866fa2d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Mar 22 15:41:47 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix descrec test
++
+ Wed Mar  3 09:08:14 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/write.c: compute length supporting all character sets
+ 
+@@ -2362,4 +2365,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.2999 2010/03/03 08:08:56 freddy77 Exp $
++$Id: ChangeLog,v 1.3000 2010/03/22 14:42:16 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0546599..466847b 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.530 2010/03/02 15:41:37 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.531 2010/03/22 14:42:16 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -2273,14 +2273,14 @@ SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALL
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	if (desc->type == DESC_IRD && desc->header.sql_desc_count) {
++	if (RecordNumber > desc->header.sql_desc_count)
++		ODBC_RETURN(desc, SQL_NO_DATA);
++
++	if (desc->type == DESC_IRD && !desc->header.sql_desc_count) {
+ 		odbc_errs_add(&desc->errs, "HY007", NULL);
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
+-	if (RecordNumber > desc->header.sql_desc_count)
+-		ODBC_RETURN(desc, SQL_NO_DATA);
+-
+ 	drec = &desc->records[RecordNumber - 1];
+ 
+ 	if ((rc = odbc_set_string(Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1)) != SQL_SUCCESS)
+
+commit 9b65db63a57bc2897529627f53dd6af000477989
+Author: jklowden <jklowden>
+Date:   Sat Apr 3 12:36:45 2010 +0000
+
+    Support TEXT datatype
+
+diff --git a/ChangeLog b/ChangeLog
+index 866fa2d..fc5cbea 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Apr  3 06:57:18 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c Support TEXT datatype
++
+ Mon Mar 22 15:41:47 CET 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix descrec test
+ 
+@@ -2365,4 +2368,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3000 2010/03/22 14:42:16 freddy77 Exp $
++$Id: ChangeLog,v 1.3001 2010/04/03 12:36:45 jklowden Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index f0fc136..816ee02 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -41,11 +41,15 @@
+ #include <string.h>
+ #endif
+ 
++#if HAVE_LIMITS_H
++#include <limits.h>
++#endif
++
+ #include <sqlfront.h>
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.38 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.39 2010/04/03 12:36:45 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -407,20 +411,26 @@ print_results(DBPROCESS *dbproc)
+ 			 * inaccesible to the application.  
+ 			 */
+ 
+-			data[c].buffer = calloc(1, metadata[c].width);
+-			assert(data[c].buffer);
++			if (metadata[c].width < INT_MAX) {
++				data[c].buffer = calloc(1, 1 + metadata[c].width); /* allow for null terminator */
++				assert(data[c].buffer);
+ 
+-			erc = dbbind(dbproc, c+1, bindtype, 0, (BYTE *) data[c].buffer);
+-			if (erc == FAIL) {
+-				fprintf(stderr, "%s:%d: dbbind(), column %d failed\n", options.appname, __LINE__, c+1);
+-				return;
+-			}
++				erc = dbbind(dbproc, c+1, bindtype, 0, (BYTE *) data[c].buffer);
++				if (erc == FAIL) {
++					fprintf(stderr, "%s:%d: dbbind(), column %d failed\n", options.appname, __LINE__, c+1);
++					return;
++				}
+ 
+-			erc = dbnullbind(dbproc, c+1, &data[c].status);
+-			if (erc == FAIL) {
+-				fprintf(stderr, "%s:%d: dbnullbind(), column %d failed\n", options.appname, __LINE__, c+1);
+-				return;
++				erc = dbnullbind(dbproc, c+1, &data[c].status);
++				if (erc == FAIL) {
++					fprintf(stderr, "%s:%d: dbnullbind(), column %d failed\n", options.appname, __LINE__, c+1);
++					return;
++				}
++			} else {
++				/* We don't bind text buffers, but use dbreadtext instead. */
++				data[c].buffer = NULL;
+ 			}
++
+ 		}
+ 		
+ 		/* 
+@@ -520,6 +530,20 @@ print_results(DBPROCESS *dbproc)
+ 			switch (row_code) {
+ 			case REG_ROW:
+ 				for (c=0; c < ncols; c++) {
++					if (metadata[c].width == INT_MAX) { /* TEXT/IMAGE */
++						BYTE *p = dbdata(dbproc, c+1);
++						size_t len = dbdatlen(dbproc, c+1);
++						if (len == 0) {
++							p = "NULL";
++							len = strlen(p);
++						}
++						if (fwrite(p, len, 1, stdout) != 1) {
++							perror("could not write to output file");
++							exit(EXIT_FAILURE);
++						}
++						fprintf(stdout, metadata[c].format_string); /* col/row separator */
++						continue;
++					}
+ 					switch (data[c].status) { /* handle nulls */
+ 					case -1: /* is null */
+ 						/* TODO: FreeTDS 0.62 does not support dbsetnull() */
+@@ -633,6 +657,8 @@ static int
+ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+ {
+ 	switch (type) {
++	case SYBBIT:
++		return 1;
+ 	case SYBINTN:
+ 		switch (size) {
+ 		case 1:
+@@ -667,16 +693,23 @@ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+ 		return 26;	/* FIX ME */
+ 	case SYBDATETIME4:
+ 		return 26;	/* FIX ME */
+-#if 0	/* seems not to be exported to sybdb.h */
++#if 0	/* not exported by sybdb.h */
+ 	case SYBBITN:
++	case SYBLONGBINARY:
++	case SYBLONGCHAR:
++	case SYBNTEXT:
++	case SYBNVARCHAR:
+ #endif
+-	case SYBBIT:
+-		return 1;
+-		/* FIX ME -- not all types present */
+-	default:
+-		return 0;
++	case SYBBINARY:
++	case SYBIMAGE:
++	case SYBTEXT:
++	case SYBVARBINARY:
++		return INT_MAX;
+ 	}
+-
++	
++	/* FIX ME -- not all types present */
++	fprintf(stderr, "type %d not supported, sorry\n", type);
++	exit(EXIT_FAILURE);
+ }
+ 
+ /** 
+@@ -692,13 +725,18 @@ set_format_string(struct METADATA * meta, const char separator[])
+ 	assert(meta);
+ 
+ 	if(0 == strcmp(options.colsep, default_colsep)) { 
+-		/* right justify numbers, left justify strings */
+-		size_and_width = is_character_data(meta->type)? "%%-%d.%ds%s" : "%%%d.%ds%s";
+-		
+-		width = get_printable_size(meta->type, meta->size);
++		if ((width = get_printable_size(meta->type, meta->size)) == INT_MAX) {
++			/* TEXT/IMAGE: no attempt to format the column; just splat the data */
++			meta->format_string = strdup(separator);
++			return strlen(meta->format_string);
++		}
++			
+ 		if (width < strlen(meta->name))
+ 			width = strlen(meta->name);
+ 
++		/* right justify numbers, left justify strings */
++		size_and_width = is_character_data(meta->type)? "%%-%d.%ds%s" : "%%%d.%ds%s";
++		
+ 		ret = asprintf(&meta->format_string, size_and_width, width, width, separator);
+ 	} else {
+ 		/* For anything except the default two-space separator, don't justify the strings. */
+
+commit bf4e3d97243db6c55bb0a928183e731ae381735e
+Author: jklowden <jklowden>
+Date:   Mon Apr 5 18:45:42 2010 +0000
+
+    Support TEXT datatype with any field terminator
+
+diff --git a/ChangeLog b/ChangeLog
+index fc5cbea..2940741 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Apr  5 14:44:11 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* src/apps/bsqldb.c Support TEXT datatype with any field terminator
++
+ Sat Apr  3 06:57:18 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/bsqldb.c Support TEXT datatype
+ 
+@@ -2368,4 +2371,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3001 2010/04/03 12:36:45 jklowden Exp $
++$Id: ChangeLog,v 1.3002 2010/04/05 18:45:42 jklowden Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 816ee02..dc84425 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -49,7 +49,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.39 2010/04/03 12:36:45 jklowden Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.40 2010/04/05 18:45:44 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -720,30 +720,29 @@ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+ static int
+ set_format_string(struct METADATA * meta, const char separator[])
+ {
+-	int width, ret;
++	int width;
+ 	const char *size_and_width;
+ 	assert(meta);
+ 
+-	if(0 == strcmp(options.colsep, default_colsep)) { 
+-		if ((width = get_printable_size(meta->type, meta->size)) == INT_MAX) {
+-			/* TEXT/IMAGE: no attempt to format the column; just splat the data */
+-			meta->format_string = strdup(separator);
+-			return strlen(meta->format_string);
+-		}
+-			
+-		if (width < strlen(meta->name))
+-			width = strlen(meta->name);
++	if ((width = get_printable_size(meta->type, meta->size)) == INT_MAX) {
++		/* TEXT/IMAGE: no attempt to format the column; just splat the data */
++		meta->format_string = strdup(separator);
++		return strlen(meta->format_string);
++	}
+ 
+-		/* right justify numbers, left justify strings */
+-		size_and_width = is_character_data(meta->type)? "%%-%d.%ds%s" : "%%%d.%ds%s";
+-		
+-		ret = asprintf(&meta->format_string, size_and_width, width, width, separator);
+-	} else {
+-		/* For anything except the default two-space separator, don't justify the strings. */
+-		ret = asprintf(&meta->format_string, "%%s%s", separator);
++	/* For anything except the default two-space separator, don't justify the strings. */
++	if(0 != strcmp(options.colsep, default_colsep)) { 
++		return asprintf(&meta->format_string, "%%s%s", separator);
+ 	}
+-		       
+-	return ret;
++		
++	/* Set the printing width large enough for the data or its title, whichever is greater. */
++	if (width < strlen(meta->name))
++		width = strlen(meta->name);
++
++	/* right justify numbers, left justify strings */
++	size_and_width = is_character_data(meta->type)? "%%-%d.%ds%s" : "%%%d.%ds%s";
++
++	return asprintf(&meta->format_string, size_and_width, width, width, separator);
+ }
+ 
+ static void
+
+commit bb84eee596c058c2397af4258198bf1978372e03
+Author: jklowden <jklowden>
+Date:   Mon Apr 5 18:49:25 2010 +0000
+
+    log table metadata succintly
+
+diff --git a/ChangeLog b/ChangeLog
+index 2940741..defb1d7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Apr  5 14:45:37 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* include/tds.h src/tds/token.c log table metadata succintly
++	* src/dblib/unittests/t0004.c test dbgetchar()
++
+ Mon Apr  5 14:44:11 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/apps/bsqldb.c Support TEXT datatype with any field terminator
+ 
+@@ -2371,4 +2375,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3002 2010/04/05 18:45:42 jklowden Exp $
++$Id: ChangeLog,v 1.3003 2010/04/05 18:49:25 jklowden Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 63f151d..7bbb2c8 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.331 2010/01/29 18:57:03 freddy77 Exp $ */
++/* $Id: tds.h,v 1.332 2010/04/05 18:49:25 jklowden Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -348,6 +348,7 @@ typedef enum {	TDSEOK    = TDS_SUCCEED,
+ #define TDS_LOGINACK_TOKEN        173	/* 0xAD                              */
+ #define TDS_CONTROL_TOKEN         174	/* 0xAE    TDS_CONTROL               */
+ #define TDS_ROW_TOKEN             209	/* 0xD1                              */
++#define TDS_NBC_ROW_TOKEN         210	/* 0xD2    as of TDS 7.3.B           */ /* not implemented */
+ #define TDS_CMP_ROW_TOKEN         211	/* 0xD3                              */
+ #define TDS5_PARAMS_TOKEN         215	/* 0xD7    TDS 5.0 only              */
+ #define TDS_CAPABILITY_TOKEN      226	/* 0xE2                              */
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 54a2b50..d3de1ae 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.380 2010/03/01 12:38:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.381 2010/04/05 18:49:25 jklowden Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -236,7 +236,10 @@ tds_process_default_tokens(TDSSOCKET * tds, int marker)
+ 		tdsdump_log(TDS_DBG_WARN, "Eating %s token\n", _tds_token_name(marker));
+ 		tds_get_n(tds, NULL, tds_get_int(tds));
+ 		break;
+-	default: /* SYBEBTOK */
++	case TDS_NBC_ROW_TOKEN:
++		tdsdump_log(TDS_DBG_ERROR, "error: cannot process TDS_NBC_ROW_TOKEN %d(%x)!\n", marker, (unsigned char) marker);
++		/* fall out */
++	default: 
+ 		tds_close_socket(tds);
+ 		tdserror(tds->tds_ctx, tds, TDSEBTOK, 0);
+ 		tdsdump_log(TDS_DBG_ERROR, "Unknown marker: %d(%x)!!\n", marker, (unsigned char) marker);
+@@ -306,7 +309,6 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 	int marker;
+ 	int len;
+ 	int memrc = 0;
+-	unsigned char major_ver, minor_ver;
+ 	unsigned char ack;
+ 	TDS_UINT product_version;
+ 
+@@ -315,6 +317,11 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 	tdsdump_log(TDS_DBG_FUNC, "tds_process_login_tokens()\n");
+ 	/* get_incoming(tds->s); */
+ 	do {
++		struct 	{ unsigned char major, minor, tiny[2]; 
++			  unsigned int reported; 
++			  char *name;
++			} ver;
++		
+ 		marker = tds_get_byte(tds);
+ 		tdsdump_log(TDS_DBG_FUNC, "looking for login token, got  %x(%s)\n", marker, _tds_token_name(marker));
+ 
+@@ -326,46 +333,66 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 			/* TODO function */
+ 			len = tds_get_smallint(tds);
+ 			ack = tds_get_byte(tds);
+-			major_ver = tds_get_byte(tds);
+-			minor_ver = tds_get_byte(tds);
+-			tds_get_n(tds, NULL, 2);
+-			/* ignore product name length, see below */
++			
++			ver.major = tds_get_byte(tds);
++			ver.minor = tds_get_byte(tds);
++			ver.tiny[1] = tds_get_byte(tds);
++			ver.tiny[2] = tds_get_byte(tds);
++			ver.reported = (ver.major << 24) | (ver.minor << 16) | (ver.tiny[1] << 8) | ver.tiny[2];
++			
++			/* Log reported server product name, cf. MS-TDS LOGINACK documentation. */
++			switch(ver.reported) {
++			case 0x07000000: 
++				ver.name = "7.0"; break;
++			case 0x07010000: 
++				ver.name = "2000"; break;
++			case 0x71000001: 
++				ver.name = "2000 SP1"; break;
++			case 0x72090002: 
++				ver.name = "2005"; break;
++			case 0x730A0003: 
++				ver.name = "2008 (no NBCROW or fSparseColumnSet)"; break;
++			case 0x730B0003: 
++				ver.name = "2008"; break;
++			default:
++				ver.name = "unknown"; break;
++			}
++			
++			tdsdump_log(TDS_DBG_FUNC, "server reports TDS version %x.%x.%x.%x\n", 
++							ver.major, ver.minor, ver.tiny[1], ver.tiny[2]);
++			tdsdump_log(TDS_DBG_FUNC, "Product name for 0x%x is %s\n", ver.reported, ver.name);
++			
++			/* Get server product name. */
++			/* Ignore product name length; some servers seem to set it incorrectly.  */
+ 			tds_get_byte(tds);
+ 			product_version = 0;
+-			/* get server product name */
+-			/* compute length from packet, some version seem to fill this information wrongly */
++			/* Compute product name length from packet length. */
+ 			len -= 10;
+ 			free(tds->product_name);
+-			if (major_ver >= 7u) {
++			if (ver.major >= 7u) {
+ 				product_version = 0x80000000u;
+ 				memrc += tds_alloc_get_string(tds, &tds->product_name, len / 2);
+-			} else if (major_ver >= 5) {
++			} else if (ver.major >= 5) {
+ 				memrc += tds_alloc_get_string(tds, &tds->product_name, len);
+ 			} else {
+ 				memrc += tds_alloc_get_string(tds, &tds->product_name, len);
+ 				if (tds->product_name != NULL && strstr(tds->product_name, "Microsoft") != NULL)
+ 					product_version = 0x80000000u;
+ 			}
++			
+ 			product_version |= ((TDS_UINT) tds_get_byte(tds)) << 24;
+ 			product_version |= ((TDS_UINT) tds_get_byte(tds)) << 16;
+ 			product_version |= ((TDS_UINT) tds_get_byte(tds)) << 8;
+ 			product_version |= tds_get_byte(tds);
++
+ 			/*
+ 			 * MSSQL 6.5 and 7.0 seem to return strange values for this
+ 			 * using TDS 4.2, something like 5F 06 32 FF for 6.50
+ 			 */
+-			if (major_ver == 4 && minor_ver == 2 && (product_version & 0xff0000ffu) == 0x5f0000ffu)
++			if (ver.major == 4 && ver.minor == 2 && (product_version & 0xff0000ffu) == 0x5f0000ffu)
+ 				product_version = ((product_version & 0xffff00u) | 0x800000u) << 8;
+ 			tds->product_version = product_version;
+-#ifdef WORDS_BIGENDIAN
+-			/* TODO do a best check */
+-/*
+-				
+-				if (major_ver==7) {
+-					tds->broken_dates=1;
+-				}
+-*/
+-#endif
++
+ 			/*
+ 			 * TDS 5.0 reports 5 on success 6 on failure
+ 			 * TDS 4.2 reports 1 on success and is not
+@@ -393,9 +420,12 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 			succeed = TDS_FAIL;
+ 		}
+ 	}
+-	tdsdump_log(TDS_DBG_FUNC, "leaving tds_process_login_tokens() returning %d\n", succeed);
+ 	if (memrc != 0)
+ 		succeed = TDS_FAIL;
++		
++	tdsdump_log(TDS_DBG_FUNC, "tds_process_login_tokens() returning %s\n", 
++					(succeed == TDS_SUCCEED)? "TDS_SUCCEED" : "TDS_FAIL");
++
+ 	return succeed;
+ }
+ 
+@@ -1523,7 +1553,6 @@ static int
+ tds7_process_result(TDSSOCKET * tds)
+ {
+ 	int col, num_cols, result;
+-	TDSCOLUMN *curcol;
+ 	TDSRESULTINFO *info;
+ 
+ 	CHECK_TDS_EXTRA(tds);
+@@ -1558,13 +1587,32 @@ tds7_process_result(TDSSOCKET * tds)
+ 	 * loop through the columns populating COLINFO struct from
+ 	 * server response
+ 	 */
++	tdsdump_log(TDS_DBG_INFO1, "setting up %d columns\n", num_cols);
+ 	for (col = 0; col < num_cols; col++) {
+-
+-		curcol = info->columns[col];
+-
+-		tdsdump_log(TDS_DBG_INFO1, "setting up column %d\n", col);
++		TDSCOLUMN *curcol = info->columns[col];
++		
+ 		tds7_get_data_info(tds, curcol);
+ 	}
++		
++	if (num_cols > 0) {
++		static char dashes[31] = "------------------------------";
++		tdsdump_log(TDS_DBG_INFO1, " %-20s %-15s %-15s %-7s\n", "name", "size/wsize", "type/wtype", "utype");
++		tdsdump_log(TDS_DBG_INFO1, " %-20s %15s %15s %7s\n", dashes+10, dashes+30-15, dashes+30-15, dashes+30-7);
++	}
++	for (col = 0; col < num_cols; col++) {
++		char name[TDS_SYSNAME_SIZE] = {'\0'};
++		TDSCOLUMN *curcol = info->columns[col];
++
++		if (curcol->column_namelen > 0) {
++			memcpy(name, curcol->column_name, curcol->column_namelen);
++			name[curcol->column_namelen] = '\0';
++		}
++		tdsdump_log(TDS_DBG_INFO1, " %-20s %7d/%-7d %7d/%-7d %7d\n", 
++						name, 
++						curcol->column_size, curcol->on_server.column_size, 
++						curcol->column_type, curcol->on_server.column_type, 
++						curcol->column_usertype);
++	}
+ 
+ 	/* all done now allocate a row for tds_process_row to use */
+ 	result = tds_alloc_row(info);
+
+commit b5bc1a5c3c2c9416ca089b4ec1b6de00324cf878
+Author: jklowden <jklowden>
+Date:   Mon Apr 5 18:49:30 2010 +0000
+
+    test dbgetchar()
+
+diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c
+index 1a62955..f859052 100644
+--- a/src/dblib/unittests/t0004.c
++++ b/src/dblib/unittests/t0004.c
+@@ -1,12 +1,12 @@
+ /* 
+  * Purpose: Test retrieving data and attempting to initiate a new query with results pending
+- * Functions: dbnextrow dbresults dbsqlexec 
++ * Functions: dbnextrow dbresults dbsqlexec dbgetchar 
+  */
+ 
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.19 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.20 2010/04/05 18:49:30 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+@@ -18,7 +18,7 @@ main(int argc, char **argv)
+ 	LOGINREC *login;
+ 	DBPROCESS *dbproc;
+ 	int i, expected_error;
+-	char teststr[1024];
++	char *s, teststr[1024];
+ 	DBINT testint;
+ 	int failed = 0;
+ 
+@@ -132,6 +132,16 @@ main(int argc, char **argv)
+ 
+ 
+ 	fprintf(stdout, "second select\n");
++	fprintf(stdout, "testing dbgetchar...\n");
++	for (i=0; (s = dbgetchar(dbproc, i)) != NULL; i++) {
++		putchar(*s);
++		if (!(isprint((unsigned char)*s) || iscntrl((unsigned char)*s))) {
++			fprintf(stderr, "%s:%d: dbgetchar failed with %x at position %d\n", __FILE__, __LINE__, *s, i);
++			failed = 1;
++			break;
++		}
++	}
++	fprintf(stdout, "<== end of command buffer\n");
+ 
+ 	if (SUCCEED != sql_cmd(dbproc)) {
+ 		fprintf(stderr, "%s:%d: dbcmd failed\n", __FILE__, __LINE__);
+
+commit d4ab24c44d35aa70bec5835a09d840b13b42933f
+Author: freddy77 <freddy77>
+Date:   Thu Apr 8 07:36:49 2010 +0000
+
+    Avoid hang on variant type if conversion enabled
+
+diff --git a/ChangeLog b/ChangeLog
+index defb1d7..02ded3d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr  8 09:36:21 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: Avoid hang on variant type if conversion enabled
++
+ Mon Apr  5 14:45:37 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* include/tds.h src/tds/token.c log table metadata succintly
+ 	* src/dblib/unittests/t0004.c test dbgetchar()
+@@ -2375,4 +2378,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3003 2010/04/05 18:49:25 jklowden Exp $
++$Id: ChangeLog,v 1.3004 2010/04/08 07:36:49 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index d3de1ae..d62866a 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.381 2010/04/05 18:49:25 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.382 2010/04/08 07:36:49 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2110,12 +2110,13 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 		TDS_ZERO_FREE(v->data);
+ 	if (colsize) {
+ 		if (USE_ICONV && curcol->char_conv) {
+-			curcol->column_cur_size = colsize = determine_adjusted_size(curcol->char_conv, colsize);
+-			v->data = (TDS_CHAR*) malloc(colsize);
++			curcol->column_cur_size = determine_adjusted_size(curcol->char_conv, colsize);
++			v->data = (TDS_CHAR*) malloc(curcol->column_cur_size);
+ 			if (!v->data)
+ 				return TDS_FAIL;
+ 			if (tds_get_char_data(tds, (char *) v->data, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
++			colsize = curcol->column_cur_size;
+ 			v->type = tds_get_cardinal_type(type, 0);
+ 		} else {
+ 			v->data = (TDS_CHAR*) malloc(colsize);
+
+commit 55df8e954ef9c07b5c158d263c9fc6774245cac1
+Author: freddy77 <freddy77>
+Date:   Thu Apr 8 08:19:16 2010 +0000
+
+    fix tsql and variant type
+
+diff --git a/ChangeLog b/ChangeLog
+index 02ded3d..c4f5737 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Apr  8 10:17:24 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/apps/tsql.c src/tds/token.c:
++	- fix tsql and variant type
++
+ Thu Apr  8 09:36:21 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: Avoid hang on variant type if conversion enabled
+ 
+@@ -2378,4 +2382,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3004 2010/04/08 07:36:49 freddy77 Exp $
++$Id: ChangeLog,v 1.3005 2010/04/08 08:19:16 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 7bbb2c8..b81474e 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.332 2010/04/05 18:49:25 jklowden Exp $ */
++/* $Id: tds.h,v 1.333 2010/04/08 08:19:16 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -920,6 +920,7 @@ typedef struct tds_blob
+  */
+ typedef struct tds_variant
+ {
++	/* this MUST have same position and place of textvalue in tds_blob */
+ 	TDS_CHAR *data;
+ 	TDS_INT size;
+ 	TDS_INT data_len;
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index a1d716b..26574fb 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -87,7 +87,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.132 2010/01/12 15:43:17 jklowden Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.133 2010/04/08 08:19:16 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -237,7 +237,7 @@ do_query(TDSSOCKET * tds, char *buf, int opt_flags)
+ 					ctype = tds_get_conversion_type(col->column_type, col->column_size);
+ 
+ 					src = col->column_data;
+-					if (is_blob_col(col))
++					if (is_blob_col(col) && col->column_type != SYBVARIANT)
+ 						src = (unsigned char *) ((TDSBLOB *) src)->textvalue;
+ 					srclen = col->column_cur_size;
+ 
+diff --git a/src/tds/token.c b/src/tds/token.c
+index d62866a..c51e80b 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.382 2010/04/08 07:36:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.383 2010/04/08 08:19:16 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -81,6 +81,17 @@ static int determine_adjusted_size(const TDSICONV * char_conv, int size);
+ static /*@observer@*/ const char *tds_pr_op(int op);
+ static int tds_alloc_get_string(TDSSOCKET * tds, /*@special@*/ char **string, int len) /*allocates *string*/;
+ 
++#if ENABLE_EXTRA_CHECKS
++
++#if defined(__GNUC__) && __GNUC__ >= 2
++#define COMPILE_CHECK(name,check) \
++    extern int name[(check)?1:-1] __attribute__ ((unused))
++#else
++#define COMPILE_CHECK(name,check) \
++    extern int name[(check)?1:-1]
++#endif
++
++#endif
+ 
+ /**
+  * \ingroup libtds
+@@ -2037,6 +2048,11 @@ tds9_get_varmax(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 	return TDS_SUCCEED;
+ }
+ 
++#if ENABLE_EXTRA_CHECKS
++COMPILE_CHECK(tds_variant_size,  sizeof(((TDSVARIANT*)0)->data) == sizeof(((TDSBLOB*)0)->textvalue));
++COMPILE_CHECK(tds_variant_offset,(TDS_INTPTR)(&((TDSVARIANT*)0)->data) == (TDS_INTPTR)(&((TDSBLOB*)0)->textvalue));
++#endif
++
+ static int
+ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ {
+@@ -2114,7 +2130,7 @@ tds7_get_variant(TDSSOCKET * tds, TDSCOLUMN * curcol)
+ 			v->data = (TDS_CHAR*) malloc(curcol->column_cur_size);
+ 			if (!v->data)
+ 				return TDS_FAIL;
+-			if (tds_get_char_data(tds, (char *) v->data, colsize, curcol) == TDS_FAIL)
++			if (tds_get_char_data(tds, (char *) v, colsize, curcol) == TDS_FAIL)
+ 				return TDS_FAIL;
+ 			colsize = curcol->column_cur_size;
+ 			v->type = tds_get_cardinal_type(type, 0);
+
+commit 92e0af38ba938848957634d27437a774b268e766
+Author: freddy77 <freddy77>
+Date:   Thu Apr 8 08:24:20 2010 +0000
+
+    remove undeclared warning
+
+diff --git a/ChangeLog b/ChangeLog
+index c4f5737..76cbf63 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr  8 10:23:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/t0004.c: remove undeclared warning
++
+ Thu Apr  8 10:17:24 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/apps/tsql.c src/tds/token.c:
+ 	- fix tsql and variant type
+@@ -2382,4 +2385,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3005 2010/04/08 08:19:16 freddy77 Exp $
++$Id: ChangeLog,v 1.3006 2010/04/08 08:24:20 freddy77 Exp $
+diff --git a/src/dblib/unittests/t0004.c b/src/dblib/unittests/t0004.c
+index f859052..36fce80 100644
+--- a/src/dblib/unittests/t0004.c
++++ b/src/dblib/unittests/t0004.c
+@@ -4,9 +4,9 @@
+  */
+ 
+ #include "common.h"
++#include <ctype.h>
+ 
+-
+-static char software_version[] = "$Id: t0004.c,v 1.20 2010/04/05 18:49:30 jklowden Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.21 2010/04/08 08:24:20 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ 
+
+commit 4053e0ab049a0a8a0bfdc8547dbfe2e795bde884
+Author: freddy77 <freddy77>
+Date:   Thu Apr 8 09:02:55 2010 +0000
+
+    remove some conversion warnings
+
+diff --git a/ChangeLog b/ChangeLog
+index 76cbf63..5b26ba6 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Apr  8 11:02:24 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqldb.c: remove some conversion warnings
++
+ Thu Apr  8 10:23:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/t0004.c: remove undeclared warning
+ 
+@@ -2385,4 +2388,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3006 2010/04/08 08:24:20 freddy77 Exp $
++$Id: ChangeLog,v 1.3007 2010/04/08 09:02:55 freddy77 Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index dc84425..5319757 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -49,7 +49,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.40 2010/04/05 18:45:44 jklowden Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.41 2010/04/08 09:02:55 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -534,10 +534,8 @@ print_results(DBPROCESS *dbproc)
+ 						BYTE *p = dbdata(dbproc, c+1);
+ 						size_t len = dbdatlen(dbproc, c+1);
+ 						if (len == 0) {
+-							p = "NULL";
+-							len = strlen(p);
+-						}
+-						if (fwrite(p, len, 1, stdout) != 1) {
++							fputs("NULL", stdout);
++						} else if (fwrite(p, len, 1, stdout) != 1) {
+ 							perror("could not write to output file");
+ 							exit(EXIT_FAILURE);
+ 						}
+
+commit c5088213a245e2bc1eaafa27cf65ff117f86f21c
+Author: freddy77 <freddy77>
+Date:   Sat Apr 10 14:22:09 2010 +0000
+
+    make execution faster if log disabled (patch from Steve Brown)
+
+diff --git a/ChangeLog b/ChangeLog
+index 5b26ba6..1ca80b8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Apr 10 16:21:49 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/log.c:
++	- make execution faster if log disabled (patch from Steve Brown)
++
+ Thu Apr  8 11:02:24 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqldb.c: remove some conversion warnings
+ 
+@@ -2388,4 +2392,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3007 2010/04/08 09:02:55 freddy77 Exp $
++$Id: ChangeLog,v 1.3008 2010/04/10 14:22:09 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index b81474e..08580ee 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.333 2010/04/08 08:19:16 freddy77 Exp $ */
++/* $Id: tds.h,v 1.334 2010/04/10 14:22:09 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1581,12 +1581,15 @@ int tdsdump_open(const char *filename);
+ void tdsdump_close(void);
+ void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length);
+ void tdsdump_col(const TDSCOLUMN *col);
++#undef tdsdump_log
+ void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+-
+ #if defined(__GNUC__) && __GNUC__ >= 2
+ 	__attribute__ ((__format__ (__printf__, 3, 4)))
+ #endif
+ ;
++#define tdsdump_log if (tds_write_dump) tdsdump_log
++
++extern int tds_write_dump;
+ extern int tds_debug_flags;
+ extern int tds_g_append_mode;
+ 
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 335bf59..3d51bcd 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,13 +66,13 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.17 2010/01/28 13:31:51 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.18 2010/04/10 14:22:09 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+ int tds_g_append_mode = 0;
+ static char *g_dump_filename = NULL;
+-static int write_dump = 0;	/* is TDS stream debug log turned on? */
++int tds_write_dump = 0;	/* is TDS stream debug log turned on? */
+ static FILE *g_dumpfile = NULL;	/* file pointer for dump log          */
+ static TDS_MUTEX_DEFINE(g_dump_mutex);
+ 
+@@ -93,7 +93,7 @@ void
+ tdsdump_off(void)
+ {
+ 	TDS_MUTEX_LOCK(&g_dump_mutex);
+-	write_dump = 0;
++	tds_write_dump = 0;
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+ }				/* tdsdump_off()  */
+ 
+@@ -105,7 +105,7 @@ void
+ tdsdump_on(void)
+ {
+ 	TDS_MUTEX_LOCK(&g_dump_mutex);
+-	write_dump = 1;
++	tds_write_dump = 1;
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+ }
+ 
+@@ -166,7 +166,7 @@ tdsdump_open(const char *filename)
+ 	}
+ 
+ 	if (result)
+-		write_dump = 1;
++		tds_write_dump = 1;
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+ 
+ 	if (result) {
+@@ -221,7 +221,7 @@ void
+ tdsdump_close(void)
+ {
+ 	TDS_MUTEX_LOCK(&g_dump_mutex);
+-	write_dump = 0;
++	tds_write_dump = 0;
+ 	if (g_dumpfile != NULL && g_dumpfile != stdout && g_dumpfile != stderr)
+ 		fclose(g_dumpfile);
+ 	g_dumpfile = NULL;
+@@ -287,7 +287,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con
+ 	char line_buf[BYTES_PER_LINE * 8 + 16], *p;
+ 	FILE *dumpfile;
+ 
+-	if (((tds_debug_flags >> debug_lvl) & 1) == 0 || !write_dump)
++	if (((tds_debug_flags >> debug_lvl) & 1) == 0 || !tds_write_dump)
+ 		return;
+ 
+ 	if (!g_dumpfile && !g_dump_filename)
+@@ -366,6 +366,7 @@ tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, con
+ }				/* tdsdump_dump_buf()  */
+ 
+ 
++#undef tdsdump_log
+ /**
+  * Write a message to the debug log.  
+  * \param file name of the log file
+@@ -380,7 +381,7 @@ tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ 	va_list ap;
+ 	FILE *dumpfile;
+ 
+-	if (((tds_debug_flags >> debug_lvl) & 1) == 0 || !write_dump)
++	if (((tds_debug_flags >> debug_lvl) & 1) == 0 || !tds_write_dump)
+ 		return;
+ 
+ 	if (!g_dumpfile && !g_dump_filename)
+@@ -419,6 +420,8 @@ tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ #endif
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+ }				/* tdsdump_log()  */
++#define tdsdump_log if (tds_write_dump) tdsdump_log
++
+ 
+ /**
+  * Write a column value to the debug log.  
+
+commit 977043d8857fc931742542d329d513104e2b8cbd
+Author: freddy77 <freddy77>
+Date:   Sat Apr 10 14:29:36 2010 +0000
+
+    add TDS_LIKELY/TDS_UNLIKELY macro and use them for logging
+
+diff --git a/ChangeLog b/ChangeLog
+index 1ca80b8..0281c23 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Apr 10 16:29:29 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/log.c:
++	- add TDS_LIKELY/TDS_UNLIKELY macro and use them for logging
++
+ Sat Apr 10 16:21:49 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/log.c:
+ 	- make execution faster if log disabled (patch from Steve Brown)
+@@ -2392,4 +2396,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3008 2010/04/10 14:22:09 freddy77 Exp $
++$Id: ChangeLog,v 1.3009 2010/04/10 14:29:36 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 08580ee..930e60a 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.334 2010/04/10 14:22:09 freddy77 Exp $ */
++/* $Id: tds.h,v 1.335 2010/04/10 14:29:36 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -682,6 +682,14 @@ typedef enum tds_encryption_level {
+ #define TDS_ZERO_FREE(x) do {free((x)); (x) = NULL;} while(0)
+ #define TDS_VECTOR_SIZE(x) (sizeof(x)/sizeof(x[0]))
+ 
++#if defined(__GNUC__) && __GNUC__ >= 3
++# define TDS_LIKELY(x)	__builtin_expect(!!(x), 1)
++# define TDS_UNLIKELY(x)	__builtin_expect(!!(x), 0)
++#else
++# define TDS_LIKELY(x)	(x)
++# define TDS_UNLIKELY(x)	(x)
++#endif
++
+ /*
+  * TODO use system macros for optimization
+  * See mcrypt for reference and linux kernel source for optimization
+@@ -1587,7 +1595,7 @@ void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...
+ 	__attribute__ ((__format__ (__printf__, 3, 4)))
+ #endif
+ ;
+-#define tdsdump_log if (tds_write_dump) tdsdump_log
++#define tdsdump_log if (TDS_UNLIKELY(tds_write_dump)) tdsdump_log
+ 
+ extern int tds_write_dump;
+ extern int tds_debug_flags;
+diff --git a/src/tds/log.c b/src/tds/log.c
+index 3d51bcd..afc8f1b 100644
+--- a/src/tds/log.c
++++ b/src/tds/log.c
+@@ -66,7 +66,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: log.c,v 1.18 2010/04/10 14:22:09 freddy77 Exp $");
++TDS_RCSID(var, "$Id: log.c,v 1.19 2010/04/10 14:29:36 freddy77 Exp $");
+ 
+ /* for now all messages go to the log */
+ int tds_debug_flags = TDS_DBGFLAG_ALL | TDS_DBGFLAG_SOURCE;
+@@ -420,7 +420,7 @@ tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
+ #endif
+ 	TDS_MUTEX_UNLOCK(&g_dump_mutex);
+ }				/* tdsdump_log()  */
+-#define tdsdump_log if (tds_write_dump) tdsdump_log
++#define tdsdump_log if (TDS_UNLIKELY(tds_write_dump)) tdsdump_log
+ 
+ 
+ /**
+
+commit 4e77e4a7ec769d915a50c44e1635795a8673a634
+Author: freddy77 <freddy77>
+Date:   Tue Apr 13 13:19:12 2010 +0000
+
+    improve CTLib cs_convert (partial patch from David Dick with additional tests)
+
+diff --git a/ChangeLog b/ChangeLog
+index 0281c23..3fb8a12 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Tue Apr 13 15:18:41 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/cs.c src/ctlib/unittests/common.c:
++	* src/ctlib/unittests/t0006.c:
++	- improve CTLib cs_convert (partial patch from David Dick with
++	  additional tests)
++
+ Sat Apr 10 16:29:29 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/log.c:
+ 	- add TDS_LIKELY/TDS_UNLIKELY macro and use them for logging
+@@ -2396,4 +2402,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3009 2010/04/10 14:29:36 freddy77 Exp $
++$Id: ChangeLog,v 1.3010 2010/04/13 13:19:12 freddy77 Exp $
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index d136fc3..14f126b 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.73 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.74 2010/04/13 13:19:12 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -733,19 +733,17 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ 	case SYBBINARY:
+ 	case SYBVARBINARY:
+ 	case SYBIMAGE:
+-
++		ret = CS_SUCCEED;
+ 		if (len > destlen) {
+-			free(cres.ib);
+-			fprintf(stderr, "error_handler: Data-conversion resulted in overflow.\n");
++			tdsdump_log(TDS_DBG_FUNC, "error_handler: Data-conversion resulted in overflow\n");
+ 			ret = CS_FAIL;
+-		} else {
+-			memcpy(dest, cres.ib, len);
+-			free(cres.ib);
+-			for (i = len; i < destlen; i++)
+-				dest[i] = '\0';
+-			*resultlen = destlen;
+-			ret = CS_SUCCEED;
++			len = destlen;
+ 		}
++		memcpy(dest, cres.ib, len);
++		free(cres.ib);
++		for (i = len; i < destlen; i++)
++			dest[i] = '\0';
++		*resultlen = destlen;
+ 		break;
+ 	case SYBBIT:
+ 	case SYBBITN:
+@@ -812,54 +810,51 @@ cs_convert(CS_CONTEXT * ctx, CS_DATAFMT * srcfmt, CS_VOID * srcdata, CS_DATAFMT
+ 	case SYBCHAR:
+ 	case SYBVARCHAR:
+ 	case SYBTEXT:
++		ret = CS_SUCCEED;
+ 		if (len > destlen) {
+-			fprintf(stderr, "error_handler: Data-conversion resulted in overflow.\n");
++			tdsdump_log(TDS_DBG_FUNC, "Data-conversion resulted in overflow\n");
++			len = destlen;
+ 			ret = CS_FAIL;
+-		} else {
+-			switch (destfmt->format) {
+-
+-			case CS_FMT_NULLTERM:
+-				tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_NULLTERM\n");
+-				if (len == destlen) {
+-					tdsdump_log(TDS_DBG_FUNC, "not enough room for data + a null terminator - error\n");
+-					ret = CS_FAIL;	/* not enough room for data + a null terminator - error */
+-				} else {
+-					memcpy(dest, cres.c, len);
+-					dest[len] = 0;
+-					*resultlen = len + 1;
+-					ret = CS_SUCCEED;
+-				}
+-				break;
+-
+-			case CS_FMT_PADBLANK:
+-				tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADBLANK\n");
+-				/* strcpy here can lead to a small buffer overflow */
+-				memcpy(dest, cres.c, len);
+-				for (i = len; i < destlen; i++)
+-					dest[i] = ' ';
+-				*resultlen = destlen;
+-				ret = CS_SUCCEED;
+-				break;
++		}
++		switch (destfmt->format) {
+ 
+-			case CS_FMT_PADNULL:
+-				tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADNULL\n");
+-				/* strcpy here can lead to a small buffer overflow */
+-				memcpy(dest, cres.c, len);
+-				for (i = len; i < destlen; i++)
+-					dest[i] = '\0';
+-				*resultlen = destlen;
+-				ret = CS_SUCCEED;
+-				break;
+-			case CS_FMT_UNUSED:
+-				tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_UNUSED\n");
++		case CS_FMT_NULLTERM:
++			tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_NULLTERM\n");
++			if (len == destlen) {
++				tdsdump_log(TDS_DBG_FUNC, "not enough room for data + a null terminator - error\n");
++				ret = CS_FAIL;	/* not enough room for data + a null terminator - error */
++			} else {
+ 				memcpy(dest, cres.c, len);
+-				*resultlen = len;
+-				ret = CS_SUCCEED;
+-				break;
+-			default:
+-				ret = CS_FAIL;
+-				break;
++				dest[len] = 0;
++				*resultlen = len + 1;
+ 			}
++			break;
++
++		case CS_FMT_PADBLANK:
++			tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADBLANK\n");
++			/* strcpy here can lead to a small buffer overflow */
++			memcpy(dest, cres.c, len);
++			for (i = len; i < destlen; i++)
++				dest[i] = ' ';
++			*resultlen = destlen;
++			break;
++
++		case CS_FMT_PADNULL:
++			tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_PADNULL\n");
++			/* strcpy here can lead to a small buffer overflow */
++			memcpy(dest, cres.c, len);
++			for (i = len; i < destlen; i++)
++				dest[i] = '\0';
++			*resultlen = destlen;
++			break;
++		case CS_FMT_UNUSED:
++			tdsdump_log(TDS_DBG_FUNC, "cs_convert() FMT_UNUSED\n");
++			memcpy(dest, cres.c, len);
++			*resultlen = len;
++			break;
++		default:
++			ret = CS_FAIL;
++			break;
+ 		}
+ 		free(cres.c);
+ 		break;
+diff --git a/src/ctlib/unittests/common.c b/src/ctlib/unittests/common.c
+index b563131..a9f0c2a 100644
+--- a/src/ctlib/unittests/common.c
++++ b/src/ctlib/unittests/common.c
+@@ -22,9 +22,11 @@
+ 
+ #include <ctpublic.h>
+ #include "common.h"
++#ifdef TDS_STATIC_CAST
+ #include "ctlib.h"
++#endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.22 2009/05/03 19:32:57 jklowden Exp $";
++static char software_version[] = "$Id: common.c,v 1.23 2010/04/13 13:19:12 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -210,7 +212,9 @@ continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd,
+ {
+ 	CS_RETCODE ret;
+ 	char query[30];
++#ifdef TDS_STATIC_CAST
+ 	TDSCONTEXT *tds_ctx;
++#endif
+ 
+ 	ret = cs_ctx_alloc(CS_VERSION_100, ctx);
+ 	if (ret != CS_SUCCEED) {
+@@ -220,12 +224,14 @@ continue_logging_in(CS_CONTEXT ** ctx, CS_CONNECTION ** conn, CS_COMMAND ** cmd,
+ 		return ret;
+ 	}
+ 
++#ifdef TDS_STATIC_CAST
+ 	/* Force default date format, some tests rely on it */
+ 	tds_ctx = (TDSCONTEXT *) (*ctx)->tds_ctx;
+ 	if (tds_ctx && tds_ctx->locale && tds_ctx->locale->date_fmt) {
+ 		free(tds_ctx->locale->date_fmt);
+ 		tds_ctx->locale->date_fmt = strdup("%b %d %Y %I:%M%p");
+ 	}
++#endif
+ 
+ 	ret = ct_init(*ctx, CS_VERSION_100);
+ 	if (ret != CS_SUCCEED) {
+diff --git a/src/ctlib/unittests/t0006.c b/src/ctlib/unittests/t0006.c
+index 0d98faa..23f5929 100644
+--- a/src/ctlib/unittests/t0006.c
++++ b/src/ctlib/unittests/t0006.c
+@@ -9,7 +9,7 @@
+ #include <stdio.h>
+ #include <ctpublic.h>
+ 
+-static char software_version[] = "$Id: t0006.c,v 1.12 2009/12/13 10:36:54 freddy77 Exp $";
++static char software_version[] = "$Id: t0006.c,v 1.13 2010/04/13 13:19:12 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ CS_CONTEXT *ctx;
+@@ -91,7 +91,7 @@ DoTest(
+ 	/* success */
+ 	return 0;
+       Failed:
+-	fprintf(stderr, "Test %s failed (ret=%d len=%d)\n", err, retcode, reslen);
++	fprintf(stderr, "Test %s failed (ret=%d len=%d)\n", err, (int) retcode, (int) reslen);
+ 	fprintf(stderr, "line: %d\n  DO_TEST(%s,\n"
+ 		"\t   %s,%s,%s,\n"
+ 		"\t   %s,%s,\n"
+@@ -111,7 +111,9 @@ int
+ main(int argc, char **argv)
+ {
+ 	CS_RETCODE ret;
++#ifdef tds_sysdep_int64_type
+ 	volatile tds_sysdep_int64_type one = 1;
++#endif
+ 	int verbose = 1;
+ 
+ 	fprintf(stdout, "%s: Testing conversion\n", __FILE__);
+@@ -235,6 +237,7 @@ main(int argc, char **argv)
+ 		-1230000}
+ 		, CS_CHAR_TYPE, test, 4, CS_MONEY4_TYPE, sizeof(test2), CS_SUCCEED, &test2, sizeof(test2));
+ 
++#ifdef tds_sysdep_int64_type
+ 	DO_TEST(CS_INT test = 1234678;
+ 		CS_MONEY test2;
+ 		test2.mnyhigh = ((one * 1234678) * 10000) >> 32;
+@@ -245,6 +248,7 @@ main(int argc, char **argv)
+ 		test2.mnyhigh = ((one * -8765) * 10000) >> 32;
+ 		test2.mnylow = (CS_UINT) ((one * -8765) * 10000),
+ 		CS_INT_TYPE, &test, sizeof(test), CS_MONEY_TYPE, sizeof(test2), CS_SUCCEED, &test2, sizeof(test2));
++#endif
+ 
+ 	DO_TEST(CS_INT test = 12345;
+ 		CS_CHAR test2[] = "12345",
+@@ -264,6 +268,30 @@ main(int argc, char **argv)
+ 	DO_TEST(CS_CHAR test[] = " - 12345";
+ 		CS_INT test2 = -12, CS_CHAR_TYPE, test, 5, CS_INT_TYPE, sizeof(test2), CS_SUCCEED, &test2, sizeof(test2));
+ 
++	/* to binary */
++	DO_TEST(CS_CHAR test[] = "abc";
++		CS_CHAR test2[] = "abc", CS_BINARY_TYPE, test, 3, CS_BINARY_TYPE, 3, CS_SUCCEED, test2, 3);
++#if 0
++	DO_TEST(CS_CHAR test[] = "abcdef";
++		CS_CHAR test2[] = "ab", CS_BINARY_TYPE, test, 6, CS_BINARY_TYPE, 2, CS_FAIL, test2, 2);
++	DO_TEST(CS_CHAR test[] = "abc";
++		CS_CHAR test2[] = "ab", CS_BINARY_TYPE, test, 3, CS_BINARY_TYPE, 2, CS_FAIL, test2, 2);
++#endif
++	DO_TEST(CS_CHAR test[] = "616263";
++		CS_CHAR test2[] = "abc", CS_CHAR_TYPE, test, 6, CS_BINARY_TYPE, 3, CS_SUCCEED, test2, 3);
++	DO_TEST(CS_CHAR test[] = "616263646566";
++		CS_CHAR test2[] = "abc", CS_CHAR_TYPE, test, 12, CS_BINARY_TYPE, 3, CS_FAIL, test2, 3);
++
++	/* to char */
++	DO_TEST(CS_INT test = 1234567;
++		CS_CHAR test2[] = "1234567", CS_INT_TYPE, &test, sizeof(test), CS_CHAR_TYPE, 7, CS_SUCCEED, test2, 7);
++	DO_TEST(CS_CHAR test[] = "abc";
++		CS_CHAR test2[] = "ab", CS_CHAR_TYPE, test, 3, CS_CHAR_TYPE, 2, CS_FAIL, test2, 2);
++	DO_TEST(CS_CHAR test[] = "abc";
++		CS_CHAR test2[] = "616263", CS_BINARY_TYPE, test, 3, CS_CHAR_TYPE, 6, CS_SUCCEED, test2, 6);
++	DO_TEST(CS_CHAR test[] = "abcdef";
++		CS_CHAR test2[] = "616263", CS_BINARY_TYPE, test, 6, CS_CHAR_TYPE, 6, CS_FAIL, test2, 6);
++
+ 	ret = cs_ctx_drop(ctx);
+ 	if (ret != CS_SUCCEED) {
+ 		fprintf(stderr, "Drop failed\n");
+
+commit b82b378cbc4e3001ec1a89c2bffda9d7c9652275
+Author: freddy77 <freddy77>
+Date:   Tue Apr 13 13:23:32 2010 +0000
+
+    improve datafmt->status computation (patch from David Dick)
+
+diff --git a/ChangeLog b/ChangeLog
+index 3fb8a12..c0bd53d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Apr 13 15:23:12 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c:
++	- improve datafmt->status computation (patch from David Dick)
++
+ Tue Apr 13 15:18:41 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/cs.c src/ctlib/unittests/common.c:
+ 	* src/ctlib/unittests/t0006.c:
+@@ -2402,4 +2406,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3010 2010/04/13 13:19:12 freddy77 Exp $
++$Id: ChangeLog,v 1.3011 2010/04/13 13:23:32 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index ec2406b..203d466 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.202 2009/12/13 09:48:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.203 2010/04/13 13:23:32 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2326,7 +2326,13 @@ ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt)
+ 		datafmt->status |= CS_CANBENULL;
+ 	if (curcol->column_identity)
+ 		datafmt->status |= CS_IDENTITY;
+-	if (strcmp(datafmt->name, "txts") == 0)
++	if (curcol->column_writeable)
++		datafmt->status |= CS_UPDATABLE;
++	if (curcol->column_key)
++		datafmt->status |= CS_KEY;
++	if (curcol->column_hidden)
++		datafmt->status |= CS_HIDDEN;
++	if (curcol->column_timestamp)
+ 		datafmt->status |= CS_TIMESTAMP;
+ 
+ 	datafmt->count = 1;
+
+commit 78c8658e5f5398ee5e0d4753a1819f4967d63b2d
+Author: freddy77 <freddy77>
+Date:   Mon Apr 26 09:09:48 2010 +0000
+
+    fix maxlength returned by ct_describe for numeric types
+
+diff --git a/ChangeLog b/ChangeLog
+index c0bd53d..a2b037d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Apr 26 11:09:11 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/ct.c src/ctlib/unittests/t0007.c:
++	- fix maxlength returned by ct_describe for numeric types
++
+ Tue Apr 13 15:23:12 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c:
+ 	- improve datafmt->status computation (patch from David Dick)
+@@ -2406,4 +2410,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3011 2010/04/13 13:23:32 freddy77 Exp $
++$Id: ChangeLog,v 1.3012 2010/04/26 09:09:48 freddy77 Exp $
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index 203d466..e103f55 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.203 2010/04/13 13:23:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.204 2010/04/26 09:09:49 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -2311,8 +2311,10 @@ ct_describe(CS_COMMAND * cmd, CS_INT item, CS_DATAFMT * datafmt)
+ 	datafmt->datatype = _ct_get_client_type(curcol);
+ 	tdsdump_log(TDS_DBG_INFO1, "ct_describe() datafmt->datatype = %d server type %d\n", datafmt->datatype,
+ 		    curcol->column_type);
+-	/* FIXME is ok this value for numeric/decimal? */
+-	datafmt->maxlength = curcol->column_size;
++	if (is_numeric_type(curcol->column_type))
++		datafmt->maxlength = sizeof(CS_NUMERIC);
++	else
++		datafmt->maxlength = curcol->column_size;
+ 	datafmt->usertype = curcol->column_usertype;
+ 	datafmt->precision = curcol->column_prec;
+ 	datafmt->scale = curcol->column_scale;
+diff --git a/src/ctlib/unittests/t0007.c b/src/ctlib/unittests/t0007.c
+index 407ac83..b2a3d91 100644
+--- a/src/ctlib/unittests/t0007.c
++++ b/src/ctlib/unittests/t0007.c
+@@ -10,7 +10,7 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0007.c,v 1.9 2007/06/19 12:07:59 freddy77 Exp $";
++static char software_version[] = "$Id: t0007.c,v 1.10 2010/04/26 09:09:50 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Testing: Retrieve CS_TEXT_TYPE using ct_bind() */
+@@ -27,16 +27,17 @@ main(int argc, char **argv)
+ 	CS_INT result_type;
+ 	CS_INT num_cols;
+ 
+-	CS_DATAFMT datafmt[3];
+-	CS_INT datalength[3];
+-	CS_SMALLINT ind[3];
++	CS_DATAFMT datafmt[4];
++	CS_INT datalength[4];
++	CS_SMALLINT ind[4];
+ 	CS_INT count, row_count = 0;
+ 
+-	CS_CHAR name[3][1024];
++	CS_CHAR name[4][1024];
+ 
+ 	name[0][0] = 0;
+ 	name[1][0] = 0;
+ 	name[2][0] = 0;
++	name[3][0] = 0;
+ 
+ 	fprintf(stdout, "%s: Retrieve CS_CHAR_TYPE using ct_bind()\n", __FILE__);
+ 	if (verbose) {
+@@ -48,7 +49,7 @@ main(int argc, char **argv)
+ 		return 1;
+ 	}
+ 
+-	ret = ct_command(cmd, CS_LANG_CMD, "SELECT CONVERT(VARCHAR(7),'1234') AS test, CONVERT(VARCHAR(7),'') AS test2, CONVERT(VARCHAR(7),NULL) AS test3", CS_NULLTERM, CS_UNUSED);
++	ret = ct_command(cmd, CS_LANG_CMD, "SELECT CONVERT(VARCHAR(7),'1234') AS test, CONVERT(VARCHAR(7),'') AS test2, CONVERT(VARCHAR(7),NULL) AS test3, CONVERT(NUMERIC(38,2), 123.45) as test4", CS_NULLTERM, CS_UNUSED);
+ 	if (ret != CS_SUCCEED) {
+ 		fprintf(stderr, "ct_command() failed\n");
+ 		return 1;
+@@ -73,8 +74,8 @@ main(int argc, char **argv)
+ 				fprintf(stderr, "ct_res_info() failed");
+ 				return 1;
+ 			}
+-			if (num_cols != 3) {
+-				fprintf(stderr, "num_cols %d != 1", num_cols);
++			if (num_cols != 4) {
++				fprintf(stderr, "num_cols %d != 4", num_cols);
+ 				return 1;
+ 			}
+ 			if (ct_describe(cmd, 1, &datafmt[0]) != CS_SUCCEED) {
+@@ -98,7 +99,7 @@ main(int argc, char **argv)
+ 			}
+ 
+ 			if (ct_describe(cmd, 3, &datafmt[2]) != CS_SUCCEED) {
+-				fprintf(stderr, "ct_describe() failed");
++				fprintf(stderr, "ct_describe() failed\n");
+ 				return 1;
+ 			}
+ 			datafmt[2].format = CS_FMT_NULLTERM;
+@@ -107,6 +108,20 @@ main(int argc, char **argv)
+ 				datafmt[2].maxlength = 1024;
+ 			}
+ 
++			if (ct_describe(cmd, 4, &datafmt[3]) != CS_SUCCEED) {
++				fprintf(stderr, "ct_describe() failed\n");
++				return 1;
++			}
++			datafmt[3].format = CS_FMT_NULLTERM;
++			if (datafmt[3].maxlength != sizeof(CS_NUMERIC)) {
++				fprintf(stderr, "wrong maxlength for numeric\n");
++				return 1;
++			}
++			++datafmt[3].maxlength;
++			if (datafmt[3].maxlength > 1024) {
++				datafmt[3].maxlength = 1024;
++			}
++
+ 			if (ct_bind(cmd, 1, &datafmt[0], name[0], &datalength[0], &ind[0]) != CS_SUCCEED) {
+ 				fprintf(stderr, "ct_bind() failed\n");
+ 				return 1;
+@@ -119,6 +134,10 @@ main(int argc, char **argv)
+ 				fprintf(stderr, "ct_bind() failed\n");
+ 				return 1;
+ 			}
++			if (ct_bind(cmd, 4, &datafmt[3], name[3], &datalength[3], &ind[3]) != CS_SUCCEED) {
++				fprintf(stderr, "ct_bind() failed\n");
++				return 1;
++			}
+ 
+ 			while (((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) == CS_SUCCEED)
+ 			       || (ret == CS_ROW_FAIL)) {
+
+commit 8278cff1fb9b7ed41ef477adefd7dabaf617bfde
+Author: jklowden <jklowden>
+Date:   Fri Apr 30 21:59:42 2010 +0000
+
+    initilize client charset per setlocale(3) and friends
+
+diff --git a/ChangeLog b/ChangeLog
+index a2b037d..015df49 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Apr 30 17:57:22 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* src/tds/mem.c initilize client charset per setlocale(3) and friends
++
+ Mon Apr 26 11:09:11 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/ct.c src/ctlib/unittests/t0007.c:
+ 	- fix maxlength returned by ct_describe for numeric types
+@@ -2410,4 +2413,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3012 2010/04/26 09:09:48 freddy77 Exp $
++$Id: ChangeLog,v 1.3013 2010/04/30 21:59:42 jklowden Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index c17209b..4624330 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -37,11 +37,23 @@
+ #include "replacements.h"
+ #include "enum_cap.h"
+ 
++#ifdef STRING_H
++#include <string.h>
++#endif
++
++#ifdef HAVE_LOCALE_H
++#include <locale.h>
++#endif /* HAVE_LOCALE_H */
++
++#ifdef HAVE_LANGINFO_H
++#include <langinfo.h>
++#endif /* HAVE_LANGINFO_H */
++
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.196 2010/01/11 18:14:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.197 2010/04/30 21:59:43 jklowden Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -678,8 +690,29 @@ TDSLOCALE *
+ tds_alloc_locale(void)
+ {
+ 	TDSLOCALE *locale;
++#if !(HAVE_NL_LANGINFO && defined(CODESET))
++	char *lc_all;
++#endif
+ 
+ 	TEST_MALLOC(locale, TDSLOCALE);
++
++	locale->client_charset = strdup("ISO-8859-1"); 
++	
++#if HAVE_NL_LANGINFO && defined(CODESET)
++	locale->client_charset = nl_langinfo(CODESET);
++#else
++	if ((lc_all = strdup(setlocale(LC_ALL, NULL)) == NULL)
++		goto Cleanup;
++
++	if (strtok(lc_all, ".")) {
++		char *encoding = strtok(NULL, "@");
++		if (encoding) {
++			locale->client_charset = strdup(encoding);
++		}
++	}
++#endif
++	tdsdump_log(TDS_DBG_FUNC, "tds_alloc_locale(): initialized locale to \"%s\"\n", locale->client_charset? locale->client_charset : "NULL");
++
+ 	return locale;
+ 
+       Cleanup:
+
+commit 18dbe4cc1416ea3b41c24aeba18ddc45638b9a98
+Author: freddy77 <freddy77>
+Date:   Sun May 2 11:52:13 2010 +0000
+
+    fix unmatched parenthesis (patch from Mark Brand) and minor memory leaks
+
+diff --git a/ChangeLog b/ChangeLog
+index 015df49..cdc757f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sun May  2 13:52:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c:
++	- fix unmatched parenthesis (patch from Mark Brand) and minor
++	  memory leaks
++
+ Fri Apr 30 17:57:22 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/mem.c initilize client charset per setlocale(3) and friends
+ 
+@@ -2413,4 +2418,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3013 2010/04/30 21:59:42 jklowden Exp $
++$Id: ChangeLog,v 1.3014 2010/05/02 11:52:13 freddy77 Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 4624330..1977c19 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.197 2010/04/30 21:59:43 jklowden Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.198 2010/05/02 11:52:13 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -696,26 +696,33 @@ tds_alloc_locale(void)
+ 
+ 	TEST_MALLOC(locale, TDSLOCALE);
+ 
+-	locale->client_charset = strdup("ISO-8859-1"); 
+-	
+ #if HAVE_NL_LANGINFO && defined(CODESET)
+-	locale->client_charset = nl_langinfo(CODESET);
++	locale->client_charset = strdup(nl_langinfo(CODESET));
+ #else
+-	if ((lc_all = strdup(setlocale(LC_ALL, NULL)) == NULL)
++	locale->client_charset = strdup("ISO-8859-1");
++	if (!locale->client_charset)
++		goto Cleanup;
++
++	if ((lc_all = strdup(setlocale(LC_ALL, NULL))) == NULL)
+ 		goto Cleanup;
+ 
+ 	if (strtok(lc_all, ".")) {
+ 		char *encoding = strtok(NULL, "@");
+ 		if (encoding) {
++			free(locale->client_charset);
+ 			locale->client_charset = strdup(encoding);
+ 		}
+ 	}
++	free(lc_all);
+ #endif
++	if (!locale->client_charset)
++		goto Cleanup;
+ 	tdsdump_log(TDS_DBG_FUNC, "tds_alloc_locale(): initialized locale to \"%s\"\n", locale->client_charset? locale->client_charset : "NULL");
+ 
+ 	return locale;
+ 
+       Cleanup:
++	tds_free_locale(locale);
+ 	return NULL;
+ }
+ static const unsigned char defaultcaps[] = { 
+
+commit a926d3b8f3e132b5cb391bc0efaa23273b254053
+Author: jklowden <jklowden>
+Date:   Fri May 7 02:55:27 2010 +0000
+
+    tidied up and added explicit test for null varchar input
+
+diff --git a/ChangeLog b/ChangeLog
+index cdc757f..70dde64 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu May  6 21:08:58 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* src/dblib/unittests/rpc.c src/dblib/unittests/rpc.sql
++	- tidied up and added explicit test for null varchar input	
++
+ Sun May  2 13:52:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/mem.c:
+ 	- fix unmatched parenthesis (patch from Mark Brand) and minor
+@@ -2418,4 +2422,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3014 2010/05/02 11:52:13 freddy77 Exp $
++$Id: ChangeLog,v 1.3015 2010/05/07 02:55:27 jklowden Exp $
+diff --git a/src/dblib/unittests/rpc.c b/src/dblib/unittests/rpc.c
+index e02eefe..903ba14 100644
+--- a/src/dblib/unittests/rpc.c
++++ b/src/dblib/unittests/rpc.c
+@@ -5,7 +5,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.38 2009/02/27 15:52:48 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.39 2010/05/07 02:55:27 jklowden Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int init_proc(DBPROCESS * dbproc, const char *name);
+@@ -128,6 +128,25 @@ colwidth( DBPROCESS * dbproc, int icol )
+ 	return 255 == width? dbcollen(dbproc, icol) : width;
+ }
+ 
++char param_data1[64];
++int param_data2, param_data3;
++
++struct parameters_t {
++	char         *name;
++	BYTE         status;
++	int          type;
++	DBINT        maxlen;
++	DBINT        datalen;
++	BYTE         *value;
++} bindings[] = 
++	{ { "@null_input", DBRPCRETURN, SYBCHAR,  -1,   0, NULL }
++	, { "@first_type", DBRPCRETURN, SYBCHAR,  sizeof(param_data1), 0, (BYTE *) &param_data1 }
++	, { "@nullout",    DBRPCRETURN, SYBINT4,  -1,   0, (BYTE *) &param_data2 }
++	, { "@nrows",      DBRPCRETURN, SYBINT4,  -1,  -1, (BYTE *) &param_data3 }
++	, { "@c",          0,        SYBVARCHAR,   0,   0, NULL }
++	, { "@nv",         0,        SYBVARCHAR,  -1,   2, (BYTE *) "OK:" }
++	}, *pb = bindings;
++
+ int
+ main(int argc, char **argv)
+ {
+@@ -139,17 +158,9 @@ main(int argc, char **argv)
+ 	char *retname = NULL;
+ 	int i, failed = 0;
+ 	int rettype = 0, retlen = 0, return_status = 0;
+-	char proc[] = "#t0022", 
+-	     param0[] = "@null_input", 
+-	     param1[] = "@first_type", 
+-	     param2[] = "@nullout",
+-	     param3[] = "@nrows",
+-	     param4[] = "@c",
+-	     param5[] = "@nv";
++	char proc[] = "#t0022";
+ 	char *proc_name = proc;
+ 
+-	char param_data1[64];
+-	int param_data2, param_data3;
+ 	int num_resultset = 0, num_empty_resultset = 0;
+ 
+ 	static const char dashes30[] = "------------------------------";
+@@ -220,49 +231,14 @@ main(int argc, char **argv)
+ 		failed = 1;
+ 	}
+ 
+-	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param0, DBRPCRETURN, SYBCHAR, /*maxlen= */ -1, /* datlen= */ 0, NULL);
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+-		failed = 1;
+-	}
+-
+-	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param1, DBRPCRETURN, SYBCHAR, /*maxlen= */ sizeof(param_data1), /* datlen= */ 0, (BYTE *) & param_data1);
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+-		failed = 1;
+-	}
+-
+-	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param2, DBRPCRETURN, SYBINT4, /*maxlen= */ -1, /* datalen= */ 0, (BYTE *) & param_data2);
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+-		failed = 1;
+-	}
+-
+-	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param3, DBRPCRETURN, SYBINT4, /*maxlen= */ -1, /* datalen= */ -1, (BYTE *) & param_data3);
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+-		failed = 1;
+-	}
+-
+-	/* test for strange parameters using input */
+-	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param4, 0, SYBVARCHAR, /*maxlen= */ 0, /* datalen= */ 0, NULL);
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+-		failed = 1;
+-	}
++	for (pb = bindings; pb < bindings + sizeof(bindings)/sizeof(bindings[0]); pb++) {
++		printf("executing dbrpcparam for %s\n", pb->name);
++		if ((erc = dbrpcparam(dbproc, pb->name, pb->status, pb->type, pb->maxlen, pb->datalen, pb->value)) == FAIL) {
++			fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
++			failed++;
++		}
+ 
+-	printf("executing dbrpcparam\n");
+-	erc = dbrpcparam(dbproc, param5, 0, SYBVARCHAR, /*maxlen= */ -1, /* datalen= */ 2, (BYTE *) "OK:");
+-	if (erc == FAIL) {
+-		fprintf(stderr, "Failed line %d: dbrpcparam\n", __LINE__);
+-		failed = 1;
+ 	}
+-
+ 	printf("executing dbrpcsend\n");
+ 	param_data3 = 0x11223344;
+ 	erc = dbrpcsend(dbproc);
+@@ -366,8 +342,8 @@ main(int argc, char **argv)
+ 	/* 
+ 	 * Test the last parameter for expected outcome 
+ 	 */
+-	if ((save_param.name == NULL) || strcmp(save_param.name, param3)) {
+-		fprintf(stderr, "Expected retname to be '%s', got ", param3);
++	if ((save_param.name == NULL) || strcmp(save_param.name, bindings[3].name)) {
++		fprintf(stderr, "Expected retname to be '%s', got ", bindings[3].name);
+ 		if (save_param.name == NULL) 
+ 			fprintf(stderr, "<NULL> instead.\n");
+ 		else
+@@ -396,8 +372,8 @@ main(int argc, char **argv)
+ 
+ 
+ 	/* Test number of result sets */
+-	if (num_resultset != 3) {
+-		fprintf(stderr, "Expected 3 resultset got %d.\n", num_resultset);
++	if (num_resultset != 4) {
++		fprintf(stderr, "Expected 4 resultset got %d.\n", num_resultset);
+ 		exit(1);
+ 	}
+ 	if (num_empty_resultset != 1) {
+diff --git a/src/dblib/unittests/rpc.sql b/src/dblib/unittests/rpc.sql
+index 7e73cc0..a1fb520 100644
+--- a/src/dblib/unittests/rpc.sql
++++ b/src/dblib/unittests/rpc.sql
+@@ -7,6 +7,18 @@ CREATE PROCEDURE #t0022
+ , @nv nvarchar(20) = N'hello'
+ AS 
+ BEGIN 
++if @null_input is not NULL begin 
++	select 'error: should be NULL' as status, @null_input as '@null_input'
++	return -42
++end else begin
++	print 'Good: @null_input is NULL'
++end
++if @c is not NULL begin 
++	select 'error: should be NULL' as status, @c as '@c'
++	return -42
++end else begin
++	print 'Good: @c is NULL'
++end
+ select @null_input = max(convert(varchar(30), name)) from systypes 
+ select @first_type = min(convert(varchar(30), name)) from systypes 
+ select name from sysobjects where 0=1
+@@ -14,6 +26,14 @@ select distinct convert(varchar(30), name) as 'type'  from systypes
+ where name in ('int', 'char', 'text') 
+ select @nrows = @@rowcount 
+ select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' 
++select	  @null_input as '@null_input'
++	, @first_type as '@first_type'
++	, @nullout as '@nullout'
++	, @nrows as '@nrows'
++	, @c as '@c'
++	, @nv as '@nv'
++	into #parameters
++select * from #parameters
+ return 42 
+ END 
+ 
+@@ -29,6 +49,18 @@ CREATE PROCEDURE t0022
+ , @nv nvarchar(20) = N'hello'
+ AS 
+ BEGIN 
++if @null_input is not NULL begin 
++	select 'error: should be NULL' as status, @null_input as '@null_input'
++	return -42
++end else begin
++	print '@null_input is NULL, as expected'
++end
++if @c is not NULL begin 
++	select 'error: should be NULL' as status, @c as '@c'
++	return -42
++end else begin
++	print 'Good: @c is NULL'
++end
+ select @null_input = max(convert(varchar(30), name)) from systypes 
+ select @first_type = min(convert(varchar(30), name)) from systypes 
+ select name from sysobjects where 0=1
+@@ -36,6 +68,14 @@ select distinct convert(varchar(30), name) as 'type'  from systypes
+ where name in ('int', 'char', 'text') 
+ select @nrows = @@rowcount 
+ select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' 
++select	  @null_input as '@null_input'
++	, @first_type as '@first_type'
++	, @nullout as '@nullout'
++	, @nrows as '@nrows'
++	, @c as '@c'
++	, @nv as '@nv'
++	into #parameters
++select * from #parameters
+ return 42 
+ END 
+ 
+
+commit e53947a630d3833e27f7d0b8ed13a75a95c0f5ac
+Author: jklowden <jklowden>
+Date:   Fri May 7 20:18:29 2010 +0000
+
+    produce gzip tarball, too.
+
+diff --git a/ChangeLog b/ChangeLog
+index 70dde64..4d9c8ad 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri May  7 13:55:20 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* configure.ac produce gzip tarball, too. 
++
+ Thu May  6 21:08:58 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/dblib/unittests/rpc.c src/dblib/unittests/rpc.sql
+ 	- tidied up and added explicit test for null varchar input	
+@@ -2422,4 +2425,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3015 2010/05/07 02:55:27 jklowden Exp $
++$Id: ChangeLog,v 1.3016 2010/05/07 20:18:29 jklowden Exp $
+diff --git a/configure.ac b/configure.ac
+index db49bf0..61dabb5 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.46 2010/02/01 10:10:19 freddy77 Exp $
++dnl $Id: configure.ac,v 1.47 2010/05/07 20:18:38 jklowden Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,9 +15,9 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.46 $)
++AC_REVISION($Revision: 1.47 $)
+ 
+-AM_INIT_AUTOMAKE([dist-bzip2 no-dist-gzip])
++AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+ 
+ dnl configuration directory will be /usr/local/etc
+
+commit 4b38e899236920b2eb1ddada3c3280b9243fc73d
+Author: jklowden <jklowden>
+Date:   Fri May 7 21:11:29 2010 +0000
+
+    Applied today's ML patch from Craig A. Berry
+
+diff --git a/ChangeLog b/ChangeLog
+index 4d9c8ad..d162c3d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri May  7 17:09:50 EDT 2010	JK Lowden <jklowden@freetds.org>
++	* src/tds/token.c Applied today's ML patch from Craig A. Berry
++
+ Fri May  7 13:55:20 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* configure.ac produce gzip tarball, too. 
+ 
+@@ -2425,4 +2428,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3016 2010/05/07 20:18:29 jklowden Exp $
++$Id: ChangeLog,v 1.3017 2010/05/07 21:11:29 jklowden Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index c51e80b..3939428 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.383 2010/04/08 08:19:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.384 2010/05/07 21:11:30 jklowden Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -347,9 +347,9 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 			
+ 			ver.major = tds_get_byte(tds);
+ 			ver.minor = tds_get_byte(tds);
++			ver.tiny[0] = tds_get_byte(tds);
+ 			ver.tiny[1] = tds_get_byte(tds);
+-			ver.tiny[2] = tds_get_byte(tds);
+-			ver.reported = (ver.major << 24) | (ver.minor << 16) | (ver.tiny[1] << 8) | ver.tiny[2];
++			ver.reported = (ver.major << 24) | (ver.minor << 16) | (ver.tiny[0] << 8) | ver.tiny[1];
+ 			
+ 			/* Log reported server product name, cf. MS-TDS LOGINACK documentation. */
+ 			switch(ver.reported) {
+@@ -370,7 +370,7 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 			}
+ 			
+ 			tdsdump_log(TDS_DBG_FUNC, "server reports TDS version %x.%x.%x.%x\n", 
+-							ver.major, ver.minor, ver.tiny[1], ver.tiny[2]);
++							ver.major, ver.minor, ver.tiny[0], ver.tiny[1]);
+ 			tdsdump_log(TDS_DBG_FUNC, "Product name for 0x%x is %s\n", ver.reported, ver.name);
+ 			
+ 			/* Get server product name. */
+
+commit cc2abb95a95a4af1bfdae8fa006c50e95a75ab87
+Author: freddy77 <freddy77>
+Date:   Mon May 10 15:10:42 2010 +0000
+
+    improve Visual Studio compile
+
+diff --git a/ChangeLog b/ChangeLog
+index d162c3d..cf6b86f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon May 10 17:10:10 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h src/dblib/dbopen.c:
++	- improve Visual Studio compile
++
+ Fri May  7 17:09:50 EDT 2010	JK Lowden <jklowden@freetds.org>
+ 	* src/tds/token.c Applied today's ML patch from Craig A. Berry
+ 
+@@ -2428,4 +2432,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3017 2010/05/07 21:11:29 jklowden Exp $
++$Id: ChangeLog,v 1.3018 2010/05/10 15:10:42 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index dbe30e2..7a4a5c2 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.32 2010/02/09 08:40:07 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.33 2010/05/10 15:10:47 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -107,9 +107,10 @@ typedef DWORD pid_t;
+ #define TDS_SDIR_SEPARATOR "\\"
+ 
+ /* use macros to use new style names */
+-#ifdef __MSVCRT__
++#if defined(__MSVCRT__) || defined(_MSC_VER)
+ #define getpid()           _getpid()
+ #define strdup(s)          _strdup(s)
++#define fileno(f)          _fileno(f)
+ #define stricmp(s1,s2)     _stricmp(s1,s2)
+ #define strnicmp(s1,s2,n)  _strnicmp(s1,s2,n)
+ #endif
+diff --git a/src/dblib/dbopen.c b/src/dblib/dbopen.c
+index 4e61b6d..f1f4b44 100644
+--- a/src/dblib/dbopen.c
++++ b/src/dblib/dbopen.c
+@@ -22,7 +22,7 @@
+ #endif
+ 
+ #include <tds.h>
+-#include <../../include/sybdb.h>
++#include <sybdb.h>
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+@@ -32,7 +32,7 @@
+ #undef dbopen
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dbopen.c,v 1.13 2009/10/23 19:21:45 jklowden Exp $");
++TDS_RCSID(var, "$Id: dbopen.c,v 1.14 2010/05/10 15:10:47 freddy77 Exp $");
+ 
+ /**
+  * Normally not used. 
+
+commit 3b914627445d66c2f8277abe288ccb8cc01fd8ab
+Author: freddy77 <freddy77>
+Date:   Wed May 12 08:00:10 2010 +0000
+
+    workaround for header incompatibility
+
+diff --git a/ChangeLog b/ChangeLog
+index cf6b86f..4043ceb 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 12 09:59:17 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: workaround for header incompatibility
++
+ Mon May 10 17:10:10 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h src/dblib/dbopen.c:
+ 	- improve Visual Studio compile
+@@ -2432,4 +2435,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3018 2010/05/10 15:10:42 freddy77 Exp $
++$Id: ChangeLog,v 1.3019 2010/05/12 08:00:10 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 953f576..5fe7d72 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.102 2010/03/01 12:38:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.103 2010/05/12 08:00:11 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -148,8 +148,12 @@ _tds_socket_done(void)
+ }
+ #endif
+ 
+-#if !defined(SOL_TCP) && defined(IPPROTO_TCP)
+-#define SOL_TCP IPPROTO_TCP
++#if !defined(SOL_TCP) && (defined(IPPROTO_TCP) || defined(_WIN32))
++/* fix incompatibility between MS headers */
++# ifndef IPPROTO_TCP
++#  define IPPROTO_TCP IPPROTO_TCP
++# endif
++# define SOL_TCP IPPROTO_TCP
+ #endif
+ 
+ /* Optimize the way we send packets */
+
+commit f5076242192fce135296058baa6088c409dc0a1b
+Author: freddy77 <freddy77>
+Date:   Wed May 12 08:13:58 2010 +0000
+
+    fix minor issue with MingW
+
+diff --git a/ChangeLog b/ChangeLog
+index 4043ceb..1823424 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 12 10:13:17 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds_sysdep_private.h: fix minor issue with MingW
++
+ Wed May 12 09:59:17 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: workaround for header incompatibility
+ 
+@@ -2435,4 +2438,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3019 2010/05/12 08:00:10 freddy77 Exp $
++$Id: ChangeLog,v 1.3020 2010/05/12 08:13:58 freddy77 Exp $
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index 7a4a5c2..c04a39d 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.33 2010/05/10 15:10:47 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.34 2010/05/12 08:13:58 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -110,6 +110,7 @@ typedef DWORD pid_t;
+ #if defined(__MSVCRT__) || defined(_MSC_VER)
+ #define getpid()           _getpid()
+ #define strdup(s)          _strdup(s)
++#undef fileno
+ #define fileno(f)          _fileno(f)
+ #define stricmp(s1,s2)     _stricmp(s1,s2)
+ #define strnicmp(s1,s2,n)  _strnicmp(s1,s2,n)
+
+commit 8c208a877d30b53a11d9caa0a49fad899201f4fa
+Author: freddy77 <freddy77>
+Date:   Wed May 12 08:15:27 2010 +0000
+
+    fix and improve fakepoll for Windows
+
+diff --git a/ChangeLog b/ChangeLog
+index 1823424..689b4b0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed May 12 10:15:04 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/fakepoll.h src/replacements/fakepoll.c:
++	- fix and improve fakepoll for Windows
++
+ Wed May 12 10:13:17 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds_sysdep_private.h: fix minor issue with MingW
+ 
+@@ -2438,4 +2442,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3020 2010/05/12 08:13:58 freddy77 Exp $
++$Id: ChangeLog,v 1.3021 2010/05/12 08:15:27 freddy77 Exp $
+diff --git a/include/fakepoll.h b/include/fakepoll.h
+index 74cd7d4..5b77fde 100644
+--- a/include/fakepoll.h
++++ b/include/fakepoll.h
+@@ -1,4 +1,4 @@
+-/* $Id: fakepoll.h,v 1.3 2010/01/10 14:43:11 freddy77 Exp $ */
++/* $Id: fakepoll.h,v 1.4 2010/05/12 08:15:27 freddy77 Exp $ */
+ #if !defined(_FAKE_POLL_H) && !defined(HAVE_POLL)
+ #define _FAKE_POLL_H
+ 
+@@ -30,29 +30,49 @@
+ #define FD_SETSIZE OPEN_MAX
+ #endif
+ 
+-// poll flags
+-#define POLLIN  0x0001
+-#define POLLOUT 0x0004
+-#define POLLERR 0x0008
++#ifndef _WIN32
++/* poll flags */
++# define POLLIN  0x0001
++# define POLLOUT 0x0004
++# define POLLERR 0x0008
+ 
+-// synonyms
+-#define POLLNORM POLLIN
+-#define POLLPRI POLLIN
+-#define POLLRDNORM POLLIN
+-#define POLLRDBAND POLLIN
+-#define POLLWRNORM POLLOUT
+-#define POLLWRBAND POLLOUT
+-
+-// ignored
+-#define POLLHUP 0x0010
+-#define POLLNVAL 0x0020
++/* synonyms */
++# define POLLNORM POLLIN
++# define POLLPRI POLLIN
++# define POLLRDNORM POLLIN
++# define POLLRDBAND POLLIN
++# define POLLWRNORM POLLOUT
++# define POLLWRBAND POLLOUT
+ 
++/* ignored */
++# define POLLHUP 0x0010
++# define POLLNVAL 0x0020
+ typedef struct pollfd {
+     int fd;		/* file descriptor to poll */
+     short events;	/* events of interest on fd */
+     short revents;	/* events that occurred on fd */
+ } pollfd_t;
+ 
++#else /* Windows */
++/*
++ * Windows use different constants then Unix
++ * Newer version have a WSAPoll which is equal to Unix poll
++ */
++# if !defined(POLLRDNORM) && !defined(POLLWRNORM)
++#  define POLLIN  0x0300
++#  define POLLOUT 0x0010
++#  define POLLERR 0x0001
++#  define POLLRDNORM 0x0100
++#  define POLLWRNORM 0x0010
++typedef struct pollfd {
++    SOCKET fd;	/* file descriptor to poll */
++    short events;	/* events of interest on fd */
++    short revents;	/* events that occurred on fd */
++} pollfd_t;
++# else
++typedef struct pollfd pollfd_t;
++# endif
++#endif
+ 
+ int fakepoll(struct pollfd fds[], int nfds, int timeout);
+ 
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index 3899c2b..81cc5ce 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -23,7 +23,7 @@
+ 
+ #ifndef HAVE_POLL
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.8 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.9 2010/05/12 08:15:27 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include <stdarg.h>
+@@ -68,6 +68,22 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 	const struct pollfd *endp = fds? fds + nfds : NULL;
+ 	int selected, polled = 0, maxfd = 0;
+ 
++#if defined(_WIN32)
++	typedef int WSAAPI (*WSAPoll_t)(struct pollfd fds[], ULONG nfds, INT timeout);
++	static WSAPoll_t poll_p = (WSAPoll_t) -1;
++	if (poll_p == (WSAPoll_t) -1) {
++		HMODULE mod;
++
++		poll_p = NULL;
++		mod = GetModuleHandle("ws2_32");
++		if (mod)
++			poll_p = (WSAPoll_t) GetProcAddress(mod, "WSAPoll");
++	}
++	/* Windows 2008 have WSAPoll which is semantically equal to poll */
++	if (poll_p != NULL)
++		return poll_p(fds, nfds, timeout);
++#endif
++
+ 	if (fds == NULL) {
+ 		errno = EFAULT;
+ 		return -1;
+
+commit 30a94937a0d46a7ed38ebea801926da9ddcde6f2
+Author: freddy77 <freddy77>
+Date:   Wed May 12 11:19:16 2010 +0000
+
+    small compile fix for Visual Studio
+
+diff --git a/ChangeLog b/ChangeLog
+index 689b4b0..344b19a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed May 12 13:18:25 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/fakepoll.c: small compile fix for Visual Studio
++
+ Wed May 12 10:15:04 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/fakepoll.h src/replacements/fakepoll.c:
+ 	- fix and improve fakepoll for Windows
+@@ -2442,4 +2445,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3021 2010/05/12 08:15:27 freddy77 Exp $
++$Id: ChangeLog,v 1.3022 2010/05/12 11:19:16 freddy77 Exp $
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index 81cc5ce..b6ad165 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -23,7 +23,7 @@
+ 
+ #ifndef HAVE_POLL
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.9 2010/05/12 08:15:27 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.10 2010/05/12 11:19:16 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include <stdarg.h>
+@@ -69,7 +69,7 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 	int selected, polled = 0, maxfd = 0;
+ 
+ #if defined(_WIN32)
+-	typedef int WSAAPI (*WSAPoll_t)(struct pollfd fds[], ULONG nfds, INT timeout);
++	typedef int (WSAAPI *WSAPoll_t)(struct pollfd fds[], ULONG nfds, INT timeout);
+ 	static WSAPoll_t poll_p = (WSAPoll_t) -1;
+ 	if (poll_p == (WSAPoll_t) -1) {
+ 		HMODULE mod;
+
+commit 87f5f9ecacd1ad1e7659d981bd1413c3299eff9c
+Author: freddy77 <freddy77>
+Date:   Thu May 13 22:06:38 2010 +0000
+
+    remove Dev-C++ project files (obsolete)
+
+diff --git a/ChangeLog b/ChangeLog
+index 344b19a..149386e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri May 14 00:06:28 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac win32/Makefile.am win32/freetds.nsi:
++	- remove Dev-C++ project files (obsolete)
++
+ Wed May 12 13:18:25 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/fakepoll.c: small compile fix for Visual Studio
+ 
+@@ -2445,4 +2449,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3022 2010/05/12 11:19:16 freddy77 Exp $
++$Id: ChangeLog,v 1.3023 2010/05/13 22:06:38 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 61dabb5..45f3f12 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.47 2010/05/07 20:18:38 jklowden Exp $
++dnl $Id: configure.ac,v 1.48 2010/05/13 22:06:38 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.47 $)
++AC_REVISION($Revision: 1.48 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -816,7 +816,7 @@ AC_CONFIG_FILES(include/tdsver.h \
+ 	src/apps/Makefile \
+ 	src/apps/fisql/Makefile \
+ 	freetds.spec \
+-	win32/Makefile win32/msvc6/Makefile win32/dev-cpp/Makefile \
++	win32/Makefile win32/msvc6/Makefile \
+ 	win32/version.rc win32/freetds.nsh
+ )
+ AC_OUTPUT
+diff --git a/win32/Makefile.am b/win32/Makefile.am
+index 1edad91..78190d0 100644
+--- a/win32/Makefile.am
++++ b/win32/Makefile.am
+@@ -1,4 +1,4 @@
+-SUBDIRS	= msvc6 dev-cpp
++SUBDIRS	= msvc6
+ EXTRA_DIST      = config.h FreeTDS.def initnet.c \
+ 		tds_sysdep_public.h freetds_sysconfdir.h \
+ 		winsetup.c winlogin.c \
+diff --git a/win32/freetds.nsi b/win32/freetds.nsi
+index 9db5ae4..fca3eaf 100644
+--- a/win32/freetds.nsi
++++ b/win32/freetds.nsi
+@@ -53,7 +53,7 @@ ShowUnInstDetails show
+ Section "MainSection" SEC01
+   SetOutPath "$SYSDIR"
+   SetOverwrite ifnewer
+-  File "dev-cpp\FreeTDS.dll"
++  File ".\FreeTDS.dll"
+ 
+   ; install driver
+   WriteRegStr ${ODBC_ROOT_KEY} "${ODBC_REGKEY}" "Driver" "$SYSDIR\FreeTDS.dll"
+
+commit 9bec9ba3608aebb647c676bafb5cf6de85b5da12
+Author: freddy77 <freddy77>
+Date:   Fri May 21 13:54:27 2010 +0000
+
+    freebcp's direction doesn't need to be case sensitive (from Craig A. Berry).
+
+diff --git a/ChangeLog b/ChangeLog
+index 149386e..8af38c7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri May 21 15:53:53 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/freebcp.c:
++	- freebcp's direction doesn't need to be case sensitive (from Craig
++	  A. Berry).
++
+ Fri May 14 00:06:28 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac win32/Makefile.am win32/freetds.nsi:
+ 	- remove Dev-C++ project files (obsolete)
+@@ -2449,4 +2454,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3023 2010/05/13 22:06:38 freddy77 Exp $
++$Id: ChangeLog,v 1.3024 2010/05/21 13:54:27 freddy77 Exp $
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 2c75a19..c5f49db 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -46,7 +46,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.51 2009/07/23 18:22:00 freddy77 Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.52 2010/05/21 13:54:28 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -173,11 +173,11 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 	/* argument 2 - the direction */
+ 	tds_strlcpy(pdata->dbdirection, argv[2], sizeof(pdata->dbdirection));
+ 
+-	if (strcmp(pdata->dbdirection, "in") == 0) {
++	if (strcasecmp(pdata->dbdirection, "in") == 0) {
+ 		pdata->direction = DB_IN;
+-	} else if (strcmp(pdata->dbdirection, "out") == 0) {
++	} else if (strcasecmp(pdata->dbdirection, "out") == 0) {
+ 		pdata->direction = DB_OUT;
+-	} else if (strcmp(pdata->dbdirection, "queryout") == 0) {
++	} else if (strcasecmp(pdata->dbdirection, "queryout") == 0) {
+ 		pdata->direction = DB_QUERYOUT;
+ 	} else {
+ 		fprintf(stderr, "Copy direction must be either 'in', 'out' or 'queryout'.\n");
+
+commit 4b60e1107600bfea76d5a29d75faa1088241f8f6
+Author: freddy77 <freddy77>
+Date:   Fri May 21 14:02:08 2010 +0000
+
+    update VMS build files (patch from Craig A. Berry).
+
+diff --git a/ChangeLog b/ChangeLog
+index 8af38c7..b0cffc4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri May 21 16:01:47 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* vms/Makefile.am vms/descrip_mms.template vms/edit.c:
++	* vms/getpass.c:
++	- update VMS build files (patch from Craig A. Berry).
++
+ Fri May 21 15:53:53 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/freebcp.c:
+ 	- freebcp's direction doesn't need to be case sensitive (from Craig
+@@ -2454,4 +2459,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3024 2010/05/21 13:54:27 freddy77 Exp $
++$Id: ChangeLog,v 1.3025 2010/05/21 14:02:08 freddy77 Exp $
+diff --git a/vms/Makefile.am b/vms/Makefile.am
+index fb78fcd..8565315 100644
+--- a/vms/Makefile.am
++++ b/vms/Makefile.am
+@@ -1,4 +1,4 @@
+ EXTRA_DIST = config_h.vms configure.com descrip_mms.template \
+-	getpass.c libodbc.opt odbc_driver_axp.opt README.vms
++	edit.c getpass.c libodbc.opt odbc_driver_axp.opt README.vms
+ 
+ clean:
+diff --git a/vms/descrip_mms.template b/vms/descrip_mms.template
+index 0799528..eb5b760 100644
+--- a/vms/descrip_mms.template
++++ b/vms/descrip_mms.template
+@@ -16,7 +16,7 @@
+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ # Boston, MA 02111-1307, USA.
+ # 
+-# $Id: descrip_mms.template,v 1.14 2009/04/09 01:40:25 jklowden Exp $
++# $Id: descrip_mms.template,v 1.15 2010/05/21 14:02:08 freddy77 Exp $
+ 
+ # OpenVMS description file for FreeTDS
+ 
+@@ -187,6 +187,9 @@ $(TDSODBCOBJS) : $(CONFIGS)
+ 	@ write sysconfh "#define FREETDS_SYSCONFDIR ""/FREETDS_ROOT"""
+ 	@ close sysconfh
+ 
++[.include]tds_sysdep_public.h_in :
++	@ IF F$SEARCH("$(MMS$TARGET)") .EQS. "" THEN COPY [.include]tds_sysdep_public^.h.in $(MMS$TARGET)
++
+ [.include]tds_sysdep_public.h : [.include]tds_sysdep_public.h_in
+ 	@ open/write vmsconfigtmp vmsconfigtmp.com
+ 	@ write vmsconfigtmp "$ define/user_mode/nolog SYS$OUTPUT _NLA0:"
+@@ -221,6 +224,15 @@ $(TDSODBCOBJS) : $(CONFIGS)
+ 	@ open/write readlineh $(MMS$TARGET)
+ 	@ write readlineh "char *readline(char *prompt);"
+ 	@ write readlineh "int rl_inhibit_completion;"
++	@ write readlineh "/* The following are needed for fisql. */"
++	@ write readlineh "FILE **rl_outstream_get_addr(void);"
++	@ write readlineh "#define rl_outstream (*rl_outstream_get_addr())"
++	@ write readlineh "FILE **rl_instream_get_addr(void);"
++	@ write readlineh "#define rl_instream (*rl_instream_get_addr())"
++	@ write readlineh "static const char *rl_readline_name = NULL;"
++	@ write readlineh "#define rl_bind_key(c,f)      do {} while(0)"
++	@ write readlineh "#define rl_reset_line_state() do {} while(0)"
++	@ write readlineh "#define rl_on_new_line()      do {} while(0)"
+ 	@ close readlineh 
+ 
+ [.include]history.h :
+@@ -278,7 +290,7 @@ $(TDSODBCSHR) : []libtdsodbc$(OLB)
+ 
+ # Build the utility programs and the pool server
+ 
+-apps : freebcp$(E) tsql$(E) bsqldb$(E) defncopy$(E) tdspool$(E)
++apps : freebcp$(E) tsql$(E) bsqldb$(E) defncopy$(E) tdspool$(E) fisql$(E)
+ 	@ continue
+ 
+ freebcp$(E) : [.src.apps]freebcp$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+@@ -306,6 +318,19 @@ defncopy$(E) : [.src.apps]defncopy$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+ tdspool$(E) : $(TDSPOOLOBJS) []libtdssrv$(OLB) []libtds$(OLB)
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(TDSPOOLOBJS), []libtdssrv$(OLB)/library, []libtds$(OLB)/library
+ 
++
++fisql$(E) : [.src.apps.fisql]fisql$(OBJ) [.src.apps.fisql]interrupt$(OBJ) [.src.apps.fisql]handlers$(OBJ) [.vms]edit$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
++
++[.src.apps.fisql]fisql$(OBJ) : [.src.apps.fisql]fisql.c
++	@ define/nolog/user_mode readline [.include]
++	$(CC) $(CFLAGS)/INCLUDE=($(CINCLUDE)) $(MMS$SOURCE)
++
++[.src.apps.fisql]interrupt$(OBJ) : [.src.apps.fisql]interrupt.c
++
++[.src.apps.fisql]handlers$(OBJ) : [.src.apps.fisql]handlers.c
++
++
+ # Run the test suite
+ 
+ check : buildchecks PWD libtdscheck ctlibcheck dblibcheck $(tdsodbccheck)
+diff --git a/vms/edit.c b/vms/edit.c
+new file mode 100644
+index 0000000..16e9812
+--- /dev/null
++++ b/vms/edit.c
+@@ -0,0 +1,73 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++ */
++
++/*      $Id: edit.c,v */
++
++#include <namdef.h>
++#include <descrip.h>
++#include <stsdef.h>
++#include <tpu$routines.h>
++#include <string.h>
++#include <unixlib.h>
++
++#if defined(NAML$C_MAXRSS) && !defined(__VAX)
++#  define VMS_MAXRSS (NAML$C_MAXRSS+1)
++#else
++#  define VMS_MAXRSS (NAM$C_MAXRSS+1)
++#endif
++
++char vms_fnm[VMS_MAXRSS];
++static int get_vms_name(char *, int);
++
++int
++edit(const char *editor, const char *arg)
++{
++    $DESCRIPTOR(fnm_dsc, "");
++    int status;
++
++    decc$to_vms(arg, get_vms_name, 0, 0);
++
++    fnm_dsc.dsc$a_pointer = vms_fnm;
++    fnm_dsc.dsc$w_length = strlen(vms_fnm);
++
++    if (fnm_dsc.dsc$a_pointer == NULL
++        || fnm_dsc.dsc$w_length == 0)
++        return -1;
++
++    status = TPU$EDIT(&fnm_dsc, &fnm_dsc);
++
++    if ($VMS_STATUS_SUCCESS(status))
++        return 0;
++    else
++        return -1;
++}
++
++static int
++get_vms_name(char *name, int type)
++{
++    strncpy(vms_fnm, name, VMS_MAXRSS);
++    return 1;
++}
++
++int
++reset_term()
++{
++        return 0;
++}
++
+diff --git a/vms/getpass.c b/vms/getpass.c
+index 8876eef..cd7c4a3 100644
+--- a/vms/getpass.c
++++ b/vms/getpass.c
+@@ -1,5 +1,5 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 2003  Craig A. Berry	craigberry@mac.com	23-JAN-2003
++ * Copyright (C) 2003, 2010  Craig A. Berry	craigberry@mac.com
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -42,10 +42,13 @@
+ #include <strings.h>
+ 
+ #include <replacements/readpassphrase.h>
++#include "readline.h"
+ 
+-static char software_version[] = "$Id: getpass.c,v 1.5 2005/12/29 10:24:34 freddy77 Exp $";
++static FILE *tds_rl_instream = NULL;
++static FILE *tds_rl_outstream = NULL;
++
++static char software_version[] = "$Id: getpass.c,v 1.6 2010/05/21 14:02:08 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+-static char passbuff[128];
+ 
+ /* 
+  * A collection of assorted UNIXy input functions for VMS.  The core
+@@ -128,14 +131,16 @@ readpassphrase(const char *prompt, char *pbuf, size_t buflen, int flags)
+ 	prompt_dsc.dsc$a_pointer = myprompt;
+ 	prompt_dsc.dsc$w_length = strlen(myprompt);
+ 
+-	/* Disable Ctrl-T and Ctrl-Y */
+-	ctrl_mask = LIB$M_CLI_CTRLT | LIB$M_CLI_CTRLY;
+-	status = LIB$DISABLE_CTRL(&ctrl_mask, &saved_ctrl_mask);
+-	if (!$VMS_STATUS_SUCCESS(status)) {
+-		errno = EVMSERR;
+-		vaxc$errno = status;
+-		free(myprompt);
+-		return NULL;
++	if (!(flags & RPP_ECHO_ON) && (ttdevclass == DC$_TERM)) {
++		/* Disable Ctrl-T and Ctrl-Y */
++		ctrl_mask = LIB$M_CLI_CTRLT | LIB$M_CLI_CTRLY;
++		status = LIB$DISABLE_CTRL(&ctrl_mask, &saved_ctrl_mask);
++		if (!$VMS_STATUS_SUCCESS(status)) {
++			errno = EVMSERR;
++			vaxc$errno = status;
++			free(myprompt);
++			return NULL;
++		}
+ 	}
+ 
+ 	/* 
+@@ -161,7 +166,7 @@ readpassphrase(const char *prompt, char *pbuf, size_t buflen, int flags)
+ 		status = SYS$ASSIGN(&ttdsc, &ttchan, 0, 0, 0);
+ 		if ($VMS_STATUS_SUCCESS(status)) {
+ 
+-			unsigned long qio_func = IO$_READPROMPT | IO$M_NOECHO;
++			unsigned long qio_func = IO$_READPROMPT | IO$M_NOECHO | IO$M_PURGE;
+ 
+ 			if (!(flags & RPP_TIMEOUT_OFF))
+ 				qio_func |= IO$M_TIMED;
+@@ -239,15 +244,17 @@ readpassphrase(const char *prompt, char *pbuf, size_t buflen, int flags)
+ 
+ 	free(myprompt);
+ 
+-	/* 
+-	 * Reenable previous control processing.
+-	 */
+-	status = LIB$ENABLE_CTRL(&saved_ctrl_mask);
++	if (!(flags & RPP_ECHO_ON) && (ttdevclass == DC$_TERM)) {
++		/*
++		 * Reenable previous control processing.
++		 */
++		status = LIB$ENABLE_CTRL(&saved_ctrl_mask);
+ 
+-	if (!$VMS_STATUS_SUCCESS(status)) {
+-		errno = EVMSERR;
+-		vaxc$errno = status;
+-		return NULL;
++		if (!$VMS_STATUS_SUCCESS(status)) {
++			errno = EVMSERR;
++			vaxc$errno = status;
++			return NULL;
++		}
+ 	}
+ 
+ 	return retval;
+@@ -271,10 +278,12 @@ getpass(const char *prompt)
+ char *
+ readline(char *prompt)
+ {
+-
+-	char *buf = NULL;
+-	char *s = readpassphrase((const char *) prompt, passbuf, sizeof(passbuf),
+-				 RPP_ECHO_ON | RPP_TIMEOUT_OFF);
++	char *buf = NULL, *s = NULL, *p = NULL;
++	if (tds_rl_instream == NULL)
++		s = readpassphrase((const char *) prompt, passbuf, sizeof(passbuf),
++					 RPP_ECHO_ON | RPP_TIMEOUT_OFF);
++	else
++		s = fgets(passbuf, sizeof(passbuf), tds_rl_instream);
+ 
+ 	if (s != NULL) {
+ 		buf = (char *) malloc(strlen(s) + 1);
+@@ -288,3 +297,17 @@ void
+ add_history(const char *s)
+ {
+ }
++
++
++FILE **
++rl_instream_get_addr(void)
++{
++	return &tds_rl_instream;
++}
++
++FILE **
++rl_outstream_get_addr(void)
++{
++	return &tds_rl_outstream;
++}
++
+
+commit 01a7bbf7959888d6b31bcbf764f48f509b1f2e31
+Author: freddy77 <freddy77>
+Date:   Fri May 21 14:10:31 2010 +0000
+
+    add -i and -o options to freebcp (patch from Craig A. Berry)
+
+diff --git a/ChangeLog b/ChangeLog
+index b0cffc4..e725282 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri May 21 16:10:04 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/freebcp.c src/apps/freebcp.h:
++	- add -i and -o options to freebcp (patch from Craig A. Berry)
++
+ Fri May 21 16:01:47 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* vms/Makefile.am vms/descrip_mms.template vms/edit.c:
+ 	* vms/getpass.c:
+@@ -2459,4 +2463,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3025 2010/05/21 14:02:08 freddy77 Exp $
++$Id: ChangeLog,v 1.3026 2010/05/21 14:10:31 freddy77 Exp $
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index c5f49db..79bd0bd 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -24,6 +24,10 @@
+ #include <stdio.h>
+ #include <ctype.h>
+ 
++#if HAVE_ERRNO_H
++#include <errno.h>
++#endif /* HAVE_ERRNO_H */
++
+ #if HAVE_STDLIB_H
+ #include <stdlib.h>
+ #endif /* HAVE_STDLIB_H */
+@@ -46,7 +50,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.52 2010/05/21 13:54:28 freddy77 Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.53 2010/05/21 14:10:31 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -192,7 +196,7 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 	 * Get the rest of the arguments 
+ 	 */
+ 	optind = 4; /* start processing options after table, direction, & filename */
+-	while ((ch = getopt(argc, argv, "m:f:e:F:L:b:t:r:U:P:I:S:h:T:A:O:0:C:ncEdvV")) != -1) {
++	while ((ch = getopt(argc, argv, "m:f:e:F:L:b:t:r:U:P:i:I:S:h:T:A:o:O:0:C:ncEdvV")) != -1) {
+ 		switch (ch) {
+ 		case 'v':
+ 		case 'V':
+@@ -263,6 +267,10 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 				pdata->pass = strdup(optarg);
+ 			}
+ 			break;
++		case 'i':
++			free(pdata->inputfile);
++			pdata->inputfile = strdup(optarg);
++			break;
+ 		case 'I':
+ 			pdata->Iflag++;
+ 			free(pdata->interfacesfile);
+@@ -275,6 +283,10 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 		case 'h':
+ 			pdata->hint = strdup(optarg);
+ 			break;
++		case 'o':
++			free(pdata->outputfile);
++			pdata->outputfile = strdup(optarg);
++			break;
+ 		case 'O':
+ 		case '0':
+ 			pdata->options = strdup(optarg);
+@@ -326,6 +338,27 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 		}
+ 	}
+ 
++	/*
++	 * Override stdin and/or stdout if requested.
++	 */
++
++	/* FIXME -- Since we don't implement prompting for field data types when neither -c nor -n
++	 * is specified, redirecting stdin doesn't do much yet.
++	 */
++	if (pdata->inputfile) {
++		if (freopen(pdata->inputfile, "rb", stdout) == NULL) {
++			fprintf(stderr, "%s: unable to open %s: %s\n", "freebcp", pdata->inputfile, strerror(errno));
++			exit(1);
++		}
++	}
++
++	if (pdata->outputfile) {
++		if (freopen(pdata->outputfile, "wb", stdout) == NULL) {
++			fprintf(stderr, "%s: unable to open %s: %s\n", "freebcp", pdata->outputfile, strerror(errno));
++			exit(1);
++		}
++	}
++
+ 	return (TRUE);
+ 
+ }
+@@ -700,6 +733,7 @@ pusage(void)
+ 	fprintf(stderr, "        [-U username] [-P password] [-I interfaces_file] [-S server]\n");
+ 	fprintf(stderr, "        [-v] [-d] [-h \"hint [,...]\" [-O \"set connection_option on|off, ...]\"\n");
+ 	fprintf(stderr, "        [-A packet size] [-T text or image size] [-E]\n");
++	fprintf(stderr, "        [-i input_file] [-o output_file]\n");
+ 	fprintf(stderr, "        \n");
+ 	fprintf(stderr, "example: freebcp testdb.dbo.inserttest in inserttest.txt -S mssql -U guest -P password -c\n");
+ }
+diff --git a/src/apps/freebcp.h b/src/apps/freebcp.h
+index 53d1e26..f5c9ac8 100644
+--- a/src/apps/freebcp.h
++++ b/src/apps/freebcp.h
+@@ -1,4 +1,4 @@
+-static char rcsid_freebcp_h[] = "$Id: freebcp.h,v 1.14 2009/07/23 18:22:00 freddy77 Exp $";
++static char rcsid_freebcp_h[] = "$Id: freebcp.h,v 1.15 2010/05/21 14:10:31 freddy77 Exp $";
+ static void *no_unused_freebcp_h_warn[] = { rcsid_freebcp_h, no_unused_freebcp_h_warn };
+ 
+ enum states
+@@ -70,5 +70,7 @@ typedef struct pd
+ 	int Tflag;
+ 	int Aflag;
+ 	int Eflag;
++	char *inputfile;
++	char *outputfile;
+ }
+ BCPPARAMDATA;
+
+commit b1a16c4ec9bb62c36ad1395feb9211d3a6a2b96a
+Author: freddy77 <freddy77>
+Date:   Fri May 21 15:18:48 2010 +0000
+
+    handle column size for SYBDATETIMN data type (Craig A. Berry)
+
+diff --git a/ChangeLog b/ChangeLog
+index e725282..0ff0264 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri May 21 17:18:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqldb.c src/apps/fisql/fisql.c src/dblib/dblib.c:
++	- handle column size for SYBDATETIMN data type (Craig A. Berry)
++
+ Fri May 21 16:10:04 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/freebcp.c src/apps/freebcp.h:
+ 	- add -i and -o options to freebcp (patch from Craig A. Berry)
+@@ -2463,4 +2467,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3026 2010/05/21 14:10:31 freddy77 Exp $
++$Id: ChangeLog,v 1.3027 2010/05/21 15:18:48 freddy77 Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 5319757..883470b 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -49,7 +49,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.41 2010/04/08 09:02:55 freddy77 Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.42 2010/05/21 15:18:49 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -688,8 +688,8 @@ get_printable_size(int type, int size)	/* adapted from src/dblib/dblib.c */
+ 	case SYBMONEY4:
+ 		return 12;	/* FIX ME */
+ 	case SYBDATETIME:
+-		return 26;	/* FIX ME */
+ 	case SYBDATETIME4:
++	case SYBDATETIMN:
+ 		return 26;	/* FIX ME */
+ #if 0	/* not exported by sybdb.h */
+ 	case SYBBITN:
+diff --git a/src/apps/fisql/fisql.c b/src/apps/fisql/fisql.c
+index 2a09df3..9e4b512 100644
+--- a/src/apps/fisql/fisql.c
++++ b/src/apps/fisql/fisql.c
+@@ -175,8 +175,8 @@ get_printable_size(int type, int size)
+ 	case SYBMONEY4:
+ 		return 12;	/* FIX ME */
+ 	case SYBDATETIME:
+-		return 26;	/* FIX ME */
+ 	case SYBDATETIME4:
++	case SYBDATETIMN:
+ 		return 26;	/* FIX ME */
+ #if 0				/* seems not to be exported to sybdb.h */
+ 	case SYBBITN:
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 00f6e44..00e2145 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.363 2010/02/07 21:56:09 jklowden Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.364 2010/05/21 15:18:49 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -3556,6 +3556,7 @@ _get_printable_size(TDSCOLUMN * colinfo)
+ 		return 12;
+ 	case SYBDATETIME:
+ 	case SYBDATETIME4:
++	case SYBDATETIMN:
+ 		return 26;
+ 	case SYBUNIQUE:
+ 		return 36;
+
+commit 41e691310de44be47be05d02d108d03376da2206
+Author: freddy77 <freddy77>
+Date:   Fri Jun 18 19:33:14 2010 +0000
+
+    Move prepare code to odbc_prepare
+
+diff --git a/ChangeLog b/ChangeLog
+index 0ff0264..d2d0664 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jun 18 21:33:02 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/odbc_util.c:
++	- Move prepare code to odbc_prepare
++
+ Fri May 21 17:18:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqldb.c src/apps/fisql/fisql.c src/dblib/dblib.c:
+ 	- handle column size for SYBDATETIMN data type (Craig A. Berry)
+@@ -2467,4 +2471,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3027 2010/05/21 15:18:48 freddy77 Exp $
++$Id: ChangeLog,v 1.3028 2010/06/18 19:33:14 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 466847b..731ea22 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.531 2010/03/22 14:42:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.532 2010/06/18 19:33:15 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -88,6 +88,7 @@ static void odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name);
+ static SQLRETURN odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...);
+ static SQLRETURN odbc_free_dynamic(TDS_STMT * stmt);
+ static SQLRETURN odbc_free_cursor(TDS_STMT * stmt);
++static SQLRETURN odbc_prepare(TDS_STMT *stmt);
+ static SQLSMALLINT odbc_swap_datetime_sql_type(SQLSMALLINT sql_type);
+ static int odbc_process_tokens(TDS_STMT * stmt, unsigned flag);
+ static int odbc_lock_statement(TDS_STMT* stmt);
+@@ -405,6 +406,70 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 	ODBC_RETURN(dbc, SQL_SUCCESS);
+ }
+ 
++static SQLRETURN
++odbc_prepare(TDS_STMT *stmt)
++{
++	TDSSOCKET *tds = stmt->dbc->tds_socket;
++	int in_row = 0;
++
++	if (tds_submit_prepare(tds, stmt->prepared_query, NULL, &stmt->dyn, stmt->params) == TDS_FAIL)
++		ODBC_RETURN(stmt, SQL_ERROR);
++
++	/* try to go to the next recordset */
++	/* TODO merge with similar code */
++	desc_free_records(stmt->ird);
++	stmt->row_status = PRE_NORMAL_ROW;
++	for (;;) {
++		TDS_INT result_type;
++		int done_flags;
++
++		switch (tds_process_tokens(tds, &result_type, &done_flags, TDS_RETURN_ROWFMT|TDS_RETURN_DONE)) {
++		case TDS_SUCCEED:
++			switch (result_type) {
++			case TDS_DONE_RESULT:
++			case TDS_DONEPROC_RESULT:
++			case TDS_DONEINPROC_RESULT:
++				stmt->row_count = tds->rows_affected;
++				if (done_flags & TDS_DONE_ERROR && !stmt->dyn->emulated)
++					stmt->errs.lastrc = SQL_ERROR;
++				/* FIXME this row is used only as a flag for update binding, should be cleared if binding/result changed */
++				stmt->row = 0;
++				break;
++
++			case TDS_ROWFMT_RESULT:
++				/* store first row informations */
++				if (!in_row)
++					odbc_populate_ird(stmt);
++				stmt->row = 0;
++				stmt->row_count = TDS_NO_COUNT;
++				stmt->row_status = PRE_NORMAL_ROW;
++				in_row = 1;
++				break;
++			}
++			continue;
++		case TDS_NO_MORE_RESULTS:
++			break;
++		case TDS_CANCELLED:
++			odbc_errs_add(&stmt->errs, "HY008", NULL);
++		default:
++			stmt->errs.lastrc = SQL_ERROR;
++			break;
++		}
++
++		if (stmt->dbc->current_statement == stmt)
++			stmt->dbc->current_statement = NULL;
++		if (stmt->errs.lastrc == SQL_ERROR && !stmt->dyn->emulated) {
++			TDSDYNAMIC *dyn = stmt->dyn;
++			stmt->dyn = NULL;
++			tds_free_dynamic(tds, dyn);
++		}
++		ODBC_RETURN_(stmt);
++	}
++
++	stmt->need_reprepare = 0;
++	ODBC_RETURN_(stmt);
++}
++
+ SQLRETURN ODBC_API
+ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR FAR * szConnStrOut,
+ 		 SQLSMALLINT cbConnStrOutMax, SQLSMALLINT FAR * pcbConnStrOut, SQLUSMALLINT fDriverCompletion)
+@@ -4300,14 +4365,13 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 	/* TODO support getting info for RPC */
+ 	if (!stmt->prepared_query_is_rpc
+ 		 && (stmt->attr.cursor_type == SQL_CURSOR_FORWARD_ONLY && stmt->attr.concurrency == SQL_CONCUR_READ_ONLY)) {
+-		TDSDYNAMIC *dyn;
+ 
+-		TDS_INT result_type;
+-		int in_row = 0;
+-		int done_flags;
+-		TDSPARAMINFO *params = NULL;
+ 		TDSSOCKET *tds = stmt->dbc->tds_socket;
++		TDSPARAMINFO *params = NULL;
+ 
++		tds_free_param_results(stmt->params);
++		stmt->params = NULL;
++		stmt->param_num = 0;
+ 		stmt->need_reprepare = 0;
+ 		/*
+ 		 * using TDS7+ we need parameters to prepare a query so try
+@@ -4341,59 +4405,7 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 		tdsdump_log(TDS_DBG_INFO1, "Creating prepared statement\n");
+ 		if (!odbc_lock_statement(stmt))
+ 			ODBC_RETURN_(stmt);
+-		if (tds_submit_prepare(tds, stmt->prepared_query, NULL, &stmt->dyn, params) == TDS_FAIL) {
+-			tds_free_param_results(params);
+-			ODBC_RETURN(stmt, SQL_ERROR);
+-		}
+-
+-		/* try to go to the next recordset */
+-		/* TODO merge with similar code */
+-		desc_free_records(stmt->ird);
+-		stmt->row_status = PRE_NORMAL_ROW;
+-		for (;;) {
+-			switch (tds_process_tokens(tds, &result_type, &done_flags, TDS_RETURN_ROWFMT|TDS_RETURN_DONE)) {
+-			case TDS_SUCCEED:
+-				switch (result_type) {
+-				case TDS_DONE_RESULT:
+-				case TDS_DONEPROC_RESULT:
+-				case TDS_DONEINPROC_RESULT:
+-					stmt->row_count = tds->rows_affected;
+-					if (done_flags & TDS_DONE_ERROR && !stmt->dyn->emulated)
+-						stmt->errs.lastrc = SQL_ERROR;
+-					/* FIXME this row is used only as a flag for update binding, should be cleared if binding/result changed */
+-					stmt->row = 0;
+-					break;
+-
+-				case TDS_ROWFMT_RESULT:
+-					/* store first row informations */
+-					if (!in_row)
+-						odbc_populate_ird(stmt);
+-					stmt->row = 0;
+-					stmt->row_count = TDS_NO_COUNT;
+-					stmt->row_status = PRE_NORMAL_ROW;
+-					in_row = 1;
+-					break;
+-				}
+-				continue;
+-			case TDS_NO_MORE_RESULTS:
+-				break;
+-			case TDS_CANCELLED:
+-				odbc_errs_add(&stmt->errs, "HY008", NULL);
+-			default:
+-				stmt->errs.lastrc = SQL_ERROR;
+-				break;
+-			}
+-
+-			if (stmt->dbc->current_statement == stmt)
+-				stmt->dbc->current_statement = NULL;
+-			if (stmt->errs.lastrc == SQL_ERROR && !stmt->dyn->emulated) {
+-				dyn = stmt->dyn;
+-				stmt->dyn = NULL;
+-				tds_free_dynamic(tds, dyn);
+-			}
+-			/* TODO ?? tds_free_param_results(params); */
+-			ODBC_RETURN_(stmt);
+-		}
++		return odbc_prepare(stmt);
+ 	}
+ 
+ 	ODBC_RETURN_(stmt);
+@@ -5891,6 +5903,7 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 			break;
+ 		case TDS_CANCELLED:
+ 			odbc_errs_add(&stmt->errs, "HY008", NULL);
++			res = SQL_ERROR;
+ 			break;
+ 		}
+ 		if (!tds->current_results)
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 3ef090d..6cc2e10 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -39,7 +39,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.111 2010/01/23 20:42:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.112 2010/06/18 19:33:15 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -74,6 +74,7 @@ odbc_set_stmt(TDS_STMT * stmt, char **dest, const char *sql, int sql_len)
+ 	stmt->prepared_pos = NULL;
+ 	stmt->curr_param_row = 0;
+ 	stmt->num_param_rows = 1;
++	stmt->need_reprepare = 0;
+ 
+ 	if (stmt->prepared_query)
+ 		TDS_ZERO_FREE(stmt->prepared_query);
+
+commit b3859c2035dbd4abe03ce8221aec0c18de0ff13d
+Author: freddy77 <freddy77>
+Date:   Fri Jun 18 19:48:56 2010 +0000
+
+    defer prepare
+
+diff --git a/ChangeLog b/ChangeLog
+index d2d0664..5498940 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jun 18 21:48:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: defer prepare
++
+ Fri Jun 18 21:33:02 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	- Move prepare code to odbc_prepare
+@@ -2471,4 +2474,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3028 2010/06/18 19:33:14 freddy77 Exp $
++$Id: ChangeLog,v 1.3029 2010/06/18 19:48:56 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 731ea22..643a571 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.532 2010/06/18 19:33:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.533 2010/06/18 19:48:56 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -88,6 +88,9 @@ static void odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name);
+ static SQLRETURN odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...);
+ static SQLRETURN odbc_free_dynamic(TDS_STMT * stmt);
+ static SQLRETURN odbc_free_cursor(TDS_STMT * stmt);
++#ifdef ENABLE_DEVELOPING
++static SQLRETURN odbc_update_ird(TDS_STMT *stmt, TDS_ERRS *errs);
++#endif
+ static SQLRETURN odbc_prepare(TDS_STMT *stmt);
+ static SQLSMALLINT odbc_swap_datetime_sql_type(SQLSMALLINT sql_type);
+ static int odbc_process_tokens(TDS_STMT * stmt, unsigned flag);
+@@ -406,6 +409,39 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 	ODBC_RETURN(dbc, SQL_SUCCESS);
+ }
+ 
++#ifdef ENABLE_DEVELOPING
++static SQLRETURN
++odbc_update_ird(TDS_STMT *stmt, TDS_ERRS *errs)
++{
++	TDSPARAMINFO *save_params = stmt->params;
++	int save_param_num = stmt->param_num;
++	SQLRETURN res;
++
++	if (!stmt->need_reprepare || stmt->prepared_query_is_rpc)
++		return SQL_SUCCESS;
++
++	stmt->params = NULL;
++	stmt->param_num = 0;
++	/* FIXME error */
++	res = start_parse_prepared_query(stmt, 0);
++	if (res != SQL_SUCCESS) {
++		stmt->params = save_params;
++		stmt->param_num = save_param_num;
++		return SQL_ERROR;
++	}
++
++	/* FIXME where error are put ?? on stmt... */
++	if (!odbc_lock_statement(stmt)) {
++		stmt->params = save_params;
++		stmt->param_num = save_param_num;
++		ODBC_RETURN_(stmt);
++	}
++	tds_free_param_results(save_params);
++
++	return odbc_prepare(stmt);
++}
++#endif
++
+ static SQLRETURN
+ odbc_prepare(TDS_STMT *stmt)
+ {
+@@ -1262,6 +1298,17 @@ SQLGetEnvAttr(SQLHENV henv, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER B
+ 
+ #endif
+ 
++#ifdef ENABLE_DEVELOPING
++#define IRD_UPDATE(desc, errs, exit) \
++	do { \
++		if (desc->type == DESC_IRD && ((TDS_STMT*)desc->parent)->need_reprepare && \
++		    odbc_update_ird((TDS_STMT*)desc->parent, errs) != SQL_SUCCESS) \
++			exit; \
++	} while(0)
++#else
++#define IRD_UPDATE(desc, errs, exit) do { } while(0)
++#endif
++
+ static SQLRETURN
+ _SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType,
+ 		  SQLULEN cbColDef, SQLSMALLINT ibScale, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue)
+@@ -1854,6 +1901,7 @@ SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLCHAR FAR * szColName, SQLSM
+ 			hstmt, icol, szColName, cbColNameMax, pcbColName, pfSqlType, pcbColDef, pibScale, pfNullable);
+ 
+ 	ird = stmt->ird;
++	IRD_UPDATE(ird, &stmt->errs, ODBC_RETURN(stmt, SQL_ERROR));
+ 
+ 	if (icol <= 0 || icol > ird->header.sql_desc_count) {
+ 		odbc_errs_add(&stmt->errs, "07009", "Column out of range");
+@@ -1932,6 +1980,7 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ #define IOUT(type, src) *pfDesc = src
+ #endif
+ 
++	IRD_UPDATE(ird, &stmt->errs, ODBC_RETURN(stmt, SQL_ERROR));
+ 
+ 	/* dont check column index for these */
+ 	switch (fDescType) {
+@@ -2338,6 +2387,7 @@ SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALL
+ 		ODBC_RETURN(desc, SQL_ERROR);
+ 	}
+ 
++	IRD_UPDATE(desc, &desc->errs, ODBC_RETURN(desc, SQL_ERROR));
+ 	if (RecordNumber > desc->header.sql_desc_count)
+ 		ODBC_RETURN(desc, SQL_NO_DATA);
+ 
+@@ -2414,6 +2464,7 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 		ODBC_RETURN_(desc);
+ 		break;
+ 	case SQL_DESC_COUNT:
++		IRD_UPDATE(desc, &desc->errs, ODBC_RETURN(desc, SQL_ERROR));
+ 		IOUT(SQLSMALLINT, desc->header.sql_desc_count);
+ 		ODBC_RETURN_(desc);
+ 		break;
+@@ -2423,6 +2474,7 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 		break;
+ 	}
+ 
++	IRD_UPDATE(desc, &desc->errs, ODBC_RETURN(desc, SQL_ERROR));
+ 	if (!desc->header.sql_desc_count) {
+ 		odbc_errs_add(&desc->errs, "07005", NULL);
+ 		ODBC_RETURN(desc, SQL_ERROR);
+@@ -2804,6 +2856,7 @@ SQLCopyDesc(SQLHDESC hdesc, SQLHDESC htarget)
+ 		odbc_errs_add(&target->errs, "HY016", NULL);
+ 		ODBC_RETURN(target, SQL_ERROR);
+ 	}
++	IRD_UPDATE(desc, &desc->errs, ODBC_RETURN(target, SQL_ERROR));
+ 
+ 	ODBC_RETURN(target, desc_copy(target, desc));
+ }
+@@ -4327,6 +4380,7 @@ SQLNumResultCols(SQLHSTMT hstmt, SQLSMALLINT FAR * pccol)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ #endif
++	IRD_UPDATE(stmt->ird, &stmt->errs, ODBC_RETURN(stmt, SQL_ERROR));
+ 	*pccol = stmt->ird->header.sql_desc_count;
+ 	ODBC_RETURN_(stmt);
+ }
+@@ -4367,7 +4421,9 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 		 && (stmt->attr.cursor_type == SQL_CURSOR_FORWARD_ONLY && stmt->attr.concurrency == SQL_CONCUR_READ_ONLY)) {
+ 
+ 		TDSSOCKET *tds = stmt->dbc->tds_socket;
++#ifndef ENABLE_DEVELOPING
+ 		TDSPARAMINFO *params = NULL;
++#endif
+ 
+ 		tds_free_param_results(stmt->params);
+ 		stmt->params = NULL;
+@@ -4380,6 +4436,10 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 		 * prepare sepatarely so this is not an issue
+ 		 */
+ 		if (IS_TDS7_PLUS(tds)) {
++#ifdef ENABLE_DEVELOPING
++			stmt->need_reprepare = 1;
++			ODBC_RETURN_(stmt);
++#else
+ 			SQLRETURN res;
+ 
+ 			/* use current parameter informations if availables */
+@@ -4400,6 +4460,7 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 			 * compute row for execute
+ 			 */
+ 			stmt->param_num = 0;
++#endif
+ 		}
+ 
+ 		tdsdump_log(TDS_DBG_INFO1, "Creating prepared statement\n");
+
+commit 20f2dd27ae3bca6bc8891a480a9335f2397d2cf3
+Author: freddy77 <freddy77>
+Date:   Sat Jun 19 07:47:52 2010 +0000
+
+    add initial README file for windows
+
+diff --git a/ChangeLog b/ChangeLog
+index 5498940..e82a8c8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 19 09:47:38 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* README.Windows: add initial README file for windows
++
+ Fri Jun 18 21:48:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: defer prepare
+ 
+@@ -2474,4 +2477,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3029 2010/06/18 19:48:56 freddy77 Exp $
++$Id: ChangeLog,v 1.3030 2010/06/19 07:47:52 freddy77 Exp $
+diff --git a/README.Windows b/README.Windows
+new file mode 100644
+index 0000000..63195dc
+--- /dev/null
++++ b/README.Windows
+@@ -0,0 +1,32 @@
++README for FreeTDS
++
++This readme provide specific informations for Windows environment.
++Please read README file for generic intro.
++
++FROM SCRATCH
++------------
++
++FreeTDS compile with ANSI strings.
++
++All libraries have them directory where you can include every C file you find
++inside (not recursively)
++- replacements
++- tds here there is an exception, do not include ptw32_MCS_lock.c file
++- dblib
++- ctlib
++- odbc
++All libraries depends in replacements one (except replacements obviously),
++dblib, ctlib and odbc depends on tds.
++You should add ws2_32.lib do dependencies.
++
++replacements and TDS library are designed to be static libraries.
++
++You have to define these macros
++- _FREETDS_LIBRARY_SOURCE
++- HAVE_CONFIG_H
++- UNIXODBC (for ODBC stuff)
++
++Also you need to include win32 and include directory (in this order!)
++
++These instructions should suffice in order to set up any project file you need.
++
+
+commit 2818e1333a2dddbdc18346d766df091e42eb69bb
+Author: freddy77 <freddy77>
+Date:   Sat Jun 19 07:53:21 2010 +0000
+
+    fix possible core
+
+diff --git a/ChangeLog b/ChangeLog
+index e82a8c8..18ceb91 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 19 09:53:14 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/pool/member.c src/tds/unittests/common.c: fix possible core
++
+ Sat Jun 19 09:47:38 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* README.Windows: add initial README file for windows
+ 
+@@ -2477,4 +2480,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3030 2010/06/19 07:47:52 freddy77 Exp $
++$Id: ChangeLog,v 1.3031 2010/06/19 07:53:21 freddy77 Exp $
+diff --git a/src/pool/member.c b/src/pool/member.c
+index 7acf8bd..156ed44 100644
+--- a/src/pool/member.c
++++ b/src/pool/member.c
+@@ -59,7 +59,7 @@
+ #define MAXHOSTNAMELEN 256
+ #endif /* MAXHOSTNAMELEN */
+ 
+-TDS_RCSID(var, "$Id: member.c,v 1.45 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: member.c,v 1.46 2010/06/19 07:53:21 freddy77 Exp $");
+ 
+ static int pool_packet_read(TDS_POOL_MEMBER * pmbr);
+ static TDSSOCKET *pool_mbr_login(TDS_POOL * pool);
+@@ -95,7 +95,7 @@ pool_mbr_login(TDS_POOL * pool)
+ 	tds_set_packet(login, 512);
+ 	context = tds_alloc_context(NULL);
+ 	tds = tds_alloc_socket(context, 512);
+-	connection = tds_read_config_info(NULL, login, context->locale);
++	connection = tds_read_config_info(tds, login, context->locale);
+ 	if (!connection || tds_connect_and_login(tds, connection) != TDS_SUCCEED) {
+ 		tds_free_socket(tds);
+ 		tds_free_connection(connection);
+diff --git a/src/tds/unittests/common.c b/src/tds/unittests/common.c
+index f037b2a..bc37d11 100644
+--- a/src/tds/unittests/common.c
++++ b/src/tds/unittests/common.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.29 2008/12/17 11:04:34 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.30 2010/06/19 07:53:21 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ char USER[512];
+@@ -96,7 +96,7 @@ try_tds_login(TDSLOGIN ** login, TDSSOCKET ** tds, const char *appname, int verb
+ 	test_context = tds_alloc_context(NULL);
+ 	*tds = tds_alloc_socket(test_context, 512);
+ 	tds_set_parent(*tds, NULL);
+-	connection = tds_read_config_info(NULL, *login, test_context->locale);
++	connection = tds_read_config_info(*tds, *login, test_context->locale);
+ 	if (!connection || tds_connect_and_login(*tds, connection) != TDS_SUCCEED) {
+ 		if (connection) {
+ 			tds_free_socket(*tds);
+
+commit 071e55e99cf8e5310ec5c0d7815560b33358a311
+Author: freddy77 <freddy77>
+Date:   Sat Jun 19 09:51:35 2010 +0000
+
+    enable defer by default, tests work correctly, use prepexec for performance
+
+diff --git a/ChangeLog b/ChangeLog
+index 18ceb91..e13f077 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sat Jun 19 11:51:23 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/odbc/odbc.c src/tds/query.c src/tds/token.c:
++	- enable defer by default, tests work correctly, use prepexec for
++	  performance
++
+ Sat Jun 19 09:53:14 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/pool/member.c src/tds/unittests/common.c: fix possible core
+ 
+@@ -2480,4 +2485,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3031 2010/06/19 07:53:21 freddy77 Exp $
++$Id: ChangeLog,v 1.3032 2010/06/19 09:51:35 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 930e60a..c148806 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.335 2010/04/10 14:29:36 freddy77 Exp $ */
++/* $Id: tds.h,v 1.336 2010/06/19 09:51:36 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1500,6 +1500,7 @@ int tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * p
+ int tds_submit_queryf(TDSSOCKET * tds, const char *queryf, ...);
+ int tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
+ int tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
++int tds8_submit_prepexec(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
+ int tds_submit_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn);
+ int tds_send_cancel(TDSSOCKET * tds);
+ const char *tds_next_placeholder(const char *start);
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 643a571..4a22069 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.533 2010/06/18 19:48:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.534 2010/06/19 09:51:36 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -88,9 +88,7 @@ static void odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name);
+ static SQLRETURN odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...);
+ static SQLRETURN odbc_free_dynamic(TDS_STMT * stmt);
+ static SQLRETURN odbc_free_cursor(TDS_STMT * stmt);
+-#ifdef ENABLE_DEVELOPING
+ static SQLRETURN odbc_update_ird(TDS_STMT *stmt, TDS_ERRS *errs);
+-#endif
+ static SQLRETURN odbc_prepare(TDS_STMT *stmt);
+ static SQLSMALLINT odbc_swap_datetime_sql_type(SQLSMALLINT sql_type);
+ static int odbc_process_tokens(TDS_STMT * stmt, unsigned flag);
+@@ -409,7 +407,6 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 	ODBC_RETURN(dbc, SQL_SUCCESS);
+ }
+ 
+-#ifdef ENABLE_DEVELOPING
+ static SQLRETURN
+ odbc_update_ird(TDS_STMT *stmt, TDS_ERRS *errs)
+ {
+@@ -440,7 +437,6 @@ odbc_update_ird(TDS_STMT *stmt, TDS_ERRS *errs)
+ 
+ 	return odbc_prepare(stmt);
+ }
+-#endif
+ 
+ static SQLRETURN
+ odbc_prepare(TDS_STMT *stmt)
+@@ -1298,16 +1294,12 @@ SQLGetEnvAttr(SQLHENV henv, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER B
+ 
+ #endif
+ 
+-#ifdef ENABLE_DEVELOPING
+ #define IRD_UPDATE(desc, errs, exit) \
+ 	do { \
+ 		if (desc->type == DESC_IRD && ((TDS_STMT*)desc->parent)->need_reprepare && \
+ 		    odbc_update_ird((TDS_STMT*)desc->parent, errs) != SQL_SUCCESS) \
+ 			exit; \
+ 	} while(0)
+-#else
+-#define IRD_UPDATE(desc, errs, exit) do { } while(0)
+-#endif
+ 
+ static SQLRETURN
+ _SQLBindParameter(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fParamType, SQLSMALLINT fCType, SQLSMALLINT fSqlType,
+@@ -3262,6 +3254,13 @@ _SQLExecute(TDS_STMT * stmt)
+ 			if (ret == TDS_SUCCEED)
+ 				ret = tds_multiple_done(tds, &multiple);
+ 		}
++	} else if (stmt->num_param_rows <= 1 && IS_TDS71_PLUS(tds) && (!stmt->dyn || stmt->need_reprepare)) {
++			if (stmt->dyn) {
++				if (odbc_free_dynamic(stmt) != SQL_SUCCESS)
++					ODBC_RETURN(stmt, SQL_ERROR);
++			}
++			stmt->need_reprepare = 0;
++			ret = tds8_submit_prepexec(tds, stmt->prepared_query, NULL, &stmt->dyn, stmt->params);
+ 	} else {
+ 		/* TODO cursor change way of calling */
+ 		/* SQLPrepare */
+@@ -4421,9 +4420,6 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 		 && (stmt->attr.cursor_type == SQL_CURSOR_FORWARD_ONLY && stmt->attr.concurrency == SQL_CONCUR_READ_ONLY)) {
+ 
+ 		TDSSOCKET *tds = stmt->dbc->tds_socket;
+-#ifndef ENABLE_DEVELOPING
+-		TDSPARAMINFO *params = NULL;
+-#endif
+ 
+ 		tds_free_param_results(stmt->params);
+ 		stmt->params = NULL;
+@@ -4436,31 +4432,8 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 		 * prepare sepatarely so this is not an issue
+ 		 */
+ 		if (IS_TDS7_PLUS(tds)) {
+-#ifdef ENABLE_DEVELOPING
+ 			stmt->need_reprepare = 1;
+ 			ODBC_RETURN_(stmt);
+-#else
+-			SQLRETURN res;
+-
+-			/* use current parameter informations if availables */
+-			res = start_parse_prepared_query(stmt, 0);
+-			if (res != SQL_SUCCESS) {
+-				/*
+-				 * not all parameters are bounded, prepare
+-				 * with dummy parameters however we need to
+-				 * prepare again later
+-				 * TODO prepare only getting information
+-				 */
+-				stmt->need_reprepare = 1;
+-			} else {
+-				params = stmt->params;
+-			}
+-			/*
+-			 * we can't reuse parsed parameters cause we didn't
+-			 * compute row for execute
+-			 */
+-			stmt->param_num = 0;
+-#endif
+ 		}
+ 
+ 		tdsdump_log(TDS_DBG_INFO1, "Creating prepared statement\n");
+diff --git a/src/tds/query.c b/src/tds/query.c
+index 4dd1d18..1114416 100644
+--- a/src/tds/query.c
++++ b/src/tds/query.c
+@@ -46,7 +46,7 @@
+ 
+ #include <assert.h>
+ 
+-TDS_RCSID(var, "$Id: query.c,v 1.243 2009/12/13 10:37:37 freddy77 Exp $");
++TDS_RCSID(var, "$Id: query.c,v 1.244 2010/06/19 09:51:36 freddy77 Exp $");
+ 
+ static void tds_put_params(TDSSOCKET * tds, TDSPARAMINFO * info, int flags);
+ static void tds7_put_query_params(TDSSOCKET * tds, const char *query, size_t query_len);
+@@ -1272,6 +1272,112 @@ tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params)
+ }
+ 
+ /**
++ * tds8_submit_prepexec() creates a temporary stored procedure in the server.
++ * \param tds     state information for the socket and the TDS protocol
++ * \param query   language query with given placeholders (?)
++ * \param id      string to identify the dynamic query. Pass NULL for automatic generation.
++ * \param dyn_out will receive allocated TDSDYNAMIC*. Any older allocated dynamic won't be freed, Can be NULL.
++ * \param params  parameters to use. It can be NULL even if parameters are present. Used only for TDS7+
++ * \return TDS_FAIL or TDS_SUCCEED
++ */
++int
++tds8_submit_prepexec(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params)
++{
++	int query_len;
++	int rc;
++	TDSDYNAMIC *dyn;
++	size_t definition_len = 0;
++	char *param_definition = NULL;
++	size_t converted_query_len;
++	const char *converted_query;
++
++	CHECK_TDS_EXTRA(tds);
++	if (params)
++		CHECK_PARAMINFO_EXTRA(params);
++
++	if (!query || !IS_TDS7_PLUS(tds))
++		return TDS_FAIL;
++
++	/* allocate a structure for this thing */
++	dyn = tds_alloc_dynamic(tds, id);
++	if (!dyn)
++		return TDS_FAIL;
++
++	tds->cur_dyn = dyn;
++
++	if (dyn_out)
++		*dyn_out = dyn;
++
++	if (tds_set_state(tds, TDS_QUERYING) != TDS_QUERYING)
++		goto failure_nostate;
++
++	query_len = (int)strlen(query);
++
++	converted_query = tds_convert_string(tds, tds->char_convs[client2ucs2], query, query_len, &converted_query_len);
++	if (!converted_query)
++		goto failure;
++
++	param_definition = tds7_build_param_def_from_query(tds, converted_query, converted_query_len, params, &definition_len);
++	if (!param_definition) {
++		tds_convert_string_free(query, converted_query);
++		goto failure;
++	}
++
++	tds->out_flag = TDS_RPC;
++	START_QUERY;
++	/* procedure name */
++	if (IS_TDS71_PLUS(tds)) {
++		tds_put_smallint(tds, -1);
++		tds_put_smallint(tds, TDS_SP_PREPEXEC);
++	} else {
++		tds_put_smallint(tds, 10);
++		TDS_PUT_N_AS_UCS2(tds, "sp_prepexec");
++	}
++	tds_put_smallint(tds, 0);
++
++	/* return param handle (int) */
++	tds_put_byte(tds, 0);
++	tds_put_byte(tds, 1);	/* result */
++	tds_put_byte(tds, SYBINTN);
++	tds_put_byte(tds, 4);
++	tds_put_byte(tds, 0);
++
++	tds7_put_params_definition(tds, param_definition, definition_len);
++	tds7_put_query_params(tds, converted_query, converted_query_len);
++	tds_convert_string_free(query, converted_query);
++	free(param_definition);
++
++	if (params) {
++		int i;
++
++		for (i = 0; i < params->num_cols; i++) {
++			TDSCOLUMN *param = params->columns[i];
++			/* TODO check error */
++			tds_put_data_info(tds, param, 0);
++			/* FIXME handle error */
++			tds_put_data(tds, param);
++		}
++	}
++
++	tds->internal_sp_called = TDS_SP_PREPEXEC;
++
++	rc = tds_query_flush_packet(tds);
++	if (rc != TDS_FAIL)
++		return rc;
++
++failure:
++	/* TODO correct if writing fail ?? */
++	tds_set_state(tds, TDS_IDLE);
++
++failure_nostate:
++	tds->cur_dyn = NULL;
++	tds_free_dynamic(tds, dyn);
++	if (dyn_out)
++		*dyn_out = NULL;
++	return TDS_FAIL;
++}
++
++/**
+  * Get column size for wire
+  */
+ static size_t
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 3939428..11a86fd 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.384 2010/05/07 21:11:30 jklowden Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.385 2010/06/19 09:51:36 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -625,7 +625,7 @@ tds_process_tokens(TDSSOCKET *tds, TDS_INT *result_type, int *done_flags, unsign
+ 						cursor->srv_status &= ~(TDS_CUR_ISTAT_CLOSED|TDS_CUR_ISTAT_OPEN|TDS_CUR_ISTAT_DEALLOC);
+ 						cursor->srv_status |= cursor->cursor_id ? TDS_CUR_ISTAT_OPEN : TDS_CUR_ISTAT_CLOSED|TDS_CUR_ISTAT_DEALLOC;
+ 					}
+-					if (tds->internal_sp_called == TDS_SP_PREPARE 
++					if ((tds->internal_sp_called == TDS_SP_PREPARE || tds->internal_sp_called == TDS_SP_PREPEXEC)
+ 					    && tds->cur_dyn && tds->cur_dyn->num_id == 0 && curcol->column_cur_size > 0) {
+ 						tds->cur_dyn->num_id = *(TDS_INT *) curcol->column_data;
+ 					}
+@@ -740,6 +740,7 @@ tds_process_tokens(TDSSOCKET *tds, TDS_INT *result_type, int *done_flags, unsign
+ 			switch (tds->internal_sp_called) {
+ 			case 0: 
+ 			case TDS_SP_PREPARE: 
++			case TDS_SP_PREPEXEC:
+ 			case TDS_SP_EXECUTE: 
+ 			case TDS_SP_UNPREPARE: 
+ 			case TDS_SP_EXECUTESQL:
+
+commit 5dadc5e04ffeee35b886c10e9e0dcd2fe7433975
+Author: freddy77 <freddy77>
+Date:   Sun Jun 20 08:38:41 2010 +0000
+
+    add Perl to tools required for CVS build
+
+diff --git a/ChangeLog b/ChangeLog
+index e13f077..0ed202b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jun 20 10:38:35 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* INSTALL.CVS: add Perl to tools required for CVS build
++
+ Sat Jun 19 11:51:23 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/odbc/odbc.c src/tds/query.c src/tds/token.c:
+ 	- enable defer by default, tests work correctly, use prepexec for
+@@ -2485,4 +2488,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3032 2010/06/19 09:51:35 freddy77 Exp $
++$Id: ChangeLog,v 1.3033 2010/06/20 08:38:41 freddy77 Exp $
+diff --git a/INSTALL.CVS b/INSTALL.CVS
+index 7fb6b55..33162c4 100644
+--- a/INSTALL.CVS
++++ b/INSTALL.CVS
+@@ -13,6 +13,7 @@ connecting to the CVS server.  Then follow these steps:
+ 	libtool		(GNU Libtool, library creation support scripts)
+ 	make		(GNU or BSD Make.)
+ 	gcc		(GNU Compiler Collection, for C code compilation)
++	perl		(Perl, used to generate some files)
+ 	
+ 	Autotool versions that work:
+ 	$ (autoconf --version; automake --version; libtool --version) |grep GNU
+@@ -62,4 +63,4 @@ the CVS tree via rsync:
+ $ rsync -av rsync://freetds.cvs.sourceforge.net/cvsroot/freetds/* .
+ 	
+ --
+-$Id: INSTALL.CVS,v 1.9 2008/07/17 11:52:33 freddy77 Exp $
++$Id: INSTALL.CVS,v 1.10 2010/06/20 08:38:41 freddy77 Exp $
+
+commit 1bda2905374a8a7eedbfb10be9afab16d0e171c0
+Author: freddy77 <freddy77>
+Date:   Sun Jun 20 12:19:41 2010 +0000
+
+    fix test script due to 2 distribution files
+
+diff --git a/ChangeLog b/ChangeLog
+index 0ed202b..ff11d5a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jun 20 14:19:31 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-dist.sh: fix test script due to 2 distribution files
++
+ Sun Jun 20 10:38:35 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* INSTALL.CVS: add Perl to tools required for CVS build
+ 
+@@ -2488,4 +2491,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3033 2010/06/20 08:38:41 freddy77 Exp $
++$Id: ChangeLog,v 1.3034 2010/06/20 12:19:41 freddy77 Exp $
+diff --git a/misc/test-dist.sh b/misc/test-dist.sh
+index 354d394..d799e77 100755
+--- a/misc/test-dist.sh
++++ b/misc/test-dist.sh
+@@ -55,7 +55,7 @@ make dist
+ echo "make distribution ok" >> "$LOG"
+ 
+ # untar to test it, should already contains documentation
+-DIR=`echo freetds-* | sed s,.tar.bz2$,,g`
++DIR=`echo freetds-*.tar.bz2 | sed s,.tar.bz2$,,g`
+ bzip2 -dc freetds-*.tar.bz2 | tar xf -
+ test -d "$DIR"
+ cd "$DIR"
+
+commit bfafbe719bff868ac7bf04e8bcf32a061f08ccc4
+Author: freddy77 <freddy77>
+Date:   Sat Jun 26 07:19:54 2010 +0000
+
+    reuse CheckCursor
+
+diff --git a/ChangeLog b/ChangeLog
+index ff11d5a..271cb6d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 26 09:19:45 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor2.c: reuse CheckCursor
++
+ Sun Jun 20 14:19:31 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/test-dist.sh: fix test script due to 2 distribution files
+ 
+@@ -2491,4 +2494,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3034 2010/06/20 12:19:41 freddy77 Exp $
++$Id: ChangeLog,v 1.3035 2010/06/26 07:19:54 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index 8a9cd6c..28cc035 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursor do not give error for statement that do not return rows  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.6 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.7 2010/06/26 07:19:54 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -16,19 +16,10 @@ main(int argc, char *argv[])
+ 
+ 	Command("CREATE TABLE #cursor2_test (i INT)");
+ 
+-	retcode = SQLSetConnectAttr(Connection, SQL_ATTR_CURSOR_TYPE,  (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER);
+-	if (retcode != SQL_SUCCESS) {
+-		CHKGetDiagRec(SQL_HANDLE_DBC, Connection, 1, sqlstate, NULL, (SQLCHAR *) msg, sizeof(msg), NULL, "S");
+-		sqlstate[5] = 0;
+-		if (strcmp((const char*) sqlstate, "S1092") == 0) {
+-			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+-			Disconnect();
+-			exit(0);
+-		}
+-		ODBC_REPORT_ERROR("SQLSetConnectAttr");
+-	}
++	CheckCursor();
+ 
+ 	ResetStatement();
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER, "S");
+ 
+ 	/* this should not fail or return warnings */
+ 	Command("DROP TABLE #cursor2_test");
+
+commit 5fc235c70b3f15fd315529f352c5bcd3e7568145
+Author: freddy77 <freddy77>
+Date:   Sat Jun 26 07:23:40 2010 +0000
+
+    add test for cursors on rpc
+
+diff --git a/ChangeLog b/ChangeLog
+index 271cb6d..40b021b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 26 09:23:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor2.c: add test for cursors on rpc
++
+ Sat Jun 26 09:19:45 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor2.c: reuse CheckCursor
+ 
+@@ -2494,4 +2497,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3035 2010/06/26 07:19:54 freddy77 Exp $
++$Id: ChangeLog,v 1.3036 2010/06/26 07:23:40 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index 28cc035..e16f726 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -1,8 +1,11 @@
+ #include "common.h"
+ 
+-/* Test cursor do not give error for statement that do not return rows  */
++/*
++ * 1) Test cursor do not give error for statement that do not return rows
++ * 2) Test cursor returns results on language RPCs
++ */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.7 2010/06/26 07:19:54 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.8 2010/06/26 07:23:40 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -26,6 +29,21 @@ main(int argc, char *argv[])
+ 
+ 	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "No");
+ 
++
++	ResetStatement();
++	CommandWithResult(Statement, "drop proc sp_test");
++	Command("create proc sp_test @name varchar(30) as select 0 as pippo select 1 as 'test', @name as 'nome'");
++
++	ResetStatement();
++	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, SQL_IS_INTEGER, "S");
++
++	Command(" exec sp_test 'ciao'");
++
++	CHKFetch("S");
++
++	ResetStatement();
++	Command("drop proc sp_test");
++
+ 	Disconnect();
+ 	
+ 	return 0;
+
+commit afb4bcdf3a38b5d01d6a883bbe46b1c01f131000
+Author: freddy77 <freddy77>
+Date:   Sat Jun 26 08:03:57 2010 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index 40b021b..c7ceadc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 26 10:03:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/cursor2.c: remove warning
++
+ Sat Jun 26 09:23:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor2.c: add test for cursors on rpc
+ 
+@@ -2497,4 +2500,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3036 2010/06/26 07:23:40 freddy77 Exp $
++$Id: ChangeLog,v 1.3037 2010/06/26 08:03:57 freddy77 Exp $
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index e16f726..039b21f 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -5,7 +5,7 @@
+  * 2) Test cursor returns results on language RPCs
+  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.8 2010/06/26 07:23:40 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.9 2010/06/26 08:03:57 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -13,7 +13,6 @@ main(int argc, char *argv[])
+ {
+ 	unsigned char sqlstate[6];
+ 	unsigned char msg[256];
+-	SQLRETURN retcode;
+ 
+ 	Connect();
+ 
+
+commit a36099f10fad14bc93ea4d6308c02f4882fce7f0
+Author: freddy77 <freddy77>
+Date:   Sat Jun 26 09:14:49 2010 +0000
+
+    fix a leak if cursor returns multiple resultsets
+
+diff --git a/ChangeLog b/ChangeLog
+index c7ceadc..6a53999 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jun 26 11:14:37 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/token.c: fix a leak if cursor returns multiple resultsets
++
+ Sat Jun 26 10:03:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/cursor2.c: remove warning
+ 
+@@ -2500,4 +2503,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3037 2010/06/26 08:03:57 freddy77 Exp $
++$Id: ChangeLog,v 1.3038 2010/06/26 09:14:49 freddy77 Exp $
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 11a86fd..fcfb8b2 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.385 2010/06/19 09:51:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.386 2010/06/26 09:14:50 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -1588,6 +1588,7 @@ tds7_process_result(TDSSOCKET * tds)
+ 		return TDS_FAIL;
+ 	tds->current_results = info;
+ 	if (tds->cur_cursor) {
++		tds_free_results(tds->cur_cursor->res_info);
+ 		tds->cur_cursor->res_info = info;
+ 		tdsdump_log(TDS_DBG_INFO1, "set current_results to cursor->res_info\n");
+ 	} else {
+
+commit 32c369ff1f4e25b11d22d7171b44297968d29e92
+Author: berryc <berryc>
+Date:   Sat Jun 26 23:47:01 2010 +0000
+
+    VMS-style native command syntax for fisql, freebcp, and defncopy
+
+diff --git a/Makefile.am b/Makefile.am
+index 1ae6503..e9268f1 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,4 +1,4 @@
+-# version $Id: Makefile.am,v 1.47 2010/01/21 08:34:04 freddy77 Exp $
++# version $Id: Makefile.am,v 1.48 2010/06/26 23:47:01 berryc Exp $
+ 
+ ## SUBDIRS determines in which directories automake will generate a Makefile
+ ## See also AC_OUTPUT in configure.ac
+@@ -9,11 +9,22 @@ ACLOCAL_AMFLAGS = -I m4
+ 
+ VMS	=	vms/config_h.vms \
+ 		vms/configure.com \
++		vms/edit.c \
+ 		vms/descrip_mms.template \
+ 		vms/getpass.c \
+ 		vms/libodbc.opt \
++		vms/Makefile.am \
+ 		vms/odbc_driver_axp.opt \
+-		vms/README.vms
++		vms/README.vms \
++		vms/vargdefs.h \
++		vms/vmsarg_command_bcp.cld \
++		vms/vmsarg_command_defncopy.cld \
++		vms/vmsarg_command_isql.cld \
++		vms/vmsarg_mapping_bcp.c \
++		vms/vmsarg_mapping_defncopy.c \
++		vms/vmsarg_mapping_isql.c \
++		vms/vmsarg_parse.c
++
+ 
+ EXTRA_DIST = 	$(VMS) interfaces PWD.in BUGS \
+ 		freetds.conf locales.conf \
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index dd6b021..7cfda75 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -87,7 +87,7 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.19 2010/01/11 14:03:20 jklowden Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.20 2010/06/26 23:47:02 berryc Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -143,6 +143,11 @@ main(int argc, char *argv[])
+ 	RETCODE erc;
+ 	int i, nrows;
+ 
++#ifdef __VMS
++        /* Convert VMS-style arguments to Unix-style */
++        parse_vms_args(&argc, &argv);
++#endif
++
+ 	/* Initialize db-lib */
+ #if _WIN32 && defined(MicrosoftsDbLib)
+ 	LPCSTR msg = dbinit();	
+diff --git a/src/apps/fisql/fisql.c b/src/apps/fisql/fisql.c
+index 9e4b512..8ba0189 100644
+--- a/src/apps/fisql/fisql.c
++++ b/src/apps/fisql/fisql.c
+@@ -268,6 +268,11 @@ main(int argc, char *argv[])
+ 	int nby;
+ 	char adash;
+ 
++#ifdef __VMS
++        /* Convert VMS-style arguments to Unix-style */
++        parse_vms_args(&argc, &argv);
++#endif
++
+ 	editor = getenv("EDITOR");
+ 	if (!editor) {
+ 		editor = getenv("VISUAL");
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 79bd0bd..84c0965 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -50,7 +50,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.53 2010/05/21 14:10:31 freddy77 Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.54 2010/06/26 23:47:02 berryc Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -74,6 +74,11 @@ main(int argc, char **argv)
+ 	DBPROCESS *dbproc;
+ 	int ok = FALSE;
+ 
++#ifdef __VMS
++        /* Convert VMS-style arguments to Unix-style */
++        parse_vms_args(&argc, &argv);
++#endif
++
+ 	memset(&params, '\0', sizeof(params));
+ 
+ 	params.textsize = 4096;	/* our default text size is 4K */
+diff --git a/vms/Makefile.am b/vms/Makefile.am
+index 8565315..1260e1c 100644
+--- a/vms/Makefile.am
++++ b/vms/Makefile.am
+@@ -1,4 +1,8 @@
+-EXTRA_DIST = config_h.vms configure.com descrip_mms.template \
+-	edit.c getpass.c libodbc.opt odbc_driver_axp.opt README.vms
++EXTRA_DIST = config_h.vms  configure.com edit.c descrip_mms.template \
++		getpass.c libodbc.opt odbc_driver_axp.opt README.vms \
++		vargdefs.h vmsarg_command_bcp.cld vmsarg_command_defncopy.cld \
++		vmsarg_command_isql.cld vmsarg_mapping_bcp.c \
++		vmsarg_mapping_defncopy.c vmsarg_mapping_isql.c \
++		vmsarg_parse.c
+ 
+ clean:
+diff --git a/vms/config_h.vms b/vms/config_h.vms
+index f727dd6..b122278 100644
+--- a/vms/config_h.vms
++++ b/vms/config_h.vms
+@@ -1,4 +1,4 @@
+-/* $Id: config_h.vms,v 1.10 2009/04/09 01:40:25 jklowden Exp $ */
++/* $Id: config_h.vms,v 1.11 2010/06/26 23:47:02 berryc Exp $ */
+ 
+ /* include/config.h.in.  Generated from configure.ac by autoheader.  */
+ /* and edited by hand for VMS */
+@@ -346,4 +346,7 @@ char * readpassphrase(const char *, char *, size_t, int);
+ #define HAVE_SQLSETPOSIROW 1
+ #define TDS_SQLCOLATTRIBUTE_SQLLEN 1
+ 
++/* Prototype for routine to convert VMS-style arguments to Unix-style. */
++int parse_vms_args(int *argc, char **argv[]);
++
+ #endif /* CONFIG_H_LOADED */
+diff --git a/vms/descrip_mms.template b/vms/descrip_mms.template
+index eb5b760..b92c881 100644
+--- a/vms/descrip_mms.template
++++ b/vms/descrip_mms.template
+@@ -16,7 +16,7 @@
+ # Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ # Boston, MA 02111-1307, USA.
+ # 
+-# $Id: descrip_mms.template,v 1.15 2010/05/21 14:02:08 freddy77 Exp $
++# $Id: descrip_mms.template,v 1.16 2010/06/26 23:47:02 berryc Exp $
+ 
+ # OpenVMS description file for FreeTDS
+ 
+@@ -293,10 +293,21 @@ $(TDSODBCSHR) : []libtdsodbc$(OLB)
+ apps : freebcp$(E) tsql$(E) bsqldb$(E) defncopy$(E) tdspool$(E) fisql$(E)
+ 	@ continue
+ 
+-freebcp$(E) : [.src.apps]freebcp$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+-	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
++[]vmsarg_parse$(OBJ) : [.vms]vmsarg_parse.c
++       $(CC) $(CFLAGS)/INCLUDE=([.vms],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++
++freebcp$(E) : [.src.apps]freebcp$(OBJ) []vmsarg_mapping_bcp$(OBJ) []vmsarg_command_bcp$(OBJ) []vmsarg_parse$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
++
++[.src.apps]freebcp$(OBJ) : [.src.apps]freebcp.c []libsybdb$(OLB) []libtds$(OLB)
++
++[]vmsarg_mapping_bcp$(OBJ) : [.vms]vmsarg_mapping_bcp.c
++       $(CC) $(CFLAGS)/INCLUDE=([.vms],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[]vmsarg_command_bcp$(OBJ) : [.vms]vmsarg_command_bcp.cld
++       SET COMMAND/OBJECT=$(MMS$TARGET) $(MMS$SOURCE)
+ 
+-[.src.apps]freebcp$(OBJ) : [.src.apps]freebcp.c
+ 
+ tsql$(E) : [.src.apps]tsql$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
+@@ -305,24 +316,34 @@ tsql$(E) : [.src.apps]tsql$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+ 	@ define/nolog/user_mode readline [.include]
+ 	$(CC) $(CFLAGS)/INCLUDE=($(CINCLUDE)) $(MMS$SOURCE)
+ 
++
+ bsqldb$(E) : [.src.apps]bsqldb$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
+ 
+ [.src.apps]bsqldb$(OBJ) : [.src.apps]bsqldb.c
+ 
+-defncopy$(E) : [.src.apps]defncopy$(OBJ) []libsybdb$(OLB) []libtds$(OLB)
+-	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
+ 
+-[.src.apps]defncopy$(OBJ) : [.src.apps]defncopy.c
++defncopy$(E) : [.src.apps]defncopy$(OBJ) []vmsarg_mapping_defncopy$(OBJ) []vmsarg_command_defncopy$(OBJ) []vmsarg_parse$(OBJ)
++	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
++ 
++[.src.apps]defncopy$(OBJ) : [.src.apps]defncopy.c []libsybdb$(OLB) []libtds$(OLB)
++
++[]vmsarg_mapping_defncopy$(OBJ) : [.vms]vmsarg_mapping_defncopy.c
++       $(CC) $(CFLAGS)/INCLUDE=([.vms],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[]vmsarg_command_defncopy$(OBJ) : [.vms]vmsarg_command_defncopy.cld
++       SET COMMAND/OBJECT=$(MMS$TARGET) $(MMS$SOURCE)
++
+ 
+ tdspool$(E) : $(TDSPOOLOBJS) []libtdssrv$(OLB) []libtds$(OLB)
+ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(TDSPOOLOBJS), []libtdssrv$(OLB)/library, []libtds$(OLB)/library
+ 
+ 
+-fisql$(E) : [.src.apps.fisql]fisql$(OBJ) [.src.apps.fisql]interrupt$(OBJ) [.src.apps.fisql]handlers$(OBJ) [.vms]edit$(OBJ)
+-	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
+-
+-[.src.apps.fisql]fisql$(OBJ) : [.src.apps.fisql]fisql.c
++fisql$(E) : [.src.apps.fisql]fisql$(OBJ) [.src.apps.fisql]interrupt$(OBJ) [.src.apps.fisql]handlers$(OBJ) [.vms]edit$(OBJ) \
++    []vmsarg_mapping_isql$(OBJ) []vmsarg_command_isql$(OBJ) []vmsarg_parse$(OBJ)
++ 	link$(LINKFLAGS)/exe=$(MMS$TARGET) $(MMS$SOURCE_LIST),[]libsybdb$(OLB)/library, []libtds$(OLB)/library
++ 
++[.src.apps.fisql]fisql$(OBJ) : [.src.apps.fisql]fisql.c []libsybdb$(OLB) []libtds$(OLB)
+ 	@ define/nolog/user_mode readline [.include]
+ 	$(CC) $(CFLAGS)/INCLUDE=($(CINCLUDE)) $(MMS$SOURCE)
+ 
+@@ -330,6 +351,11 @@ fisql$(E) : [.src.apps.fisql]fisql$(OBJ) [.src.apps.fisql]interrupt$(OBJ) [.src.
+ 
+ [.src.apps.fisql]handlers$(OBJ) : [.src.apps.fisql]handlers.c
+ 
++[]vmsarg_mapping_isql$(OBJ) : [.vms]vmsarg_mapping_isql.c
++       $(CC) $(CFLAGS)/INCLUDE=([.vms],$(CINCLUDE)) $(CDBGFLAGS) $(MMS$SOURCE)
++
++[]vmsarg_command_isql$(OBJ) : [.vms]vmsarg_command_isql.cld
++       SET COMMAND/OBJECT=$(MMS$TARGET) $(MMS$SOURCE)
+ 
+ # Run the test suite
+ 
+diff --git a/vms/vargdefs.h b/vms/vargdefs.h
+new file mode 100644
+index 0000000..a75adc9
+--- /dev/null
++++ b/vms/vargdefs.h
+@@ -0,0 +1,70 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++
++/*
++ * Definitions used by the VMSARG parsing and mapping routines.
++ *
++ * Based on VMSARG Version 2.0 by Tom Wade <t.wade@vms.eurokom.ei>
++ *
++ * Extensively revised for inclusion in FreeTDS by Craig A. Berry.
++ *
++ * From the VMSARG 2.0 documentation:
++ *
++ * The product is aimed at . . . people who are porting a package from 
++ * Unix to VMS. This software is made freely available for inclusion in 
++ * such products, whether they are freeware, public domain or commercial. 
++ * No licensing is required.
++ */
++
++#if __CRTL_VER >= 70302000 && !defined(__VAX)
++#define QUAL_LENGTH		(4000+1)
++#define S_LENGTH		(4096+1)
++#else
++#define QUAL_LENGTH		(255+1)
++#define S_LENGTH		(1024+1)
++#endif
++
++#define MAX_ARGS 255
++
++/*	bit fields for arg flags.
++*/
++
++#define VARG_M_AFFIRM		 1
++#define VARG_M_NEGATIVE		 2
++#define VARG_M_KEYWORDS		 4
++#define VARG_M_SEPARATOR	 8
++#define VARG_M_DATE		16
++#define VARG_M_APPEND		32
++#define VARG_M_HELP		64
++
++/*	bit fields for action flags.
++*/
++
++#define VARGACT_M_UPPER		1
++#define VARGACT_M_LOWER		2
++#define VARGACT_M_SPECIAL	4
++#define VARGACT_M_ESCAPE	8
++#define VARGACT_M_DOUBLE	16
++#define VARGACT_M_IMAGE		32
++#define VARGACT_M_SYMBOL	64
++#define VARGACT_M_COMMAND	128
++#define VARGACT_M_RETURN	256
++#define VARGACT_M_PROTECT	512
++#define VARGACT_M_UNIXARG	1024
++
++#define VARGACT_M_PROTMASK	1+2+4+8+16
+diff --git a/vms/vmsarg_command_bcp.cld b/vms/vmsarg_command_bcp.cld
+new file mode 100644
+index 0000000..6872e2b
+--- /dev/null
++++ b/vms/vmsarg_command_bcp.cld
+@@ -0,0 +1,92 @@
++! FreeTDS - Library of routines accessing Sybase and Microsoft databases
++! Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++!
++! This library is free software; you can redistribute it and/or
++! modify it under the terms of the GNU Library General Public
++! License as published by the Free Software Foundation; either
++! version 2 of the License, or (at your option) any later version.
++!
++! This library is distributed in the hope that it will be useful,
++! but WITHOUT ANY WARRANTY; without even the implied warranty of
++! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++! Library General Public License for more details.
++!
++! You should have received a copy of the GNU Library General Public
++! License along with this library; if not, write to the
++! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++! Boston, MA 02111-1307, USA.
++
++! Command definitions for the BCP command.
++
++
++Module VARG_CLD
++
++Define Verb VARG
++   parameter P1, label=TABLE_NAME
++      value (required)
++   parameter P2, label=DIRECTION
++      value (required,type=DIR_KEYS)
++   parameter P3, label=DATA_FILE
++      value (required,type=$file)
++   qualifier MAX_ERRORS
++      value (required,type=$number)
++   qualifier FORMAT_FILE
++      value (required,type=$file)
++   qualifier ERRORFILE
++      value (required,type=$file)
++   qualifier FIRST_ROW
++      value (required,type=$number)
++   qualifier LAST_ROW
++      value (required,type=$number)
++   qualifier BATCH_SIZE
++      value (required,type=$number)
++   qualifier NATIVE_DEFAULT
++   qualifier CHARACTER_DEFAULT
++   qualifier COLUMN_TERMINATOR
++      value (required)
++   qualifier ROW_TERMINATOR
++      value (required)
++   qualifier USERNAME
++      value
++   qualifier PASSWORD
++      value (default="")
++   qualifier SERVER_NAME
++      value (required)
++   qualifier INPUT
++      value (required,type=$file)
++   qualifier OUTPUT
++      value (required,type=$file)
++   qualifier SERVCHARSET
++      value
++   qualifier CLIENTCHARSET
++      value
++   qualifier DISPCHARSET
++      value
++   qualifier FILECHARSET
++      value
++   qualifier LANGUAGE
++      value
++   qualifier FILECHARSET
++      value
++   qualifier TDSPACKETSIZE
++      value (type=$number)
++   qualifier TEXTSIZE
++      value (type=$number)
++   qualifier VERSION, syntax=NOPARAM
++   qualifier HOMEDIR
++      value
++   qualifier ENCRYPT
++   qualifier IDENTITY
++   disallow (NATIVE_DEFAULT and CHARACTER_DEFAULT)
++
++define type DIR_KEYS
++   keyword IN
++   keyword OUT
++
++define syntax NOPARAM
++   parameter P1, label=TABLE_NAME
++   parameter P2, label=DIRECTION
++      value (type=DIR_KEYS)
++   parameter P3, label=DATA_FILE
++      value (type=$file)
++
+diff --git a/vms/vmsarg_command_defncopy.cld b/vms/vmsarg_command_defncopy.cld
+new file mode 100644
+index 0000000..0569eed
+--- /dev/null
++++ b/vms/vmsarg_command_defncopy.cld
+@@ -0,0 +1,65 @@
++! FreeTDS - Library of routines accessing Sybase and Microsoft databases
++! Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++!
++! This library is free software; you can redistribute it and/or
++! modify it under the terms of the GNU Library General Public
++! License as published by the Free Software Foundation; either
++! version 2 of the License, or (at your option) any later version.
++!
++! This library is distributed in the hope that it will be useful,
++! but WITHOUT ANY WARRANTY; without even the implied warranty of
++! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++! Library General Public License for more details.
++!
++! You should have received a copy of the GNU Library General Public
++! License along with this library; if not, write to the
++! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++! Boston, MA 02111-1307, USA.
++
++! Command definitions for the DEFNCOPY command.
++
++Module VARG_CLD
++
++define verb VARG
++   parameter P1, label=DIRECTION
++      value (required,type=DIR_KEYS)
++   parameter P2, label=FILE_NAME
++      value (required,type=$file)
++   parameter P3, label=DATABASE_NAME
++      value (required)
++   parameter P4, label=OBJECT_NAME
++      value (list)
++   qualifier USERNAME
++      value
++   qualifier PASSWORD
++      value (default="")
++   qualifier SERVER_NAME, label=SERVERNAME
++      value
++   qualifier VERSION, syntax=NOPARAM
++   qualifier INTERFACES, label=INTERFACE
++      value (type=$file)
++   qualifier DISPCHARSET
++      value
++   qualifier LANGUAGE
++      value
++   qualifier SERVCHARSET
++      value
++   qualifier CLIENTCHARSET
++      value
++   qualifier REAL_VERSION
++   qualifier HOMEDIR
++      value
++
++define type DIR_KEYS
++   keyword IN
++   keyword OUT
++
++define syntax NOPARAM
++   parameter P1, label=DIRECTION
++      value (type=DIR_KEYS)
++   parameter P2, label=FILE_NAME
++      value (type=$file)
++   parameter P3, label=DATABASE_NAME
++   parameter P4, label=OBJECT_NAME
++      value (list)
++
+diff --git a/vms/vmsarg_command_isql.cld b/vms/vmsarg_command_isql.cld
+new file mode 100644
+index 0000000..b31a975
+--- /dev/null
++++ b/vms/vmsarg_command_isql.cld
+@@ -0,0 +1,79 @@
++! FreeTDS - Library of routines accessing Sybase and Microsoft databases
++! Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++!
++! This library is free software; you can redistribute it and/or
++! modify it under the terms of the GNU Library General Public
++! License as published by the Free Software Foundation; either
++! version 2 of the License, or (at your option) any later version.
++!
++! This library is distributed in the hope that it will be useful,
++! but WITHOUT ANY WARRANTY; without even the implied warranty of
++! MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++! Library General Public License for more details.
++!
++! You should have received a copy of the GNU Library General Public
++! License along with this library; if not, write to the
++! Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++! Boston, MA 02111-1307, USA.
++
++! Command definitions for the ISQL command.
++
++Module VARG_CLD
++
++Define Verb VARG
++   qualifier ECHO
++   qualifier STATISTICS
++   qualifier NOPROMPT
++   qualifier TERMINATOR
++      value
++   qualifier WIDTH
++      value (type=$number)
++   qualifier COLSEPARATOR
++      value
++   qualifier ROWSINPAGE
++      value (type=$number)
++   qualifier TIMEOUT
++      value
++   qualifier ERRORLEVEL
++      value (type=$number)
++   qualifier USERNAME
++      value
++   qualifier PASSWORD
++      value
++   qualifier SERVER_NAME
++      value
++   qualifier INTERFACE
++      value (type=$file)
++   qualifier HOSTNAME
++      value
++   qualifier CLIENTCHARSET
++      value
++   qualifier DISPCHARSET
++      value
++   qualifier INPUT
++      value (type=$file)
++   qualifier OUTPUT
++      value (type=$file)
++   qualifier LANGUAGE
++      value
++   qualifier HOMEDIR
++      value
++   qualifier VERSION
++   qualifier DEBUG
++   qualifier BROWSE
++   qualifier RECORD_FRONT_TO_SERVER
++      value
++   qualifier LOGINTIME
++      value
++   qualifier EDITOR
++      value
++   qualifier TDSPACKETSIZE
++      value (type=$number)
++   qualifier TRACE
++      value
++   qualifier ADDID
++   qualifier LOOK3
++   qualifier ENCRYPT
++   qualifier CHAIN_XACT
++   qualifier FIPS
++define syntax NOPARAM
+diff --git a/vms/vmsarg_mapping_bcp.c b/vms/vmsarg_mapping_bcp.c
+new file mode 100644
+index 0000000..82ef349
+--- /dev/null
++++ b/vms/vmsarg_mapping_bcp.c
+@@ -0,0 +1,136 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++
++/*
++ * Mapping table for the BCP command.
++ */
++
++int vmsarg_mapping (int *nvargs, char *vms_arg[], char *unix_arg[],
++	char *unix_narg[], char *vms_key[], char *unix_key[],
++	char *separator[], int flags[], char *pattern[],
++	char **outverb, int *action_flags, char **arg_symbol,
++	char **image_name)
++{
++ *nvargs = 26;
++ *action_flags = 1301;
++ vms_arg[1] = "TABLE_NAME";
++ flags[1] = 1;
++ unix_arg[1] = "$";
++
++ vms_arg[2] = "DIRECTION";
++ flags[2] = 1;
++ unix_arg[2] = "$";
++
++ vms_arg[3] = "DATA_FILE";
++ flags[3] = 1;
++ unix_arg[3] = "$";
++
++ vms_arg[4] = "MAX_ERRORS";
++ flags[4] = 1;
++ unix_arg[4] = "-m";
++
++ vms_arg[5] = "FORMAT_FILE";
++ flags[5] = 1;
++ unix_arg[5] = "-f";
++
++ vms_arg[6] = "ERRORFILE";
++ flags[6] = 1;
++ unix_arg[6] = "-e";
++
++ vms_arg[7] = "FIRST_ROW";
++ flags[7] = 1;
++ unix_arg[7] = "-F";
++
++ vms_arg[8] = "LAST_ROW";
++ flags[8] = 1;
++ unix_arg[8] = "-L";
++
++ vms_arg[9] = "BATCH_SIZE";
++ flags[9] = 1;
++ unix_arg[9] = "-b";
++
++ vms_arg[10] = "NATIVE_DEFAULT";
++ flags[10] = 1;
++ unix_arg[10] = "-n";
++
++ vms_arg[11] = "CHARACTER_DEFAULT";
++ flags[11] = 1;
++ unix_arg[11] = "-c";
++
++ vms_arg[12] = "COLUMN_TERMINATOR";
++ flags[12] = 1;
++ unix_arg[12] = "-t";
++
++ vms_arg[13] = "ROW_TERMINATOR";
++ flags[13] = 1;
++ unix_arg[13] = "-r";
++
++ vms_arg[14] = "USERNAME";
++ flags[14] = 1;
++ unix_arg[14] = "-U";
++
++ vms_arg[15] = "PASSWORD";
++ flags[15] = 1;
++ unix_arg[15] = "-P";
++
++ vms_arg[16] = "SERVER_NAME";
++ flags[16] = 1;
++ unix_arg[16] = "-S";
++
++ vms_arg[17] = "INPUT";
++ flags[17] = 1;
++ unix_arg[17] = "-i";
++
++ vms_arg[18] = "OUTPUT";
++ flags[18] = 1;
++ unix_arg[18] = "-o";
++
++ vms_arg[19] = "TDSPACKETSIZE";
++ flags[19] = 1;
++ unix_arg[19] = "-A";
++
++ vms_arg[20] = "TEXTSIZE";
++ flags[20] = 1;
++ unix_arg[20] = "-T";
++
++ vms_arg[21] = "VERSION";
++ flags[21] = 1;
++ unix_arg[21] = "-v";
++
++ vms_arg[22] = "DISPCHARSET";
++ flags[22] = 1;
++ unix_arg[22] = "-a";
++
++ vms_arg[23] = "LANGUAGE";
++ flags[23] = 1;
++ unix_arg[23] = "-z";
++
++ vms_arg[24] = "CLIENTCHARSET";
++ flags[24] = 1;
++ unix_arg[24] = "-J";
++
++ vms_arg[25] = "IDENTITY";
++ flags[25] = 1;
++ unix_arg[25] = "-E";
++
++ vms_arg[26] = "ENCRYPT";
++ flags[26] = 1;
++ unix_arg[26] = "-X";
++
++ return 1;
++}
+diff --git a/vms/vmsarg_mapping_defncopy.c b/vms/vmsarg_mapping_defncopy.c
+new file mode 100644
+index 0000000..289b75c
+--- /dev/null
++++ b/vms/vmsarg_mapping_defncopy.c
+@@ -0,0 +1,80 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++
++/*
++ * Mapping table for the DEFNCOPY command.
++ */
++
++int vmsarg_mapping (int *nvargs, char *vms_arg[], char *unix_arg[],
++	char *unix_narg[], char *vms_key[], char *unix_key[],
++	char *separator[], int flags[], char *pattern[],
++	char **outverb, int *action_flags, char **arg_symbol,
++	char **image_name)
++{
++ *nvargs = 12;
++ *action_flags = 1301;
++ vms_arg[1] = "DIRECTION";
++ flags[1] = 1;
++ unix_arg[1] = "$";
++
++ vms_arg[2] = "FILE_NAME";
++ flags[2] = 1;
++ unix_arg[2] = "$";
++
++ vms_arg[3] = "DATABASE_NAME";
++ flags[3] = 1;
++ unix_arg[3] = "$";
++
++ vms_arg[4] = "OBJECT_NAME";
++ flags[4] = 1;
++ unix_arg[4] = "$";
++
++ vms_arg[5] = "USERNAME";
++ flags[5] = 1;
++ unix_arg[5] = "-U";
++
++ vms_arg[6] = "PASSOWRD";
++ flags[6] = 1;
++ unix_arg[6] = "-P";
++
++ vms_arg[7] = "SERVER_NAME";
++ flags[7] = 1;
++ unix_arg[7] = "-S";
++
++ vms_arg[8] = "VERSION";
++ flags[8] = 1;
++ unix_arg[8] = "-v";
++
++ vms_arg[9] = "INTERFACES";
++ flags[9] = 1;
++ unix_arg[9] = "-I";
++
++ vms_arg[10] = "DISPCHARSET";
++ flags[10] = 1;
++ unix_arg[10] = "-a";
++
++ vms_arg[11] = "LANGUAGE";
++ flags[11] = 1;
++ unix_arg[11] = "-z";
++
++ vms_arg[12] = "CLIENTCHARSET";
++ flags[12] = 1;
++ unix_arg[12] = "-J";
++
++ return 1;
++}
+diff --git a/vms/vmsarg_mapping_isql.c b/vms/vmsarg_mapping_isql.c
+new file mode 100644
+index 0000000..19ff256
+--- /dev/null
++++ b/vms/vmsarg_mapping_isql.c
+@@ -0,0 +1,143 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++
++/*
++ * Mapping table for the ISQL command.
++ */
++
++#include <stdlib.h>
++
++int vmsarg_mapping (int *nvargs, char *vms_arg[], char *unix_arg[],
++	char *unix_narg[], char *vms_key[], char *unix_key[],
++	char *separator[], int flags[], char *pattern[],
++	char **outverb, int *action_flags, char **arg_symbol,
++	char **image_name)
++{
++ *nvargs = 26;
++ *action_flags = 1301;
++ vms_arg[1] = "USERNAME";
++ flags[1] = 1;
++ unix_arg[1] = "-U";
++
++ vms_arg[2] = "PASSWORD";
++ flags[2] = 1;
++ unix_arg[2] = "-P";
++
++ vms_arg[3] = "SERVER_NAME";
++ flags[3] = 1;
++ unix_arg[3] = "-S";
++
++ vms_arg[4] = "TIMEOUT";
++ flags[4] = 1;
++ unix_arg[4] = "-t";
++
++ vms_arg[5] = "INPUT";
++ flags[5] = 1;
++ unix_arg[5] = "-i";
++
++ vms_arg[6] = "OUTPUT";
++ flags[6] = 1;
++ unix_arg[6] = "-o";
++
++ vms_arg[7] = "VERSION";
++ flags[7] = 1;
++ unix_arg[7] = "-v";
++
++ vms_arg[8] = "ECHO";
++ flags[8] = 1;
++ unix_arg[8] = "-e";
++
++ vms_arg[9] = "FIPS";
++ flags[9] = 1;
++ unix_arg[9] = "-F";
++
++ vms_arg[10] = "STATISTICS";
++ flags[10] = 1;
++ unix_arg[10] = "-p";
++
++ vms_arg[11] = "NOPROMPT";
++ flags[11] = 1;
++ unix_arg[11] = "-n";
++
++ vms_arg[12] = "ENCRYPT";
++ flags[12] = 1;
++ unix_arg[12] = "-X";
++
++ vms_arg[13] = "CHAIN_XACT";
++ flags[13] = 1;
++ unix_arg[13] = "-Y";
++
++ vms_arg[14] = "DISPCHARSET";
++ flags[14] = 1;
++ unix_arg[14] = "-a";
++
++ vms_arg[15] = "TDSPACKETSIZE";
++ flags[15] = 1;
++ unix_arg[15] = "-A";
++
++ vms_arg[16] = "TERMINATOR";
++ flags[16] = 1;
++ unix_arg[16] = "-c";
++
++ vms_arg[17] = "EDITOR";
++ flags[17] = 1;
++ unix_arg[17] = "-E";
++
++ vms_arg[18] = "ROWSINPAGE";
++ flags[18] = 1;
++ unix_arg[18] = "-h";
++
++ vms_arg[19] = "HOSTNAME";
++ flags[19] = 1;
++ unix_arg[19] = "-H";
++
++ vms_arg[20] = "INTERFACE";
++ flags[20] = 1;
++ unix_arg[20] = "-I";
++
++ vms_arg[21] = "CLIENTCHARSET";
++ flags[21] = 1;
++ unix_arg[21] = "-J";
++
++ vms_arg[22] = "ERRORLEVEL";
++ flags[22] = 1;
++ unix_arg[22] = "-m";
++
++ vms_arg[23] = "LOGINTIME";
++ flags[23] = 1;
++ unix_arg[23] = "-l";
++
++ vms_arg[24] = "COLSEPARATOR";
++ flags[24] = 1;
++ unix_arg[24] = "-s";
++
++ vms_arg[25] = "WIDTH";
++ flags[25] = 1;
++ unix_arg[25] = "-w";
++
++ vms_arg[26] = "LANGUAGE";
++ flags[26] = 1;
++ unix_arg[26] = "-z";
++
++ /* Because vi is not a reasonable default on VMS.
++  */
++ if (setenv("EDITOR", "edit", 0) != 0)
++	return 0;
++
++ return 1;
++}
+diff --git a/vms/vmsarg_parse.c b/vms/vmsarg_parse.c
+new file mode 100644
+index 0000000..be53f2d
+--- /dev/null
++++ b/vms/vmsarg_parse.c
+@@ -0,0 +1,814 @@
++/* FreeTDS - Library of routines accessing Sybase and Microsoft databases
++ * Copyright (C) 2010  Craig A. Berry	craigberry@mac.com
++ *
++ * This library is free software; you can redistribute it and/or
++ * modify it under the terms of the GNU Library General Public
++ * License as published by the Free Software Foundation; either
++ * version 2 of the License, or (at your option) any later version.
++ *
++ * This library is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
++ * Library General Public License for more details.
++ *
++ * You should have received a copy of the GNU Library General Public
++ * License along with this library; if not, write to the
++ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
++ * Boston, MA 02111-1307, USA.
++
++/*
++ * Program to Parse VMS style arguments.  The calling program passes
++ * argc, argv into this routine, and we translate the VMS qualifiers into
++ * Unix style arguments according to a user specified translation table.
++ * It then puts these into a new argv and returns that address to the
++ * caller.  The calling program then happily proceeds with the Unix style
++ * qualifiers that it was written to deal with.
++ *
++ * Based on VMSARG Version 2.0 by Tom Wade <t.wade@vms.eurokom.ei>
++ *
++ * Extensively revised for inclusion in FreeTDS by Craig A. Berry.
++ *
++ * From the VMSARG 2.0 documentation:
++ *
++ * The product is aimed at . . . people who are porting a package from 
++ * Unix to VMS. This software is made freely available for inclusion in 
++ * such products, whether they are freeware, public domain or commercial. 
++ * No licensing is required.
++ */
++
++
++#include "vargdefs.h"
++
++#include <stdio.h>
++#include <string.h>
++#include <stdlib.h>
++#include <ctype.h>
++
++#include <climsgdef.h>
++#include <descrip.h>
++#include <libdef.h>
++#include <ssdef.h>
++
++#include <cli$routines.h>
++#include <lbr$routines.h>
++#include <lib$routines.h>
++#include <starlet.h>
++
++/*	Increment arg counter and crash out if we have too many
++*/
++
++#define Increment(x) x = x + 1;\
++                     if (x > MAX_ARGS) sys$exit(SS$_OVRMAXARG);
++
++/*	Declare internal static routines
++*/
++
++static int varg_get_index(), varg_set_index(), varg_convert_date(), varg_do_help();
++static int varg_protect_string(), varg_set_symbol(), varg_do_command();
++static int varg_do_exit();
++
++parse_vms_args(int *argc, char **argv[])
++{
++        static char command[S_LENGTH], value_template[S_LENGTH];
++        static char qual_template[S_LENGTH];
++        char verb[] = "VARG ";
++        char *vms_arg[MAX_ARGS];
++        char *unix_arg[MAX_ARGS];
++        char *unix_narg[MAX_ARGS];
++        char *vms_key[MAX_ARGS];
++        char *unix_key[MAX_ARGS];
++        char *separator[MAX_ARGS];
++        char *pattern[MAX_ARGS];
++        char *outverb, *arg_symbol, *image_name;
++        char foreign_image[S_LENGTH];
++        int flags[MAX_ARGS], action_flags;
++        int  nvargs, u_length, l_element, index;
++        char arg_string[S_LENGTH], arg_element[S_LENGTH];
++        static char value[S_LENGTH];
++        char *special_chars;
++        char default_special[] = "!@#^&()=+\'\"/?,";
++        $DESCRIPTOR(command_desc, command);
++        $DESCRIPTOR(qual_desc, "");
++        $DESCRIPTOR(value_desc, value);
++        int i, length, status, i_length, arg_count, q_length;
++        static char command_args[S_LENGTH];
++        $DESCRIPTOR(command_arg_desc, command_args);
++        extern VARG_CLD;
++        static	char *newargv[MAX_ARGS];
++        int affirm_flag, negative_flag, keywords_flag, separator_flag;
++        int date_flag, append_flag, present, more_flag, multivalue, help_flag;
++        int vmsarg_mapping();
++
++        /*	Get the VMS -> Unix mapping definitions from the routine generated
++        	by the GEN_MAPPING utility.
++        */
++
++        vmsarg_mapping(&nvargs, vms_arg, unix_arg, unix_narg, vms_key, unix_key,
++                       separator, flags, pattern, &outverb, &action_flags,
++                       &arg_symbol, &image_name );
++
++        /*	Get the original command line from the foreign command utility.
++        */
++
++        length = 0;					/* RTL only writes word */
++        lib$get_foreign(&command_arg_desc, 0, &length);
++        command_args[length] = 0;			/* add NULL terminator */
++
++        /*	Check to see if any of the exising arguments start with a "-"
++        	character.  if so, assume he's already using Unix style arguments so
++        	we don't have to do anything.  Only do this if the Unix_Arg bit is
++        	set in the action flags.
++        */
++
++        if ((action_flags & VARGACT_M_UNIXARG)) {
++                for (i = 1; i <= *argc - 1; i++)
++                        if ((*argv) [i][0] == '-') {
++                                /* He's using Unix style args. */
++                                if ((action_flags & VARGACT_M_RETURN)) {
++                                        return 1;		/* back out quietly	*/
++                                } else {
++                                        status = varg_do_exit(action_flags, arg_symbol, command_args,
++                                                          image_name, outverb);
++                                        sys$exit(status);	/* exit with DCL stuff done  */
++                                }
++                        }
++        }
++
++        /*	Catenate verb and arguments into the command string for DCL
++        	to parse.
++        */
++
++        strcpy(command, verb);
++        strcat(command, command_args);
++        command_desc.dsc$w_length = strlen(verb) + strlen(command_args);
++
++        /*	Pass it to the DCL parser for its approval.
++        */
++
++        status = cli$dcl_parse(&command_desc, &VARG_CLD);
++        if ((status & 1) != 1) sys$exit (status);
++
++        /*	Now that DCL is happy, we go through all the defined VMS qualifiers
++        	and parameters to check if they are present or defaulted.
++        */
++
++        arg_count = 0;		/* so far so good */
++
++        for (i = 1; i <= nvargs; i++) {
++
++                /*	Set The various flags for this qualifier.
++                */
++
++                affirm_flag = (VARG_M_AFFIRM & flags[i]) != 0;
++                negative_flag = (VARG_M_NEGATIVE & flags[i]) != 0;
++                keywords_flag = (VARG_M_KEYWORDS & flags[i]) != 0;
++                separator_flag = (VARG_M_SEPARATOR & flags[i]) != 0;
++                date_flag = (VARG_M_DATE & flags[i]) != 0;
++                append_flag = (VARG_M_APPEND & flags[i]) != 0;
++                help_flag = (VARG_M_HELP & flags[i]) != 0;
++
++                /*	Check if the qualifier or parameter is present
++                */
++
++                qual_desc.dsc$w_length = strlen(vms_arg[i]);
++                qual_desc.dsc$a_pointer = vms_arg[i];
++                present = cli$present(&qual_desc) & 1;
++
++                /*	if the qualifier is present, and there is a positive translation,
++                	then replace the VMS qualifier by its Unix equivalent.  Note that
++                	if the Unix equivalent starts with a '$', then it is a parameter and
++                	we omit the qualifier name, only putting in the value.
++                */
++
++                qual_template[0] = 0;			/* zero string initially */
++
++                if (present && affirm_flag) {
++                        if (unix_arg[i][0] != '$') strcpy(qual_template, unix_arg[i]);
++                }
++
++                if (!(present & 1) && negative_flag)		/* NOT present AND
++						   negative_flag */
++                {
++                        strcpy(qual_template, unix_narg[i]);
++                }
++
++                /*	Get the first value (if any).  We may have to catenate this with the
++                	qualifier keyword, or build up multiple values in a single argv
++                	element.
++                */
++
++                if (present) {
++                        value_desc.dsc$w_length = QUAL_LENGTH;
++                        status = cli$get_value(&qual_desc, &value_desc, &length);
++                        if ((status & 1) != 1) length = 0;
++                        value[length] = 0;			/* NULL terminator */
++                        more_flag = status == CLI$_COMMA;
++                } else {
++                        length = 0;
++                }
++
++                /*	if the /APPEND qualifier was used, then the qualifier and its value
++                	are in the same argv element.
++                */
++
++                if (append_flag) {
++                        strcpy(value_template, qual_template);
++                } else {
++                        /*	Allocate a fresh argv element and load the Unix keyword into it.
++                        */
++                        q_length = strlen(qual_template);
++
++                        if (q_length != 0) {
++                                Increment(arg_count);
++                                newargv[arg_count] = malloc(q_length + 1);
++                                if (newargv[arg_count] == NULL) sys$exit(LIB$_INSVIRMEM);
++                                strcpy(newargv[arg_count], qual_template);
++                        }
++                }
++
++                multivalue = more_flag;
++
++                /*	Get all the various values and either append them with appropriate
++                	separators to the current template, or load them in successive argv
++                	elements.
++                */
++
++                while (affirm_flag && (length != 0)) {
++
++                        /*	if a keyword list is involved, get the corresponding field from the
++                        	Unix equivalent.
++                        */
++
++                        if (keywords_flag) {
++                                index = varg_get_index(value, vms_key[i]);
++                                varg_set_index(value, unix_key[i], index);
++                        }
++
++                        /*	if the /DATE qualifier was present, we interpret the value as a
++                        	VMS date/time specification, and convert it to the equivalent Unix
++                        	type string.
++                        */
++
++                        if (date_flag) varg_convert_date(value, pattern[i]);
++
++                        /*	Add the current value to the template so far.  Add a separator
++                        	character if we need one.
++                        */
++
++                        strcat(value_template, value);
++
++                        if (separator_flag) {
++                                if (more_flag)
++                                        strcat(value_template, separator[i]);
++                        } else {
++
++                                /*	Each value should have its own argv element.
++                                */
++
++                                Increment(arg_count);
++                                newargv[arg_count] = malloc(strlen(value_template) + 1);
++                                if (newargv[arg_count] == NULL) sys$exit(LIB$_INSVIRMEM);
++                                strcpy(newargv[arg_count], value_template);
++                                value_template[0] = 0;
++                        }
++
++                        /*	Get the next value from the DCL parser.
++                        */
++
++                        value_desc.dsc$w_length = QUAL_LENGTH;		/* reset string */
++                        status = cli$get_value(&qual_desc, &value_desc, &length);
++                        if ((status & 1) != 1) length = 0;
++                        value[length] = 0;
++                        more_flag = status == CLI$_COMMA;
++                }
++
++                /*	All the values are in for this qualifier - if there were being stacked
++                	up then load them all into an argv element.
++                */
++
++                if (separator_flag & multivalue) {
++                        Increment(arg_count);
++                        newargv[arg_count] = malloc(strlen(value_template) + 1);
++                        if (newargv[arg_count] == NULL) sys$exit(LIB$_INSVIRMEM);
++                        strcpy(newargv[arg_count], value_template);
++                        value_template[0] = 0;
++                }
++
++                /*	Check to see if this is a HELP directive.  if so, then the help
++                	library name is stored in pattern[i] and the initial help string
++                	in unix_arg[i]
++                */
++
++                if ((present &1) && help_flag) {
++                        varg_do_help(pattern[i], unix_arg[i]);
++                }
++
++                /*	And around for the next qualifier.
++                */
++
++        }
++
++        /*	We've built the argument vector.  Now lets find out what we're
++        	supposed to do with it.
++        */
++
++        if ((action_flags & VARGACT_M_RETURN)) {
++
++                /*	We should return the result to the caller. Set the corresponding argc
++                	& argv variables in the caller to point at these.  Make sure the new
++                	argv contains the same [0] element as the old one (program name).
++                */
++
++                *argc = arg_count + 1;
++                newargv[0] = (*argv)[0];
++                *argv = newargv;
++                return 1;
++        }
++
++        /*	We must convert the argv elements into an arg string.
++        */
++
++        arg_string[0] = 0;
++        special_chars = default_special;
++
++        for (i = 1; i <= arg_count; i++) {
++                varg_protect_string(newargv[i], arg_element, action_flags,
++                                special_chars);
++                strcat(arg_string, arg_element);
++                if (i != arg_count) strcat(arg_string, " ");
++        }
++
++        status = varg_do_exit(action_flags, arg_symbol, arg_string, image_name, outverb);
++
++        /*	if we got this far then exit to DCL.
++        */
++
++        sys$exit(status);
++}
++
++/*****************************************************************************|
++|	Routine to scan the string 'string' to see if it matches any of       |
++|	the fields in 'keywords' (fields delimited by "|" characters). if     |
++|	so, return the field number (1=first).  if it doesn't match, return   |
++|	0.                                                                    |
++\*****************************************************************************/
++
++static int varg_get_index(char *string, char *keywords)
++{
++        int i;
++        char temp[S_LENGTH];
++        char *field;
++
++        i = 0;
++        strcpy(temp, keywords);		/* don't muck up caller's string.  */
++
++        /*	Get successive fields using STRTOK function and compare.
++        */
++
++        field = strtok(temp, "|");
++
++        while (field != NULL) {
++                i = i + 1;
++                if (strcmp(field, string) == 0) return i;
++                field = strtok(NULL, "|");
++        }
++
++        return 0;
++}
++
++/*****************************************************************************|
++|	Routine to return the 'index' numbered field of 'keywords' in         |
++|	'string'.  Keywords are delimited by "|" characters.  if 'index'      |
++|	is 0 do nothing.                                                      |
++\*****************************************************************************/
++
++static int varg_set_index(char *string, char *keywords, int index)
++{
++        int i;
++        char temp[S_LENGTH];
++        char *field;
++
++        if (index == 0) return 1;
++        strcpy(temp, keywords);		/* don't screw up caller's string. */
++        field = strtok(temp, "|");
++
++        for (i = 1; i <= index - 1; i++) {
++                field = strtok(NULL, "|");
++        }
++
++        strcpy(string, field);
++        return 1;
++}
++
++/*****************************************************************************|
++|	Invoke a help dialog with the user using the supplied help library    |
++|	and initial help command.                                             |
++\*****************************************************************************/
++
++static int varg_do_help(char *help_library, char *help_command)
++{
++        $DESCRIPTOR(lib_desc, "");
++        $DESCRIPTOR(command_desc, "");
++        int status;
++
++        lib_desc.dsc$w_length = strlen(help_library);
++        lib_desc.dsc$a_pointer = help_library;
++        command_desc.dsc$w_length = strlen(help_command);
++        command_desc.dsc$a_pointer = help_command;
++
++        status = lbr$output_help(&lib$put_output, 0, &command_desc, &lib_desc, 0,
++                                 &lib$get_input);
++        return status;
++}
++
++/*****************************************************************************|
++|	Routine to create a DCL symbol called 'symbol' with value 'value'.    |
++\*****************************************************************************/
++
++static int varg_set_symbol(char *symbol, char *value)
++{
++        $DESCRIPTOR(symbol_desc, "");
++        $DESCRIPTOR(value_desc, "");
++        int status;
++
++        symbol_desc.dsc$w_length = strlen(symbol);
++        symbol_desc.dsc$a_pointer = symbol;
++        value_desc.dsc$w_length = strlen(value);
++        value_desc.dsc$a_pointer = value;
++        status = lib$set_symbol(&symbol_desc, &value_desc);
++        return status;
++}
++
++/*****************************************************************************|
++|	Routine to exit the program and pass 'command' to DCL for execution.  |
++\*****************************************************************************/
++
++static int varg_do_command(char *command)
++{
++        $DESCRIPTOR(command_desc, "");
++        int status;
++
++        command_desc.dsc$w_length = strlen(command);
++        command_desc.dsc$a_pointer = command;
++        status = lib$do_command(&command_desc);
++        return status;
++}
++
++/*****************************************************************************|
++|	Routine to rebuild 'date_string' converting from a VMS standard       |
++|	date/time specifier to the Unix format specified in 'pattern'.        |
++|                                                                             |
++\*****************************************************************************/
++
++static int varg_convert_date(char *date_string, char *pattern)
++{
++        char date_text[30];
++        int bin_time[2], flags, length, status, i, from, to;
++        char year_4[5], year_2[4], month_name[4];
++        char month_2[2], month_1[2], date_2[3], date_1[2];
++        char hour_2[3], hour_1[2], minute[3], second[3];
++        char *months[] = {"", "Jan", "Feb", "Mar", "Apr", "May", "Jun",
++                          "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
++                         };
++        $DESCRIPTOR(date_desc, "");
++        static int context;
++
++
++        /*	First convert the date string into internal VMS format
++        */
++
++        date_desc.dsc$w_length = strlen(date_string);
++        date_desc.dsc$a_pointer = date_string;
++        context = 0;
++        flags = 0X7F;
++        status = lib$convert_date_string(&date_desc, &bin_time, &context, &flags);
++        if ((status & 1) != 1) return status;
++
++        /*	Now convert it back to string form.  This ensures that delta times
++        	and keywords like TODAY get translated into a consistent format.
++        */
++
++        date_desc.dsc$w_length = 30;
++        /* date_desc.dsc$a_pointer = &date_text;*/
++        date_desc.dsc$a_pointer = date_text;
++        length = 0;
++        status = sys$asctim(&length, &date_desc, &bin_time, 0);
++        if ((status & 1) != 1) return status;
++
++        date_text[length] = 0;		/* add NULL terminator */
++        date_string[0] = 0;			/* start with empty string */
++
++        /*	Break the date/time string up into the constituent fields.  Fields
++        	such as date have two instances - one with leading zero and one without
++        	e.g. "05" and "5".
++        */
++
++        if (date_text[0] == ' ') {
++                date_2[0] = '0';
++                date_2[1] = date_text[1];
++                date_2[2] = 0;
++                date_1[0] = date_text[1];
++                date_1[1] = 0;
++        } else {
++                date_2[0] = date_text[0];
++                date_2[1] = date_text[1];
++                date_2[2] = 0;
++                strcpy(date_1, date_2);
++        }
++
++        /*	Extract the month name and lowercase the 2nd and 3rd characters.
++        */
++
++        month_name[0] = date_text [3];
++        month_name[1] = tolower(date_text [4]);
++        month_name[2] = tolower(date_text [5]);
++        month_name[3] = 0;
++
++        /*	Calculate the month number by looking up the month name in a
++        	character array.
++        */
++
++        for (i = 1; i <= 12; i++) {
++                if (strcmp(month_name, months[i]) == 0) {
++                        sprintf(month_2, "%02d", i);
++                        sprintf(month_1, "%d", i);
++                        break;
++                }
++        }
++
++        /*	Extract the year field (both 4 digit and 2 digit forms).
++        */
++
++        year_2[0] = date_text[9];
++        year_2[1] = date_text[10];
++        year_2[3] = 0;
++
++        for (i = 0; i <= 3; i++) {
++                year_4[i] = date_text[i+7];
++        }
++
++        year_4[4] = 0;
++
++        /*	Extract hour field.
++        */
++
++        hour_2[0] = date_text[12];
++        hour_2[1] = date_text[13];
++        hour_2[2] = 0;
++
++        if (date_text[12] == '0') {
++                hour_1[0] = date_text[13];
++                hour_1[1] = 0;
++        } else strcpy(hour_1, hour_2);
++
++        /*	Lastly copy the minutes and seconds.
++        */
++
++        for (i = 0; i <= 1; i++) {
++                minute[i] = date_text[i+15];
++                second[i] = date_text[i+18];
++        }
++
++        minute[2] = 0;
++        second[2] = 0;
++
++        /*	Now start building up the output string by copying characters from
++        	'pattern' to 'date_string' substituting the various fields when we
++        	encounter an escape pair.
++        */
++
++        from = 0;
++        to = 0;
++
++        while (pattern[from] != 0) {
++                if (pattern[from] == '$') {
++                        switch (pattern[from+1]) {
++                        case 'Y':
++                                strcat(date_string, year_4);
++                                to = to + 4;
++                                break;
++
++                        case 'y':
++                                strcat(date_string, year_2);
++                                to = to + 2;
++                                break;
++
++                        case 'M':
++                                strcat(date_string, month_name);
++                                to = to + 3;
++                                break;
++
++                        case 'N':
++                                strcat(date_string, month_2);
++                                to = to + 2;
++                                break;
++
++                        case 'n':
++                                strcat(date_string, month_1);
++                                to = to + strlen(month_1);
++                                break;
++
++                        case 'D':
++                                strcat(date_string, date_2);
++                                to = to + 2;
++                                break;
++
++                        case 'd':
++                                strcat(date_string, date_1);
++                                to = to + strlen(date_1);
++                                break;
++
++                        case 'H':
++                                strcat(date_string, hour_2);
++                                to = to + 2;
++                                break;
++
++                        case 'h':
++                                strcat(date_string, hour_1);
++                                to = to + strlen(hour_1);
++                                break;
++
++                        case 'm':
++                                strcat(date_string, minute);
++                                to = to + 2;
++                                break;
++
++                        case 'S':
++                        case 's':
++                                strcat(date_string, second);
++                                to = to + 2;
++                                break;
++
++                        case '$':
++                                date_string[to] = '$';
++                                date_string[to+1] = 0;
++                                to = to + 1;
++                                break;
++                        }
++
++                        from = from + 2;
++                } else {
++                        date_string[to] = pattern[from];
++                        date_string[to+1] = 0;
++                        from = from + 1;
++                        to = to + 1;
++                }
++        }
++}
++
++/*****************************************************************************|
++|	Routine to decide if a string requires to be enclosed in quotation    |
++|	marks, and if so, put them in.  The various bits in 'flags' tells     |
++|	us what characters require protecting.  'Quote' contains the actual   |
++|	quote character (which may require doubling or escaping with "\"      |
++|	if it occurs in the string).  'Special' contains a list of characters |
++|	which require protecting.                                             |
++\*****************************************************************************/
++
++static int varg_protect_string(char *instring, char *outstring,
++                           int flags, char *special)
++{
++        int protection_needed, quote_present;
++        int length, i, j, special_length;
++        char ch, quote = '\"';
++        char quote_string[1];
++
++        quote_string[0] = quote;
++        quote_string[1] = 0;
++        length = strlen(instring);
++        special_length = strlen(special);
++        protection_needed = 0;
++        quote_present = 0;
++
++        /*	Check to see if we actually need the quotes.
++        */
++
++        if ((flags & VARGACT_M_PROTMASK) != 0) {
++                for (i = 0; i <= length-1; i++) {
++                        ch = instring[i];
++
++                        if ((flags & VARGACT_M_UPPER) && isupper (ch)) {
++                                protection_needed = 1;
++                                continue;
++                        }
++
++                        if ((flags & VARGACT_M_LOWER) && islower (ch)) {
++                                protection_needed = 1;
++                                continue;
++                        }
++
++                        if ((flags & VARGACT_M_SPECIAL)) {
++                                for (j = 0; j <= special_length-1; j++) {
++                                        if (ch == special[j]) {
++                                                protection_needed = 1;
++                                                continue;
++                                        }
++                                }
++
++                                if (protection_needed) continue;
++                        }
++
++                        if (((flags & VARGACT_M_ESCAPE) ||
++                             (flags & VARGACT_M_DOUBLE)) &&
++                            ch == quote) {
++                                protection_needed = 1;
++                                quote_present = 1;
++                                continue;
++                        }
++                }
++        }
++
++        /*	if protection is not needed, just copy the input string to the
++        	output string.
++        */
++
++        if (!protection_needed) {
++                strcpy(outstring, instring);
++                return 1;
++        }
++
++        /*	Protection is needed.  if no quotes are present, then we simply
++        	enclose the string in quote marks, otherwise we have to step through
++        	the string.
++        */
++
++        if (quote_present) {
++                outstring[0] = quote;
++                j = 1;
++
++                for (i = 0; i <= length-1; i++) {
++                        ch = instring[i];
++
++                        if (ch == quote) {
++                                if ((flags & VARGACT_M_ESCAPE)) {
++                                        outstring[j] = '\\';
++                                        j = j + 1;
++                                }
++
++                                if ((flags & VARGACT_M_DOUBLE)) {
++                                        outstring[j] = quote;
++                                        j = j + 1;
++                                }
++                        }
++
++                        outstring[j] = ch;
++                        j = j + 1;
++                }
++
++                outstring[j] = 0;
++        } else {			/* just append the output string + quote */
++                outstring[0] = 0;
++                strcat(outstring, quote_string);
++                strcat(outstring, instring);
++                strcat(outstring, quote_string);
++        }
++
++        return 1;
++}
++
++/*****************************************************************************|
++|	Routine to define any DCL symbols that are required, and if the       |
++|	appropriate flag bit is set, exit to DCL using a LIB$DO_COMMAND call  |
++|	which will activate the real application image.                       |
++\*****************************************************************************/
++
++static int varg_do_exit(int flags, char *arg_symbol,
++                    char *arg_string, char *image_name, char *verb)
++{
++        char *foreign_image;
++        char *command;
++        int status;
++
++        /*	Should we set up a symbol containing this arg string ?
++        */
++
++        if ((flags & VARGACT_M_SYMBOL))
++                varg_set_symbol(arg_symbol, arg_string);
++
++        /*	Should we define an image name in the verb symbol ?
++        */
++
++        if ((flags & VARGACT_M_IMAGE)) {
++                foreign_image = malloc(strlen(image_name) + 2);
++                if (foreign_image == NULL) return LIB$_INSVIRMEM;
++                strcpy(foreign_image, "$");
++                strcat(foreign_image, image_name);
++                varg_set_symbol(verb, foreign_image);
++        }
++
++        /*	Should we exit the program and and activate another image or
++        	command procedure ?
++        */
++
++        if ((flags & VARGACT_M_COMMAND)) {
++                command = malloc(strlen(verb) + strlen(arg_string) + 2);
++                if (command == NULL) return LIB$_INSVIRMEM;
++                strcpy(command, verb);
++                strcat(command, " ");
++                strcat(command, arg_string);
++                status = varg_do_command(command);
++                return status;
++        }
++
++        return 1;
++}
+
+commit c48e0ee41c990cc7400db8ae808076af67906e5d
+Author: berryc <berryc>
+Date:   Sat Jun 26 23:58:43 2010 +0000
+
+    *** empty log message ***
+
+diff --git a/ChangeLog b/ChangeLog
+index 6a53999..1ad5c9c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,12 @@
++Sat Jun 26 19:50:00 CEST 2010   Craig A. Berry <craigberry@mac.com>
++	* Makefile.am, src/apps/defncopy.c, src/apps/fisql/fisql.c,
++	* src/apps/freebcp.c, vms/Makefile.am, vms/config_h.vms,
++	* vms/descrip_mms.template, vms/vargdefs.h, vms/vmsarg_command_bcp.cld,
++	* vms/vmsarg_command_defncopy.cld, vms/vmsarg_command_isql.cld,
++	* vms/vmsarg_mapping_bcp.c, ms/vmsarg_mapping_defncopy.c,
++	* vms/vmsarg_mapping_isql.c, vms/vmsarg_parse.c
++	- VMS-style native command syntax for fisql, freebcp, and defncopy
++
+ Sat Jun 26 11:14:37 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/token.c: fix a leak if cursor returns multiple resultsets
+ 
+@@ -2503,4 +2512,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3038 2010/06/26 09:14:49 freddy77 Exp $
++$Id: ChangeLog,v 1.3039 2010/06/26 23:58:43 berryc Exp $
+
+commit a66d9e0a3c2ef0357a6321703e5610cd68dcd287
+Author: freddy77 <freddy77>
+Date:   Sun Jun 27 05:58:09 2010 +0000
+
+    honour vms/Makefile.am removing duplications
+
+diff --git a/ChangeLog b/ChangeLog
+index 1ad5c9c..4f18b67 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Jun 27 07:58:00 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* Makefile.am configure.ac:
++	- honour vms/Makefile.am removing duplications
++
+ Sat Jun 26 19:50:00 CEST 2010   Craig A. Berry <craigberry@mac.com>
+ 	* Makefile.am, src/apps/defncopy.c, src/apps/fisql/fisql.c,
+ 	* src/apps/freebcp.c, vms/Makefile.am, vms/config_h.vms,
+@@ -2512,4 +2516,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3039 2010/06/26 23:58:43 berryc Exp $
++$Id: ChangeLog,v 1.3040 2010/06/27 05:58:09 freddy77 Exp $
+diff --git a/Makefile.am b/Makefile.am
+index e9268f1..c078a63 100644
+--- a/Makefile.am
++++ b/Makefile.am
+@@ -1,32 +1,13 @@
+-# version $Id: Makefile.am,v 1.48 2010/06/26 23:47:01 berryc Exp $
++# version $Id: Makefile.am,v 1.49 2010/06/27 05:58:09 freddy77 Exp $
+ 
+ ## SUBDIRS determines in which directories automake will generate a Makefile
+ ## See also AC_OUTPUT in configure.ac
+ 
+-SUBDIRS	=	include src doc samples win32
++SUBDIRS	=	include src doc samples win32 vms
+ 
+ ACLOCAL_AMFLAGS = -I m4
+ 
+-VMS	=	vms/config_h.vms \
+-		vms/configure.com \
+-		vms/edit.c \
+-		vms/descrip_mms.template \
+-		vms/getpass.c \
+-		vms/libodbc.opt \
+-		vms/Makefile.am \
+-		vms/odbc_driver_axp.opt \
+-		vms/README.vms \
+-		vms/vargdefs.h \
+-		vms/vmsarg_command_bcp.cld \
+-		vms/vmsarg_command_defncopy.cld \
+-		vms/vmsarg_command_isql.cld \
+-		vms/vmsarg_mapping_bcp.c \
+-		vms/vmsarg_mapping_defncopy.c \
+-		vms/vmsarg_mapping_isql.c \
+-		vms/vmsarg_parse.c
+-
+-
+-EXTRA_DIST = 	$(VMS) interfaces PWD.in BUGS \
++EXTRA_DIST = 	interfaces PWD.in BUGS \
+ 		freetds.conf locales.conf \
+ 		autogen.sh freetds.spec.in freetds.spec tds.dox \
+ 		config.rpath Nmakefile FreeTDS.sln
+diff --git a/configure.ac b/configure.ac
+index 45f3f12..07d133f 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.48 2010/05/13 22:06:38 freddy77 Exp $
++dnl $Id: configure.ac,v 1.49 2010/06/27 05:58:09 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.48 $)
++AC_REVISION($Revision: 1.49 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -817,6 +817,7 @@ AC_CONFIG_FILES(include/tdsver.h \
+ 	src/apps/fisql/Makefile \
+ 	freetds.spec \
+ 	win32/Makefile win32/msvc6/Makefile \
+-	win32/version.rc win32/freetds.nsh
++	win32/version.rc win32/freetds.nsh \
++	vms/Makefile
+ )
+ AC_OUTPUT
+
+commit a365255bbaa9353e8c0299b75492bb51b3a507fe
+Author: berryc <berryc>
+Date:   Sun Jun 27 17:46:42 2010 +0000
+
+    consolidated locale/client charset update
+
+diff --git a/ChangeLog b/ChangeLog
+index 4f18b67..7d1ce87 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,8 +1,13 @@
++Sun Jun 27 12:40:00 CDT 2010	Craig A. Berry <craigberry@mac.com>
++	* include/tds.h src/apps/tsql.c src/tds/iconv.c src/tds/locale.c
++	* src/tds/mem.c:
++	- consolidated locale/client charset update
++
+ Sun Jun 27 07:58:00 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* Makefile.am configure.ac:
+ 	- honour vms/Makefile.am removing duplications
+ 
+-Sat Jun 26 19:50:00 CEST 2010   Craig A. Berry <craigberry@mac.com>
++Sat Jun 26 19:50:00 CDT 2010   Craig A. Berry <craigberry@mac.com>
+ 	* Makefile.am, src/apps/defncopy.c, src/apps/fisql/fisql.c,
+ 	* src/apps/freebcp.c, vms/Makefile.am, vms/config_h.vms,
+ 	* vms/descrip_mms.template, vms/vargdefs.h, vms/vmsarg_command_bcp.cld,
+@@ -2516,4 +2521,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3040 2010/06/27 05:58:09 freddy77 Exp $
++$Id: ChangeLog,v 1.3041 2010/06/27 17:46:42 berryc Exp $
+diff --git a/include/tds.h b/include/tds.h
+index c148806..ebedc0f 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.336 2010/06/19 09:51:36 freddy77 Exp $ */
++/* $Id: tds.h,v 1.337 2010/06/27 17:46:43 berryc Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -908,7 +908,6 @@ typedef struct tds_locale
+ {
+ 	char *language;
+ 	char *server_charset;
+-	char *client_charset;
+ 	char *date_fmt;
+ } TDSLOCALE;
+ 
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 26574fb..95c9b79 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -87,7 +87,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.133 2010/04/08 08:19:16 freddy77 Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.134 2010/06/27 17:46:43 berryc Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -297,7 +297,8 @@ static void
+ tsql_print_usage(const char *progname)
+ {
+ 	fprintf(stderr,
+-		"Usage:\t%s [-S <server> | -H <hostname> -p <port>] -U <username> [-P <password>] [-I <config file>] [-o <options>] [-t delim] [-r delim] [-D database]\n"
++		"Usage:\t%s [-S <server> | -H <hostname> -p <port>] -U <username> [-P <password>]\n"
++		"\t\t[-I <config file>] [-J <client charset>] [-o <options>] [-t delim] [-r delim] [-D database]\n"
+ 		"\t%s -C\n"
+ 		"Options:\n"
+ 		"\tf\tDo not print footer\n"
+@@ -402,23 +403,10 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 	char *confile = NULL;
+ 	int port = 0;
+ 	int opt;
+-	const char *locale = NULL;
+ 	const char *charset = NULL;
+ 	char *opt_flags_str = NULL;
+ 
+-	setlocale(LC_ALL, "");
+-	locale = setlocale(LC_ALL, NULL);
+-
+-#if HAVE_LOCALE_CHARSET
+-	charset = locale_charset();
+-#endif
+-#if HAVE_NL_LANGINFO && defined(CODESET)
+-	if (!charset)
+-		charset = nl_langinfo(CODESET);
+-#endif
+-
+-
+-	while ((opt = getopt(argc, argv, "H:S:I:P:U:p:Co:t:r:D:Lv")) != -1) {
++	while ((opt = getopt(argc, argv, "H:S:I:J:P:U:p:Co:t:r:D:Lv")) != -1) {
+ 		switch (opt) {
+ 		case 't':
+ 			opt_col_term = strdup(optarg);
+@@ -452,6 +440,9 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 			free(confile);
+ 			confile = strdup(optarg);
+ 			break;
++		case 'J':
++			charset = strdup(optarg);
++			break;
+ 		case 'p':
+ 			port = atoi(optarg);
+ 			break;
+@@ -495,16 +486,6 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		}
+ 	}
+ 
+-
+-	if (locale)
+-		if (!QUIET) printf("locale is \"%s\"\n", locale);
+-	if (charset) {
+-		if (!QUIET) printf("locale charset is \"%s\"\n", charset);
+-	} else {
+-		charset = "ISO-8859-1";
+-		if (!QUIET) printf("using default charset \"%s\"\n", charset);
+-	}
+-	
+ 	if ((global_opt_flags & OPT_INSTANCES) && hostname) {
+ 		static const char template[] = "%s.instances";
+ 		char ip[24] = {'\0'};
+@@ -582,7 +563,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		tds_set_app(login, "TSQL");
+ 		tds_set_library(login, "TDS-Library");
+ 		tds_set_server(login, servername);
+-		tds_set_client_charset(login, charset);
++		if (charset) tds_set_client_charset(login, charset);
+ 		tds_set_language(login, "us_english");
+ 		tds_set_passwd(login, password);
+ 		if (confile) {
+@@ -595,7 +576,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		tds_set_library(login, "TDS-Library");
+ 		tds_set_server(login, hostname);
+ 		tds_set_port(login, port);
+-		tds_set_client_charset(login, charset);
++		if (charset) tds_set_client_charset(login, charset);
+ 		tds_set_language(login, "us_english");
+ 		tds_set_passwd(login, password);
+ 	}
+@@ -681,6 +662,8 @@ main(int argc, char **argv)
+ 	pid_t timer_pid = 0;
+ 	int pipes[2];
+ #endif
++	const char *locale = NULL;
++	const char *charset = NULL;
+ 
+ 	istty = isatty(0);
+ 
+@@ -710,6 +693,32 @@ main(int argc, char **argv)
+ 	tds_set_parent(tds, NULL);
+ 	connection = tds_read_config_info(tds, login, context->locale);
+ 
++	setlocale(LC_ALL, "");
++	locale = setlocale(LC_ALL, NULL);
++
++#if HAVE_LOCALE_CHARSET
++	charset = locale_charset();
++#endif
++#if HAVE_NL_LANGINFO && defined(CODESET)
++	if (!charset)
++		charset = nl_langinfo(CODESET);
++#endif
++
++	if (locale)
++		if (!QUIET) printf("locale is \"%s\"\n", locale);
++	if (charset) {
++		if (!QUIET) printf("locale charset is \"%s\"\n", charset);
++	}
++	
++	if (tds_dstr_isempty(&connection->client_charset)) {
++		if (!charset)
++			charset = "ISO-8859-1";
++
++		tds_set_client_charset(login, charset);
++		tds_dstr_dup(&connection->client_charset, &login->client_charset);
++	}
++	if (!QUIET) printf("using default charset \"%s\"\n", tds_dstr_cstr(&connection->client_charset));
++
+ 	if (opt_default_db) {
+ 		tds_dstr_copy(&connection->database, opt_default_db);
+ 		if (!QUIET) fprintf(stderr, "Default database being set to %s\n", opt_default_db);
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index ff53b8a..2825f0d 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.143 2010/02/08 12:16:43 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.144 2010/06/27 17:46:43 berryc Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -440,12 +440,12 @@ tds_iconv_info_init(TDSICONV * char_conv, const char *client_name, const char *s
+ 	server_canonical = tds_canonical_charset(server_name);
+ 
+ 	if (client_canonical < 0) {
+-		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: client charset name \"%s\" unrecognized\n", client->name);
++		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: client charset name \"%s\" unrecognized\n", client_name);
+ 		return 0;
+ 	}
+ 
+ 	if (server_canonical < 0) {
+-		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: server charset name \"%s\" unrecognized\n", client->name);
++		tdsdump_log(TDS_DBG_FUNC, "tds_iconv_info_init: server charset name \"%s\" unrecognized\n", server_name);
+ 		return 0;
+ 	}
+ 
+diff --git a/src/tds/locale.c b/src/tds/locale.c
+index a42ca8e..8190f36 100644
+--- a/src/tds/locale.c
++++ b/src/tds/locale.c
+@@ -22,6 +22,10 @@
+ #include <config.h>
+ #endif
+ 
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include <stdarg.h>
+ #include <stdio.h>
+ #include <ctype.h>
+@@ -41,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: locale.c,v 1.28 2007/10/16 15:12:22 freddy77 Exp $");
++TDS_RCSID(var, "$Id: locale.c,v 1.29 2010/06/27 17:46:43 berryc Exp $");
+ 
+ 
+ static void tds_parse_locale(const char *option, const char *value, void *param);
+@@ -68,12 +72,16 @@ tds_get_locale(void)
+ 	if (in) {
+ 		tds_read_conf_section(in, "default", tds_parse_locale, locale);
+ 
++#if HAVE_LOCALE_H
++		setlocale(LC_ALL, "");
++		s = setlocale(LC_ALL, NULL);
++#else
+ 		s = getenv("LANG");
++#endif
+ 		if (s && s[0]) {
+ 			int found;
+ 			char buf[128];
+ 			const char *strip = "@._";
+-			const char *charset = NULL;
+ 
+ 			/* do not change environment !!! */
+ 			tds_strlcpy(buf, s, sizeof(buf));
+@@ -96,19 +104,13 @@ tds_get_locale(void)
+ 				if (!s)
+ 					continue;
+ 				*s = 0;
+-				if (*strip == '.')
+-					charset = s+1;
+ 				rewind(in);
+ 				found = tds_read_conf_section(in, buf, tds_parse_locale, locale);
+ 			}
+ 
+-			/* charset specified in LANG ?? */
+-			if (charset) {
+-				free(locale->client_charset);
+-				locale->client_charset = strdup(charset);
+-			}
+ 		}
+ 
++
+ 		fclose(in);
+ 	}
+ 	return locale;
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 1977c19..4d2bdcd 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.198 2010/05/02 11:52:13 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.199 2010/06/27 17:46:43 berryc Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -690,35 +690,9 @@ TDSLOCALE *
+ tds_alloc_locale(void)
+ {
+ 	TDSLOCALE *locale;
+-#if !(HAVE_NL_LANGINFO && defined(CODESET))
+-	char *lc_all;
+-#endif
+ 
+ 	TEST_MALLOC(locale, TDSLOCALE);
+ 
+-#if HAVE_NL_LANGINFO && defined(CODESET)
+-	locale->client_charset = strdup(nl_langinfo(CODESET));
+-#else
+-	locale->client_charset = strdup("ISO-8859-1");
+-	if (!locale->client_charset)
+-		goto Cleanup;
+-
+-	if ((lc_all = strdup(setlocale(LC_ALL, NULL))) == NULL)
+-		goto Cleanup;
+-
+-	if (strtok(lc_all, ".")) {
+-		char *encoding = strtok(NULL, "@");
+-		if (encoding) {
+-			free(locale->client_charset);
+-			locale->client_charset = strdup(encoding);
+-		}
+-	}
+-	free(lc_all);
+-#endif
+-	if (!locale->client_charset)
+-		goto Cleanup;
+-	tdsdump_log(TDS_DBG_FUNC, "tds_alloc_locale(): initialized locale to \"%s\"\n", locale->client_charset? locale->client_charset : "NULL");
+-
+ 	return locale;
+ 
+       Cleanup:
+@@ -832,6 +806,9 @@ tds_alloc_connection(TDSLOCALE * locale)
+ {
+ 	TDSCONNECTION *connection;
+ 	char hostname[128];
++#if !(HAVE_NL_LANGINFO && defined(CODESET))
++	char *lc_all;
++#endif
+ 
+ 	TEST_MALLOC(connection, TDSCONNECTION);
+ 	tds_dstr_init(&connection->server_name);
+@@ -854,9 +831,28 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 		goto Cleanup;
+ 	connection->tds_version = TDS_DEFAULT_VERSION;
+ 	connection->block_size = 0;
+-	/* TODO use system default ?? */
++
++	setlocale(LC_ALL, "");
++#if HAVE_NL_LANGINFO && defined(CODESET)
++	if (!tds_dstr_copy(&connection->client_charset, nl_langinfo(CODESET)))
++		goto Cleanup;;
++#else
+ 	if (!tds_dstr_copy(&connection->client_charset, "ISO-8859-1"))
+ 		goto Cleanup;
++
++	if ((lc_all = strdup(setlocale(LC_ALL, NULL))) == NULL)
++		goto Cleanup;
++
++	if (strtok(lc_all, ".")) {
++		char *encoding = strtok(NULL, "@");
++		if (encoding) {
++			if (!tds_dstr_copy(&connection->client_charset, encoding))
++				goto Cleanup;
++		}
++	}
++	free(lc_all);
++#endif
++
+ 	if (locale) {
+ 		if (locale->language)
+ 			if (!tds_dstr_copy(&connection->language, locale->language))
+@@ -1154,7 +1150,6 @@ tds_free_locale(TDSLOCALE * locale)
+ 	free(locale->language);
+ 	free(locale->server_charset);
+ 	free(locale->date_fmt);
+-	free(locale->client_charset);
+ 	free(locale);
+ }
+ 
+
+commit 0e10d6eb51c37b745f6105089dba7115c7e303da
+Author: berryc <berryc>
+Date:   Sun Jun 27 23:58:12 2010 +0000
+
+    Zero local password memory after setting internal structures.
+    idea from Christos Zoulas <christos@zoulas.com>
+
+diff --git a/ChangeLog b/ChangeLog
+index 7d1ce87..f03c98d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Sun Jun 27 18:51:00 CDT 2010	Craig A. Berry <craigberry@mac.com>
++	* src/apps/bsqldb.c src/apps/bsqlodbc.c src/apps/defncopy.c
++	* src/apps/fisql/fisql.c src/apps/freebcp.c src/apps/tsql.c
++	- Zero local password memory after setting internal structures.
++	- idea from Christos Zoulas <christos@zoulas.com>
++
+ Sun Jun 27 12:40:00 CDT 2010	Craig A. Berry <craigberry@mac.com>
+ 	* include/tds.h src/apps/tsql.c src/tds/iconv.c src/tds/locale.c
+ 	* src/tds/mem.c:
+@@ -2521,4 +2527,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3041 2010/06/27 17:46:42 berryc Exp $
++$Id: ChangeLog,v 1.3042 2010/06/27 23:58:12 berryc Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index 883470b..c59db09 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -49,7 +49,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.42 2010/05/21 15:18:49 freddy77 Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.43 2010/06/27 23:58:12 berryc Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -827,6 +827,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 		case 'P':
+ 			got_password = 1;
+ 			DBSETLPWD(login, optarg);
++			memset(optarg, 0, strlen(optarg));
+ 			break;
+ 		case 'S':
+ 			options->servername = strdup(optarg);
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index bac6bda..39a0744 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.14 2010/02/07 21:55:54 jklowden Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.15 2010/06/27 23:58:12 berryc Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -840,6 +840,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 			break;
+ 		case 'P':
+ 			login->password = strdup(optarg);
++			memset(optarg, 0, strlen(optarg));
+ 			break;
+ 		case 'S':
+ 			options->servername = strdup(optarg);
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 7cfda75..2d04824 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -87,7 +87,7 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.20 2010/06/26 23:47:02 berryc Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.21 2010/06/27 23:58:12 berryc Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -679,6 +679,7 @@ get_login(int argc, char *argv[], OPTIONS *options)
+ 			break;
+ 		case 'P':
+ 			DBSETLPWD(login, optarg);
++			memset(optarg, 0, strlen(optarg));
+ 			fdomain = FALSE;
+ 			break;
+ 		case 'S':
+diff --git a/src/apps/fisql/fisql.c b/src/apps/fisql/fisql.c
+index 8ba0189..3c2d0a9 100644
+--- a/src/apps/fisql/fisql.c
++++ b/src/apps/fisql/fisql.c
+@@ -450,6 +450,8 @@ main(int argc, char *argv[])
+ 		DBSETLUSER(login, username);
+ 	}
+ 	DBSETLPWD(login, password);
++	memset(password, 0, strlen(password));
++
+ 	if (char_set) {
+ 		DBSETLCHARSET(login, char_set);
+ 	}
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 84c0965..7942cab 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -50,7 +50,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.54 2010/06/26 23:47:02 berryc Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.55 2010/06/27 23:58:12 berryc Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -268,8 +268,10 @@ process_parameters(int argc, char **argv, BCPPARAMDATA *pdata)
+ 				nl = strchr(pwd, '\n');
+ 				if(nl) *nl = '\0';
+ 				pdata->pass = strdup(pwd);
++				memset(pwd, 0, 255);
+ 			} else {
+ 				pdata->pass = strdup(optarg);
++				memset(optarg, 0, strlen(optarg));
+ 			}
+ 			break;
+ 		case 'i':
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 95c9b79..543bff4 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -87,7 +87,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.134 2010/06/27 17:46:43 berryc Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.135 2010/06/27 23:58:12 berryc Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -435,6 +435,7 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		case 'P':
+ 			free(password);
+ 			password = strdup(optarg);
++			memset(optarg, 0, strlen(optarg));
+ 			break;
+ 		case 'I':
+ 			free(confile);
+@@ -581,6 +582,8 @@ populate_login(TDSLOGIN * login, int argc, char **argv)
+ 		tds_set_passwd(login, password);
+ 	}
+ 
++	memset(password, 0, strlen(password));
++
+ 	/* free up all the memory */
+ 	free(confile);
+ 	free(hostname);
+
+commit 0a4825deda7b1fdd42f3cc98c63973997414318c
+Author: freddy77 <freddy77>
+Date:   Mon Jun 28 19:51:11 2010 +0000
+
+    fix small and quite impossible leak
+
+diff --git a/ChangeLog b/ChangeLog
+index f03c98d..ce2baf0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jun 28 21:51:02 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix small and quite impossible leak
++
+ Sun Jun 27 18:51:00 CDT 2010	Craig A. Berry <craigberry@mac.com>
+ 	* src/apps/bsqldb.c src/apps/bsqlodbc.c src/apps/defncopy.c
+ 	* src/apps/fisql/fisql.c src/apps/freebcp.c src/apps/tsql.c
+@@ -2527,4 +2530,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3042 2010/06/27 23:58:12 berryc Exp $
++$Id: ChangeLog,v 1.3043 2010/06/28 19:51:11 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 4a22069..bea891a 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.534 2010/06/19 09:51:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.535 2010/06/28 19:51:11 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -3976,6 +3976,9 @@ _SQLFreeConnect(SQLHDBC hdbc)
+ 	tds_free_socket(dbc->tds_socket);
+ 
+ 	/* free attributes */
++#ifdef TDS_NO_DM
++	tds_dstr_free(&dbc->attr.tracefile);
++#endif
+ 	tds_dstr_free(&dbc->attr.current_catalog);
+ 	tds_dstr_free(&dbc->attr.translate_lib);
+ 
+
+commit 8b93f94f047f18f2277bb6f31f981187e5034177
+Author: freddy77 <freddy77>
+Date:   Mon Jun 28 20:24:49 2010 +0000
+
+    add odbc_dstr_copy and reuse it
+
+diff --git a/ChangeLog b/ChangeLog
+index ce2baf0..c54fdef 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jun 28 22:24:37 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
++	- add odbc_dstr_copy and reuse it
++
+ Mon Jun 28 21:51:02 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix small and quite impossible leak
+ 
+@@ -2530,4 +2534,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3043 2010/06/28 19:51:11 freddy77 Exp $
++$Id: ChangeLog,v 1.3044 2010/06/28 20:24:49 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index afd1c65..cfac365 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.119 2010/01/29 18:57:03 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.120 2010/06/28 20:24:49 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -545,6 +545,7 @@ SQLINTEGER odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col);
+ int odbc_get_string_size(int size, SQLCHAR * str);
+ void odbc_rdbms_version(TDSSOCKET * tds_socket, char *pversion_string);
+ SQLINTEGER odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row);
++DSTR* odbc_dstr_copy(DSTR *s, int size, SQLCHAR * str);
+ 
+ SQLRETURN odbc_set_string(SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len);
+ SQLRETURN odbc_set_string_i(SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len);
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index bea891a..56cb845 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.535 2010/06/28 19:51:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.536 2010/06/28 20:24:49 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -958,7 +958,7 @@ SQLNativeSql(SQLHDBC hdbc, SQLCHAR FAR * szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLC
+ 	}
+ #endif
+ 
+-	if (!tds_dstr_copyn(&query, (const char *) szSqlStrIn, odbc_get_string_size(cbSqlStrIn, szSqlStrIn))) {
++	if (!odbc_dstr_copy(&query, cbSqlStrIn, szSqlStrIn)) {
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+@@ -1835,7 +1835,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 
+ 	/* data source name */
+ 	if (szDSN || (*szDSN))
+-		tds_dstr_copyn(&dbc->dsn, (const char *) szDSN, odbc_get_string_size(cbDSN, szDSN));
++		odbc_dstr_copy(&dbc->dsn, cbDSN, szDSN);
+ 	else
+ 		tds_dstr_copy(&dbc->dsn, "DEFAULT");
+ 
+@@ -1854,7 +1854,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 	 */
+ 	/* user id */
+ 	if (szUID && (*szUID)) {
+-		if (!tds_dstr_copyn(&connection->user_name, (char *) szUID, odbc_get_string_size(cbUID, szUID))) {
++		if (!odbc_dstr_copy(&connection->user_name, cbUID, szUID)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+@@ -1863,7 +1863,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 
+ 	/* password */
+ 	if (szAuthStr && !tds_dstr_isempty(&connection->user_name)) {
+-		if (!tds_dstr_copyn(&connection->password, (char *) szAuthStr, odbc_get_string_size(cbAuthStr, szAuthStr))) {
++		if (!odbc_dstr_copy(&connection->password, cbAuthStr, szAuthStr)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+@@ -2743,14 +2743,9 @@ SQLSetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 		result = SQL_ERROR;
+ 		break;
+ 	case SQL_DESC_NAME:
+-		{
+-			/* FIXME test len >= 0 */
+-			int len = odbc_get_string_size(BufferLength, (SQLCHAR *) Value);
+-
+-			if (!tds_dstr_copyn(&drec->sql_desc_name, Value, len)) {
+-				odbc_errs_add(&desc->errs, "HY001", NULL);
+-				result = SQL_ERROR;
+-			}
++		if (!odbc_dstr_copy(&drec->sql_desc_name, BufferLength, Value)) {
++			odbc_errs_add(&desc->errs, "HY001", NULL);
++			result = SQL_ERROR;
+ 		}
+ 		break;
+ 	case SQL_DESC_NULLABLE:
+@@ -4492,7 +4487,7 @@ SQLSetCursorName(SQLHSTMT hstmt, SQLCHAR FAR * szCursor, SQLSMALLINT cbCursor)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	if (!tds_dstr_copyn(&stmt->cursor_name, (const char *) szCursor, odbc_get_string_size(cbCursor, szCursor))) {
++	if (!odbc_dstr_copy(&stmt->cursor_name, cbCursor, szCursor)) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -6101,8 +6096,7 @@ _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLI
+ 			odbc_errs_add(&dbc->errs, "HY090", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
+-		len = odbc_get_string_size(StringLength, (SQLCHAR *) ValuePtr);
+-		if (tds_dstr_copyn(&dbc->attr.tracefile, (const char *) ValuePtr, len))
++		if (odbc_dstr_copy(&dbc->attr.tracefile, StringLength, (SQLCHAR *) ValuePtr))
+ 			ODBC_RETURN_(dbc);
+ 		else {
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 6cc2e10..7d83ea2 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -33,13 +33,14 @@
+ #include <assert.h>
+ 
+ #include "tdsodbc.h"
++#include "tdsstring.h"
+ #include "tdsconvert.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.112 2010/06/18 19:33:15 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.113 2010/06/28 20:24:49 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -244,6 +245,12 @@ odbc_get_string_size(int size, SQLCHAR * str)
+ 	return 0;
+ }
+ 
++DSTR*
++odbc_dstr_copy(DSTR *s, int size, SQLCHAR * str)
++{
++	return tds_dstr_copyn(s, (const char *) str, odbc_get_string_size(size, str));
++}
++
+ /**
+  * Convert type from database to ODBC
+  */
+
+commit 5ee54603e270de71cd68c90ae1d334244b881609
+Author: freddy77 <freddy77>
+Date:   Tue Jun 29 12:01:17 2010 +0000
+
+    use ISO-8859-1 if ASCII is detected
+
+diff --git a/ChangeLog b/ChangeLog
+index c54fdef..1c0f42b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jun 29 14:00:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: use ISO-8859-1 if ASCII is detected
++
+ Mon Jun 28 22:24:37 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	- add odbc_dstr_copy and reuse it
+@@ -2534,4 +2537,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3044 2010/06/28 20:24:49 freddy77 Exp $
++$Id: ChangeLog,v 1.3045 2010/06/29 12:01:17 freddy77 Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 4d2bdcd..56bfede 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.199 2010/06/27 17:46:43 berryc Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.200 2010/06/29 12:01:17 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -806,7 +806,9 @@ tds_alloc_connection(TDSLOCALE * locale)
+ {
+ 	TDSCONNECTION *connection;
+ 	char hostname[128];
+-#if !(HAVE_NL_LANGINFO && defined(CODESET))
++#if HAVE_NL_LANGINFO && defined(CODESET)
++	char *charset;
++#else
+ 	char *lc_all;
+ #endif
+ 
+@@ -834,7 +836,10 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 
+ 	setlocale(LC_ALL, "");
+ #if HAVE_NL_LANGINFO && defined(CODESET)
+-	if (!tds_dstr_copy(&connection->client_charset, nl_langinfo(CODESET)))
++	charset = nl_langinfo(CODESET);
++	if (strcmp(tds_canonical_charset_name(charset), "US-ASCII") == 0)
++		charset = "ISO-8859-1";
++	if (!tds_dstr_copy(&connection->client_charset, charset))
+ 		goto Cleanup;;
+ #else
+ 	if (!tds_dstr_copy(&connection->client_charset, "ISO-8859-1"))
+
+commit d41f8d519200905926c36a64e153b8f25a714193
+Author: freddy77 <freddy77>
+Date:   Tue Jun 29 12:07:54 2010 +0000
+
+    do not use strtok which is not reentrant
+
+diff --git a/ChangeLog b/ChangeLog
+index 1c0f42b..d1bd0b0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jun 29 14:07:32 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/mem.c: do not use strtok which is not reentrant
++
+ Tue Jun 29 14:00:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/mem.c: use ISO-8859-1 if ASCII is detected
+ 
+@@ -2537,4 +2540,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3045 2010/06/29 12:01:17 freddy77 Exp $
++$Id: ChangeLog,v 1.3046 2010/06/29 12:07:54 freddy77 Exp $
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 56bfede..d5d8b01 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.200 2010/06/29 12:01:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.201 2010/06/29 12:07:54 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -809,7 +809,7 @@ tds_alloc_connection(TDSLOCALE * locale)
+ #if HAVE_NL_LANGINFO && defined(CODESET)
+ 	char *charset;
+ #else
+-	char *lc_all;
++	char *lc_all, *tok = NULL;
+ #endif
+ 
+ 	TEST_MALLOC(connection, TDSCONNECTION);
+@@ -848,8 +848,8 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 	if ((lc_all = strdup(setlocale(LC_ALL, NULL))) == NULL)
+ 		goto Cleanup;
+ 
+-	if (strtok(lc_all, ".")) {
+-		char *encoding = strtok(NULL, "@");
++	if (strtok_r(lc_all, ".", &tok)) {
++		char *encoding = strtok_r(NULL, "@", &tok);
+ 		if (encoding) {
+ 			if (!tds_dstr_copy(&connection->client_charset, encoding))
+ 				goto Cleanup;
+
+commit 90dd9b1a919fa05b2d225a2f6bad35180d00ed7d
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 09:01:22 2010 +0000
+
+    correct wrong assumption about statistics functions
+
+diff --git a/ChangeLog b/ChangeLog
+index d1bd0b0..0d1c24a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jul  2 11:01:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/stats.c:
++	- correct wrong assumption about statistics functions
++
+ Tue Jun 29 14:07:32 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/mem.c: do not use strtok which is not reentrant
+ 
+@@ -2540,4 +2544,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3046 2010/06/29 12:07:54 freddy77 Exp $
++$Id: ChangeLog,v 1.3047 2010/07/02 09:01:22 freddy77 Exp $
+diff --git a/src/odbc/unittests/stats.c b/src/odbc/unittests/stats.c
+index 0b66617..34ac2e8 100644
+--- a/src/odbc/unittests/stats.c
++++ b/src/odbc/unittests/stats.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: stats.c,v 1.1 2009/12/15 11:23:47 freddy77 Exp $";
++static char software_version[] = "$Id: stats.c,v 1.2 2010/07/02 09:01:22 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLLEN cnamesize;
+@@ -20,7 +20,7 @@ static const char *proc = "stat_proc";
+ static const char *table = "stat_proc";
+ static const char *column = "@t";
+ 
+-#define LEN(x) (x) ? strlen(x) : SQL_NULL_DATA
++#define LEN(x) (x) ? strlen(x) : 0
+ 
+ static void
+ TestProc(const char *type, const char *expected)
+
+commit abdcc863069315f92c03f7cf86e5a55be12a5932
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 09:30:49 2010 +0000
+
+    add desc_get_dbc and reuse it
+
+diff --git a/ChangeLog b/ChangeLog
+index 0d1c24a..b656f9e 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jul  2 11:30:40 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/descriptor.c src/odbc/error.c:
++	- add desc_get_dbc and reuse it
++
+ Fri Jul  2 11:01:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/stats.c:
+ 	- correct wrong assumption about statistics functions
+@@ -2544,4 +2548,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3047 2010/07/02 09:01:22 freddy77 Exp $
++$Id: ChangeLog,v 1.3048 2010/07/02 09:30:49 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index cfac365..c2adfcf 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.120 2010/06/28 20:24:49 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.121 2010/07/02 09:30:49 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -499,6 +499,7 @@ SQLRETURN desc_free(TDS_DESC * desc);
+ SQLRETURN desc_alloc_records(TDS_DESC * desc, unsigned count);
+ SQLRETURN desc_copy(TDS_DESC * dest, TDS_DESC * src);
+ SQLRETURN desc_free_records(TDS_DESC * desc);
++TDS_DBC *desc_get_dbc(TDS_DESC *desc);
+ 
+ /*
+  * odbc.c
+diff --git a/src/odbc/descriptor.c b/src/odbc/descriptor.c
+index 1eae216..feecd70 100644
+--- a/src/odbc/descriptor.c
++++ b/src/odbc/descriptor.c
+@@ -213,3 +213,13 @@ desc_free(TDS_DESC * desc)
+ 	}
+ 	return SQL_SUCCESS;
+ }
++
++TDS_DBC *
++desc_get_dbc(TDS_DESC *desc)
++{
++	if (IS_HSTMT(desc->parent))
++		return ((TDS_STMT *) desc->parent)->dbc;
++
++	return (TDS_DBC *) desc->parent;
++}
++
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index e5eaa09..10ae77f 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.58 2009/12/16 13:06:30 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.59 2010/07/02 09:30:49 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -512,7 +512,6 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	static const char msgprefix[] = "[FreeTDS][SQL Server]";
+ 
+ 	SQLINTEGER odbc_ver = SQL_OV_ODBC2;
+-	SQLHANDLE parent;
+ 
+ 	if (numRecord <= 0 || cbErrorMsgMax < 0)
+ 		return SQL_ERROR;
+@@ -534,11 +533,7 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
+ 		break;
+ 	case SQL_HANDLE_DESC:
+-		parent = ((TDS_DESC *) handle)->parent;
+-		if (((TDS_CHK *) parent)->htype == SQL_HANDLE_DBC)
+-			odbc_ver = ((TDS_DBC *) parent)->env->attr.odbc_version;
+-		else
+-			odbc_ver = ((TDS_STMT *) parent)->dbc->env->attr.odbc_version;
++		odbc_ver = desc_get_dbc((TDS_DESC *) handle)->env->attr.odbc_version;
+ 		break;
+ 	default:
+ 		return SQL_INVALID_HANDLE;
+@@ -637,7 +632,6 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	TDS_STMT *stmt = NULL;
+ 	TDS_DBC *dbc = NULL;
+ 	TDS_ENV *env = NULL;
+-	SQLHANDLE parent;
+ 	char tmp[16];
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagField(%d, %p, %d, %d, %p, %d, %p)\n", 
+@@ -666,13 +660,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		break;
+ 
+ 	case SQL_HANDLE_DESC:
+-		parent = ((TDS_DESC *) handle)->parent;
+-		if (((TDS_CHK *) parent)->htype == SQL_HANDLE_DBC) {
+-			dbc = (TDS_DBC *) parent;
+-		} else {
+-			stmt = (TDS_STMT *) parent;
+-			dbc = stmt->dbc;
+-		}
++		dbc = desc_get_dbc((TDS_DESC *) handle);
+ 		env = dbc->env;
+ 		break;
+ 
+
+commit d222ef7b7257906c027efc86a8301a60d05a3ead
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 13:38:24 2010 +0000
+
+    put odbc_set_string_i and odbc_set_string together, prepare for wide encoding
+
+diff --git a/ChangeLog b/ChangeLog
+index b656f9e..c7638c8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Jul  2 15:38:06 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c:
++	- put odbc_set_string_i and odbc_set_string together, prepare for
++	  wide encoding
++
+ Fri Jul  2 11:30:40 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/descriptor.c src/odbc/error.c:
+ 	- add desc_get_dbc and reuse it
+@@ -2548,4 +2554,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3048 2010/07/02 09:30:49 freddy77 Exp $
++$Id: ChangeLog,v 1.3049 2010/07/02 13:38:24 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index c2adfcf..8dba90e 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.121 2010/07/02 09:30:49 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.122 2010/07/02 13:38:24 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -531,8 +531,15 @@ void odbc_check_desc_extra(TDS_DESC * desc);
+ /*
+  * odbc_util.h
+  */
+-int odbc_set_stmt_query(struct _hstmt *stmt, const char *sql, int sql_len);
+-int odbc_set_stmt_prepared_query(struct _hstmt *stmt, const char *sql, int sql_len);
++/* helpers for ODBC wide string support */
++#undef _wide
++#undef _WIDE
++# define _wide
++# define _wide0
++# define _WIDE
++# define ODBC_CHAR SQLCHAR
++int odbc_set_stmt_query(struct _hstmt *stmt, const ODBC_CHAR *sql, int sql_len _WIDE);
++int odbc_set_stmt_prepared_query(struct _hstmt *stmt, const ODBC_CHAR *sql, int sql_len _WIDE);
+ void odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row);
+ void odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row);
+ 
+@@ -543,13 +550,16 @@ int odbc_c_to_server_type(int c_type);
+ 
+ void odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver);
+ SQLINTEGER odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col);
+-int odbc_get_string_size(int size, SQLCHAR * str);
++int odbc_get_string_size(int size, ODBC_CHAR * str _WIDE);
+ void odbc_rdbms_version(TDSSOCKET * tds_socket, char *pversion_string);
+ SQLINTEGER odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row);
+-DSTR* odbc_dstr_copy(DSTR *s, int size, SQLCHAR * str);
++DSTR* odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE);
+ 
+-SQLRETURN odbc_set_string(SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len);
+-SQLRETURN odbc_set_string_i(SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len);
++SQLRETURN odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag);
++static inline SQLRETURN odbc_set_string(TDS_DBC *dbc, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len _WIDE)
++{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0); }
++static inline SQLRETURN odbc_set_string_i(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len _WIDE)
++{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0x10); }
+ 
+ SQLSMALLINT odbc_get_concise_sql_type(SQLSMALLINT type, SQLSMALLINT interval);
+ SQLRETURN odbc_set_concise_sql_type(SQLSMALLINT concise_type, struct _drecord *drec, int check_only);
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 10ae77f..83f356c 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.59 2010/07/02 09:30:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.60 2010/07/02 13:38:24 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -508,6 +508,7 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	struct _sql_errors *errs;
+ 	const char *msg;
+ 	char *p;
++	TDS_DBC *dbc = NULL;
+ 
+ 	static const char msgprefix[] = "[FreeTDS][SQL Server]";
+ 
+@@ -522,18 +523,21 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	errs = &((TDS_CHK *) handle)->errs;
+ 	switch (handleType) {
+ 	case SQL_HANDLE_STMT:
+-		odbc_ver = ((TDS_STMT *) handle)->dbc->env->attr.odbc_version;
++		dbc = ((TDS_STMT *) handle)->dbc;
++		odbc_ver = dbc->env->attr.odbc_version;
+ 		break;
+ 
+ 	case SQL_HANDLE_DBC:
+-		odbc_ver = ((TDS_DBC *) handle)->env->attr.odbc_version;
++		dbc = (TDS_DBC *) handle;
++		odbc_ver = dbc->env->attr.odbc_version;
+ 		break;
+ 
+ 	case SQL_HANDLE_ENV:
+ 		odbc_ver = ((TDS_ENV *) handle)->attr.odbc_version;
+ 		break;
+ 	case SQL_HANDLE_DESC:
+-		odbc_ver = desc_get_dbc((TDS_DESC *) handle)->env->attr.odbc_version;
++		dbc = desc_get_dbc((TDS_DESC *) handle);
++		odbc_ver = dbc->env->attr.odbc_version;
+ 		break;
+ 	default:
+ 		return SQL_INVALID_HANDLE;
+@@ -559,7 +563,7 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
+ 		return SQL_ERROR;
+ 
+-	result = odbc_set_string(szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
++	result = odbc_set_string(dbc, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1 _wide);
+ 	free(p);
+ 
+ 	if (pfNativeError)
+@@ -591,7 +595,7 @@ SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, S
+ 	} else
+ 		return SQL_INVALID_HANDLE;
+ 
+-	result = _SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
++	result = _SQLGetDiagRec(type, handle, 1, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg _wide);
+ 
+ 	if (result == SQL_SUCCESS) {
+ 		/* remove first error */
+@@ -677,7 +681,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 			return SQL_ERROR;
+ 
+ 		/* TODO */
+-		return odbc_set_string(buffer, cbBuffer, pcbBuffer, "", 0);
++		return odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, "", 0 _wide);
+ 
+ 	case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
+ 		*(SQLINTEGER *) buffer = 0;
+@@ -721,9 +725,9 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	case SQL_DIAG_CLASS_ORIGIN:
+ 	case SQL_DIAG_SUBCLASS_ORIGIN:
+ 		if (odbc_ver == SQL_OV_ODBC2)
+-			result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ISO 9075", -1);
++			result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, "ISO 9075", -1 _wide);
+ 		else
+-			result = odbc_set_string(buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1);
++			result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1 _wide);
+ 		break;
+ 
+ 	case SQL_DIAG_COLUMN_NUMBER:
+@@ -750,12 +754,12 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		else
+ 			cplen = 0;
+ 
+-		result = odbc_set_string(buffer, cbBuffer, pcbBuffer, tmp, cplen);
++		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, tmp, cplen _wide);
+ 		break;
+ 
+ 	case SQL_DIAG_MESSAGE_TEXT:
+ 		msg = errs->errs[numRecord].msg;
+-		result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1);
++		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, msg, -1 _wide);
+ 		break;
+ 
+ 	case SQL_DIAG_NATIVE:
+@@ -782,7 +786,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 			}
+ 			break;
+ 		}
+-		result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, -1);
++		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, msg, -1 _wide);
+ 		break;
+ 
+ 	case SQL_DIAG_SQLSTATE:
+@@ -791,7 +795,7 @@ SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 		else
+ 			msg = errs->errs[numRecord].state2;
+ 
+-		result = odbc_set_string(buffer, cbBuffer, pcbBuffer, msg, 5);
++		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, msg, 5 _wide);
+ 		break;
+ 
+ 	default:
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 56cb845..fa6ad3c 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.536 2010/06/28 20:24:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.537 2010/07/02 13:38:24 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -73,19 +73,19 @@ static SQLRETURN _SQLFreeDesc(SQLHDESC hdesc);
+ static SQLRETURN _SQLExecute(TDS_STMT * stmt);
+ static SQLRETURN _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength,
+ 					    SQLINTEGER * StringLength);
+-static SQLRETURN _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
++static SQLRETURN _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength _WIDE);
+ static SQLRETURN _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
+ static SQLRETURN _SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength,
+ 					 SQLINTEGER * StringLength);
+ static SQLRETURN _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc,
+-					  SQLSMALLINT cbDescMax, SQLSMALLINT FAR * pcbDesc, SQLLEN FAR * pfDesc);
++					  SQLSMALLINT cbDescMax, SQLSMALLINT FAR * pcbDesc, SQLLEN FAR * pfDesc _WIDE);
+ static SQLRETURN _SQLFetch(TDS_STMT * stmt, SQLSMALLINT FetchOrientation, SQLLEN FetchOffset);
+ static SQLRETURN odbc_populate_ird(TDS_STMT * stmt);
+ static int odbc_errmsg_handler(const TDSCONTEXT * ctx, TDSSOCKET * tds, TDSMESSAGE * msg);
+ static void odbc_log_unimplemented_type(const char function_name[], int fType);
+ static void odbc_upper_column_names(TDS_STMT * stmt);
+ static void odbc_col_setname(TDS_STMT * stmt, int colpos, const char *name);
+-static SQLRETURN odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...);
++static SQLRETURN odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...);
+ static SQLRETURN odbc_free_dynamic(TDS_STMT * stmt);
+ static SQLRETURN odbc_free_cursor(TDS_STMT * stmt);
+ static SQLRETURN odbc_update_ird(TDS_STMT *stmt, TDS_ERRS *errs);
+@@ -549,7 +549,7 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 				       connection, params))
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 
+-	odbc_set_string(szConnStrOut, cbConnStrOutMax, pcbConnStrOut, (const char *) szConnStrIn, conlen);
++	odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, (const char *) szConnStrIn, conlen _wide);
+ 
+ 	/* add login info */
+ 	if (hwnd && fDriverCompletion != SQL_DRIVER_NOPROMPT
+@@ -579,7 +579,7 @@ SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALL
+ 		if (!odbc_build_connect_string(&dbc->errs, params, &out))
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 
+-		odbc_set_string(szConnStrOut, cbConnStrOutMax, pcbConnStrOut, out, -1);
++		odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, out, -1 _wide);
+ 		tdsdump_log(TDS_DBG_INFO1, "connection string is now: %s\n", out);
+ 		free(out);
+ #else
+@@ -630,7 +630,7 @@ SQLColumnPrivileges(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbC
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName, szColumnName, cbColumnName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_column_privileges ", 4, "O@table_qualifier", szCatalogName, cbCatalogName,
++		odbc_stat_execute(stmt _wide, "sp_column_privileges ", 4, "O@table_qualifier", szCatalogName, cbCatalogName,
+ 				  "O@table_owner", szSchemaName, cbSchemaName, "O@table_name", szTableName, cbTableName,
+ 				  "P@column_name", szColumnName, cbColumnName);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+@@ -724,7 +724,7 @@ SQLForeignKeys(SQLHSTMT hstmt, SQLCHAR FAR * szPkCatalogName, SQLSMALLINT cbPkCa
+ 			hstmt, szPkCatalogName, cbPkCatalogName, szPkSchemaName, cbPkSchemaName, szPkTableName, cbPkTableName, szFkCatalogName, cbFkCatalogName, szFkSchemaName, cbFkSchemaName, szFkTableName, cbFkTableName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_fkeys ", 6, "O@pktable_qualifier", szPkCatalogName, cbPkCatalogName, "O@pktable_owner",
++		odbc_stat_execute(stmt _wide, "sp_fkeys ", 6, "O@pktable_qualifier", szPkCatalogName, cbPkCatalogName, "O@pktable_owner",
+ 				  szPkSchemaName, cbPkSchemaName, "O@pktable_name", szPkTableName, cbPkTableName,
+ 				  "O@fktable_qualifier", szFkCatalogName, cbFkCatalogName, "O@fktable_owner", szFkSchemaName,
+ 				  cbFkSchemaName, "O@fktable_name", szFkTableName, cbFkTableName);
+@@ -958,7 +958,7 @@ SQLNativeSql(SQLHDBC hdbc, SQLCHAR FAR * szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLC
+ 	}
+ #endif
+ 
+-	if (!odbc_dstr_copy(&query, cbSqlStrIn, szSqlStrIn)) {
++	if (!odbc_dstr_copy(dbc, &query, cbSqlStrIn, szSqlStrIn _wide)) {
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+@@ -966,7 +966,7 @@ SQLNativeSql(SQLHDBC hdbc, SQLCHAR FAR * szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLC
+ 	/* TODO support not null terminated in native_sql */
+ 	native_sql(dbc, tds_dstr_buf(&query));
+ 
+-	ret = odbc_set_string_i(szSqlStr, cbSqlStrMax, pcbSqlStr, tds_dstr_cstr(&query), -1);
++	ret = odbc_set_string_i(dbc, szSqlStr, cbSqlStrMax, pcbSqlStr, tds_dstr_cstr(&query), -1 _wide);
+ 
+ 	tds_dstr_free(&query);
+ 
+@@ -1008,7 +1008,7 @@ SQLPrimaryKeys(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalo
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_pkeys ", 3, "O@table_qualifier", szCatalogName, cbCatalogName, "O@table_owner",
++		odbc_stat_execute(stmt _wide, "sp_pkeys ", 3, "O@table_qualifier", szCatalogName, cbCatalogName, "O@table_owner",
+ 				  szSchemaName, cbSchemaName, "O@table_name", szTableName, cbTableName);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "TABLE_CAT");
+@@ -1030,7 +1030,7 @@ SQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbC
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName, szColumnName, cbColumnName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_sproc_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4,
++		odbc_stat_execute(stmt _wide, "sp_sproc_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4,
+ 				  "O@procedure_qualifier", szCatalogName, cbCatalogName,
+ 				  "P@procedure_owner", szSchemaName, cbSchemaName, "P@procedure_name", szProcName, cbProcName,
+ 				  "P@column_name", szColumnName, cbColumnName, "V@ODBCVer", (char*) NULL, 0);
+@@ -1059,7 +1059,7 @@ SQLProcedures(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalog
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szProcName, cbProcName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "..sp_stored_procedures ", 3, "P@sp_name", szProcName, cbProcName, "P@sp_owner", szSchemaName,
++		odbc_stat_execute(stmt _wide, "..sp_stored_procedures ", 3, "P@sp_name", szProcName, cbProcName, "P@sp_owner", szSchemaName,
+ 				  cbSchemaName, "O@sp_qualifier", szCatalogName, cbCatalogName);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "PROCEDURE_CAT");
+@@ -1200,7 +1200,7 @@ SQLTablePrivileges(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCa
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_table_privileges ", 3, "O@table_qualifier", szCatalogName, cbCatalogName,
++		odbc_stat_execute(stmt _wide, "sp_table_privileges ", 3, "O@table_qualifier", szCatalogName, cbCatalogName,
+ 				  "P@table_owner", szSchemaName, cbSchemaName, "P@table_name", szTableName, cbTableName);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "TABLE_CAT");
+@@ -1835,7 +1835,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 
+ 	/* data source name */
+ 	if (szDSN || (*szDSN))
+-		odbc_dstr_copy(&dbc->dsn, cbDSN, szDSN);
++		odbc_dstr_copy(dbc, &dbc->dsn, cbDSN, szDSN _wide);
+ 	else
+ 		tds_dstr_copy(&dbc->dsn, "DEFAULT");
+ 
+@@ -1854,7 +1854,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 	 */
+ 	/* user id */
+ 	if (szUID && (*szUID)) {
+-		if (!odbc_dstr_copy(&connection->user_name, cbUID, szUID)) {
++		if (!odbc_dstr_copy(dbc, &connection->user_name, cbUID, szUID _wide)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+@@ -1863,7 +1863,7 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 
+ 	/* password */
+ 	if (szAuthStr && !tds_dstr_isempty(&connection->user_name)) {
+-		if (!odbc_dstr_copy(&connection->password, cbAuthStr, szAuthStr)) {
++		if (!odbc_dstr_copy(dbc, &connection->password, cbAuthStr, szAuthStr _wide)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+@@ -1911,7 +1911,7 @@ SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLCHAR FAR * szColName, SQLSM
+ 		SQLRETURN result;
+ 
+ 		/* straight copy column name up to cbColNameMax */
+-		result = odbc_set_string(szColName, cbColNameMax, pcbColName, tds_dstr_cstr(&drec->sql_desc_label), -1);
++		result = odbc_set_string(stmt->dbc, szColName, cbColNameMax, pcbColName, tds_dstr_cstr(&drec->sql_desc_label), -1 _wide);
+ 		if (result == SQL_SUCCESS_WITH_INFO) {
+ 			odbc_errs_add(&stmt->errs, "01004", NULL);
+ 			stmt->errs.lastrc = SQL_SUCCESS_WITH_INFO;
+@@ -1946,7 +1946,7 @@ SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLCHAR FAR * szColName, SQLSM
+ 
+ static SQLRETURN
+ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax,
+-		 SQLSMALLINT FAR * pcbDesc, SQLLEN FAR * pfDesc)
++		 SQLSMALLINT FAR * pcbDesc, SQLLEN FAR * pfDesc _WIDE)
+ {
+ 	TDS_DESC *ird;
+ 	struct _drecord *drec;
+@@ -1959,8 +1959,8 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 
+ 	ird = stmt->ird;
+ 
+-#define COUT(src) result = odbc_set_string(rgbDesc, cbDescMax, pcbDesc, src ? src : "", -1);
+-#define SOUT(src) result = odbc_set_string(rgbDesc, cbDescMax, pcbDesc, tds_dstr_cstr(&src), -1);
++#define COUT(src) result = odbc_set_string(stmt->dbc, rgbDesc, cbDescMax, pcbDesc, src ? src : "", -1 _wide);
++#define SOUT(src) result = odbc_set_string(stmt->dbc, rgbDesc, cbDescMax, pcbDesc, tds_dstr_cstr(&src), -1 _wide);
+ 
+ /* SQLColAttribute returns always attributes using SQLINTEGER */
+ #if ENABLE_EXTRA_CHECKS
+@@ -2166,7 +2166,7 @@ SQLColAttributes(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLColAttributes(%p, %d, %d, %p, %d, %p, %p)\n", 
+ 			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
+ 
+-	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
++	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc _wide0);
+ }
+ 
+ #if (ODBCVER >= 0x0300)
+@@ -2390,7 +2390,7 @@ SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALL
+ 
+ 	drec = &desc->records[RecordNumber - 1];
+ 
+-	if ((rc = odbc_set_string(Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1)) != SQL_SUCCESS)
++	if ((rc = odbc_set_string(desc_get_dbc(desc), Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1 _wide)) != SQL_SUCCESS)
+ 		odbc_errs_add(&desc->errs, "01004", NULL);
+ 
+ 	if (Type)
+@@ -2421,8 +2421,8 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDescField(%p, %d, %d, %p, %d, %p)\n", 
+ 			hdesc, icol, fDescType, Value, (int)BufferLength, StringLength);
+ 
+-#define COUT(src) result = odbc_set_string_i(Value, BufferLength, StringLength, src, -1);
+-#define SOUT(src) result = odbc_set_string_i(Value, BufferLength, StringLength, tds_dstr_cstr(&src), -1);
++#define COUT(src) result = odbc_set_string_i(desc_get_dbc(desc), Value, BufferLength, StringLength, src, -1 _wide);
++#define SOUT(src) result = odbc_set_string_i(desc_get_dbc(desc), Value, BufferLength, StringLength, tds_dstr_cstr(&src), -1 _wide);
+ 
+ #if ENABLE_EXTRA_CHECKS
+ #define IOUT(type, src) do { \
+@@ -2743,7 +2743,7 @@ SQLSetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ 		result = SQL_ERROR;
+ 		break;
+ 	case SQL_DESC_NAME:
+-		if (!odbc_dstr_copy(&drec->sql_desc_name, BufferLength, Value)) {
++		if (!odbc_dstr_copy(desc_get_dbc(desc), &drec->sql_desc_name, BufferLength, Value _wide)) {
+ 			odbc_errs_add(&desc->errs, "HY001", NULL);
+ 			result = SQL_ERROR;
+ 		}
+@@ -3423,7 +3423,7 @@ SQLExecDirect(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLExecDirect(%p, %p, %d)\n", hstmt, szSqlStr, (int)cbSqlStr);
+ 
+-	if (SQL_SUCCESS != odbc_set_stmt_query(stmt, (char *) szSqlStr, cbSqlStr)) {
++	if (SQL_SUCCESS != odbc_set_stmt_query(stmt, szSqlStr, cbSqlStr _wide)) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -4396,7 +4396,7 @@ SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
+ 	if (retcode != SQL_SUCCESS)
+ 		return retcode;
+ 
+-	if (SQL_SUCCESS != odbc_set_stmt_prepared_query(stmt, (char *) szSqlStr, cbSqlStr))
++	if (SQL_SUCCESS != odbc_set_stmt_prepared_query(stmt, szSqlStr, cbSqlStr _wide))
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 
+ 	/* count parameters */
+@@ -4487,7 +4487,7 @@ SQLSetCursorName(SQLHSTMT hstmt, SQLCHAR FAR * szCursor, SQLSMALLINT cbCursor)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	if (!odbc_dstr_copy(&stmt->cursor_name, cbCursor, szCursor)) {
++	if (!odbc_dstr_copy(stmt->dbc, &stmt->cursor_name, cbCursor, szCursor _wide)) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -4504,7 +4504,7 @@ SQLGetCursorName(SQLHSTMT hstmt, SQLCHAR FAR * szCursor, SQLSMALLINT cbCursorMax
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetCursorName(%p, %p, %d, %p)\n", 
+ 			hstmt, szCursor, cbCursorMax, pcbCursor);
+ 
+-	if ((rc = odbc_set_string(szCursor, cbCursorMax, pcbCursor, tds_dstr_cstr(&stmt->cursor_name), -1)))
++	if ((rc = odbc_set_string(stmt->dbc, szCursor, cbCursorMax, pcbCursor, tds_dstr_cstr(&stmt->cursor_name), -1 _wide)))
+ 		odbc_errs_add(&stmt->errs, "01004", NULL);
+ 
+ 	ODBC_RETURN(stmt, rc);
+@@ -4636,7 +4636,7 @@ SQLColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName,	/* object_qualifier */
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName, szColumnName, cbColumnName);
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4,
++		odbc_stat_execute(stmt _wide, "sp_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4,
+ 				  "P@table_name", szTableName, cbTableName, "P@table_owner", szSchemaName,
+ 				  cbSchemaName, "O@table_qualifier", szCatalogName, cbCatalogName, "P@column_name", szColumnName,
+ 				  cbColumnName, "V@ODBCVer", (char*) NULL, 0);
+@@ -4728,7 +4728,7 @@ _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTE
+ 
+ 	assert(p);
+ 
+-	rc = odbc_set_string_i(Value, BufferLength, StringLength, p, -1);
++	rc = odbc_set_string_i(dbc, Value, BufferLength, StringLength, p, -1 _wide);
+ 	ODBC_RETURN(dbc, rc);
+ }
+ 
+@@ -4748,7 +4748,7 @@ SQLGetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetConnectOption(%p, %u, %p)\n", hdbc, fOption, pvParam);
+ 
+-	return _SQLGetConnectAttr(hdbc, (SQLINTEGER) fOption, pvParam, SQL_MAX_OPTION_STRING_LENGTH, NULL);
++	return _SQLGetConnectAttr(hdbc, (SQLINTEGER) fOption, pvParam, SQL_MAX_OPTION_STRING_LENGTH, NULL _wide0);
+ }
+ 
+ SQLRETURN ODBC_API
+@@ -5019,7 +5019,7 @@ SQLGetFunctions(SQLHDBC hdbc, SQLUSMALLINT fFunction, SQLUSMALLINT FAR * pfExist
+ 
+ static SQLRETURN
+ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMALLINT cbInfoValueMax,
+-	    SQLSMALLINT FAR * pcbInfoValue)
++	    SQLSMALLINT FAR * pcbInfoValue _WIDE)
+ {
+ 	const char *p = NULL;
+ 	char buf[32];
+@@ -5756,7 +5756,7 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 
+ 	/* char data */
+ 	if (p) {
+-		return odbc_set_string(rgbInfoValue, cbInfoValueMax, pcbInfoValue, p, -1);
++		return odbc_set_string(dbc, rgbInfoValue, cbInfoValueMax, pcbInfoValue, p, -1 _wide);
+ 	} else {
+ 		if (out_len > 0 && pcbInfoValue)
+ 			*pcbInfoValue = out_len;
+@@ -5778,7 +5778,7 @@ SQLGetInfo(SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMA
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetInfo(%p, %d, %p, %d, %p)\n", 
+ 			hdbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue);
+ 
+-	ODBC_RETURN(dbc, _SQLGetInfo(dbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue));
++	ODBC_RETURN(dbc, _SQLGetInfo(dbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue _wide0));
+ }
+ static void
+ tds_ascii_strupr(char *s)
+@@ -5889,7 +5889,7 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 	} else {
+ 		sprintf(sql, sql_templ, fSqlType);
+ 	}
+-	if (SQL_SUCCESS != odbc_set_stmt_query(stmt, sql, strlen(sql)))
++	if (SQL_SUCCESS != odbc_set_stmt_query(stmt, (ODBC_CHAR*) sql, strlen(sql) _wide0))
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 
+       redo:
+@@ -6033,7 +6033,7 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 
+ 
+ static SQLRETURN
+-_SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength)
++_SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength _WIDE)
+ {
+ 	SQLULEN u_value = (SQLULEN) (TDS_INTPTR) ValuePtr;
+ 	int len = 0;
+@@ -6096,7 +6096,7 @@ _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLI
+ 			odbc_errs_add(&dbc->errs, "HY090", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
+-		if (odbc_dstr_copy(&dbc->attr.tracefile, StringLength, (SQLCHAR *) ValuePtr))
++		if (odbc_dstr_copy(dbc, &dbc->attr.tracefile, StringLength, (ODBC_CHAR *) ValuePtr _wide))
+ 			ODBC_RETURN_(dbc);
+ 		else {
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+@@ -6127,14 +6127,14 @@ SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLIN
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLSetConnectAttr(%p, %d, %p, %d)\n", 
+ 			hdbc, (int)Attribute, ValuePtr, (int)StringLength);
+ 
+-	return _SQLSetConnectAttr(hdbc, Attribute, ValuePtr, StringLength);
++	return _SQLSetConnectAttr(hdbc, Attribute, ValuePtr, StringLength _wide0);
+ }
+ 
+ SQLRETURN ODBC_API
+ SQLSetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLSetConnectOption(%p, %d, %u)\n", hdbc, fOption, (unsigned)vParam);
+-	return _SQLSetConnectAttr(hdbc, (SQLINTEGER) fOption, (SQLPOINTER) vParam, SQL_NTS);
++	return _SQLSetConnectAttr(hdbc, (SQLINTEGER) fOption, (SQLPOINTER) vParam, SQL_NTS _wide0);
+ }
+ 
+ static SQLRETURN
+@@ -6470,7 +6470,7 @@ SQLSpecialColumns(SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR FAR * szCatalog
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	if (!odbc_get_string_size(cbTableName, szTableName)) {
++	if (!odbc_get_string_size(cbTableName, szTableName _wide)) {
+ 		odbc_errs_add(&stmt->errs, "HY009", "SQLSpecialColumns: The table name parameter is required");
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -6502,7 +6502,7 @@ SQLSpecialColumns(SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR FAR * szCatalog
+ 		col_type = 'V';
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_special_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 7 : 4, "O", szTableName,
++		odbc_stat_execute(stmt _wide, "sp_special_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 7 : 4, "O", szTableName,
+ 				  cbTableName, "O", szSchemaName, cbSchemaName, "O@qualifier", szCatalogName, cbCatalogName,
+ 				  "@col_type", &col_type, 1, "@scope", &scope, 1, "@nullable", &nullable, 1,
+ 				  "V@ODBCVer", (char*) NULL, 0);
+@@ -6548,7 +6548,7 @@ SQLStatistics(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalog
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	if (!odbc_get_string_size(cbTableName, szTableName)) {
++	if (!odbc_get_string_size(cbTableName, szTableName _wide)) {
+ 		odbc_errs_add(&stmt->errs, "HY009", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -6565,7 +6565,7 @@ SQLStatistics(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalog
+ 		unique = 'N';
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, "sp_statistics ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4, "O@table_qualifier",
++		odbc_stat_execute(stmt _wide, "sp_statistics ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4, "O@table_qualifier",
+ 				  szCatalogName, cbCatalogName, "O@table_owner", szSchemaName, cbSchemaName, "O@table_name",
+ 				  szTableName, cbTableName, "@is_unique", &unique, 1, "@accuracy", &accuracy, 1);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+@@ -6875,7 +6875,7 @@ odbc_quote_metadata(TDS_DBC * dbc, char type, char *dest, const char *s, int len
+ 
+ #define ODBC_MAX_STAT_PARAM 8
+ static SQLRETURN
+-odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...)
++odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ {
+ 	struct param
+ 	{
+@@ -6961,7 +6961,7 @@ odbc_stat_execute(TDS_STMT * stmt, const char *begin, int nparams, ...)
+ 	assert(p - proc + 1 <= len);
+ 
+ 	/* set it */
+-	retcode = odbc_set_stmt_query(stmt, proc, p - proc);
++	retcode = odbc_set_stmt_query(stmt, (ODBC_CHAR *) proc, p - proc _wide0);
+ 	free(proc);
+ 
+ 	if (retcode != SQL_SUCCESS)
+@@ -7089,7 +7089,7 @@ SQLSetScrollOptions(SQLHSTMT hstmt, SQLUSMALLINT fConcurrency, SQLLEN crowKeyset
+ 	}
+ 
+ 	value = 0;
+-	_SQLGetInfo(stmt->dbc, info, &value, sizeof(value), NULL);
++	_SQLGetInfo(stmt->dbc, info, &value, sizeof(value), NULL _wide0);
+ 
+ 	if ((value & check) == 0) {
+ 		odbc_errs_add(&stmt->errs, "HYC00", NULL);
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 7d83ea2..3dc1f9e 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -40,7 +40,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.113 2010/06/28 20:24:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.114 2010/07/02 13:38:24 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -54,14 +54,14 @@ TDS_RCSID(var, "$Id: odbc_util.c,v 1.113 2010/06/28 20:24:49 freddy77 Exp $");
+  */
+ 
+ static int
+-odbc_set_stmt(TDS_STMT * stmt, char **dest, const char *sql, int sql_len)
++odbc_set_stmt(TDS_STMT * stmt, char **dest, const ODBC_CHAR *sql, int sql_len _WIDE)
+ {
+ 	char *p;
+ 
+ 	assert(dest == &stmt->prepared_query || dest == &stmt->query);
+ 
+ 	if (sql_len == SQL_NTS)
+-		sql_len = strlen(sql);
++		sql_len = strlen((const char*) sql);
+ 	else if (sql_len <= 0)
+ 		return SQL_ERROR;
+ 
+@@ -98,16 +98,16 @@ odbc_set_stmt(TDS_STMT * stmt, char **dest, const char *sql, int sql_len)
+ }
+ 
+ int
+-odbc_set_stmt_query(TDS_STMT * stmt, const char *sql, int sql_len)
++odbc_set_stmt_query(TDS_STMT * stmt, const ODBC_CHAR *sql, int sql_len _WIDE)
+ {
+-	return odbc_set_stmt(stmt, &stmt->query, sql, sql_len);
++	return odbc_set_stmt(stmt, &stmt->query, sql, sql_len _wide);
+ }
+ 
+ 
+ int
+-odbc_set_stmt_prepared_query(TDS_STMT * stmt, const char *sql, int sql_len)
++odbc_set_stmt_prepared_query(TDS_STMT * stmt, const ODBC_CHAR *sql, int sql_len _WIDE)
+ {
+-	return odbc_set_stmt(stmt, &stmt->prepared_query, sql, sql_len);
++	return odbc_set_stmt(stmt, &stmt->prepared_query, sql, sql_len _wide);
+ }
+ 
+ 
+@@ -233,7 +233,7 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ }
+ 
+ int
+-odbc_get_string_size(int size, SQLCHAR * str)
++odbc_get_string_size(int size, ODBC_CHAR * str _WIDE)
+ {
+ 	if (str) {
+ 		if (size == SQL_NTS)
+@@ -246,7 +246,7 @@ odbc_get_string_size(int size, SQLCHAR * str)
+ }
+ 
+ DSTR*
+-odbc_dstr_copy(DSTR *s, int size, SQLCHAR * str)
++odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE)
+ {
+ 	return tds_dstr_copyn(s, (const char *) str, odbc_get_string_size(size, str));
+ }
+@@ -756,44 +756,28 @@ odbc_sql_to_server_type(TDSSOCKET * tds, int sql_type)
+ 
+ /**
+  * Copy a string to client setting size according to ODBC convenction
++ * @param dbc       database connection. Can be NULL
+  * @param buffer    client buffer
+  * @param cbBuffer  client buffer size (in bytes)
+  * @param pcbBuffer pointer to SQLSMALLINT to hold string size
+  * @param s         string to copy
+  * @param len       len of string to copy. <0 null terminated
++ * @param flag      set of flag 0x10 SQLINTEGER
+  */
+ SQLRETURN
+-odbc_set_string(SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len)
++odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag)
+ {
+ 	SQLRETURN result = SQL_SUCCESS;
+ 
+ 	if (len < 0)
+ 		len = strlen(s);
+ 
+-	if (pcbBuffer)
+-		*pcbBuffer = len;
+-	if (len >= cbBuffer) {
+-		len = cbBuffer - 1;
+-		result = SQL_SUCCESS_WITH_INFO;
++	if (pcbBuffer) {
++		if (flag & 0x10)
++			*((SQLINTEGER *) pcbBuffer) = len;
++		else
++			*((SQLSMALLINT *) pcbBuffer) = len;
+ 	}
+-	if (buffer && len >= 0) {
+-		/* buffer can overlap, use memmove, thanks to Valgrind */
+-		memmove((char *) buffer, s, len);
+-		((char *) buffer)[len] = 0;
+-	}
+-	return result;
+-}
+-
+-SQLRETURN
+-odbc_set_string_i(SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len)
+-{
+-	SQLRETURN result = SQL_SUCCESS;
+-
+-	if (len < 0)
+-		len = strlen(s);
+-
+-	if (pcbBuffer)
+-		*pcbBuffer = len;
+ 	if (len >= cbBuffer) {
+ 		len = cbBuffer - 1;
+ 		result = SQL_SUCCESS_WITH_INFO;
+
+commit 2be07a6dd241da7995bb9f2e33f9bbbe22a1f9b0
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 14:07:56 2010 +0000
+
+    use macros to prepare code for wide encoding
+
+diff --git a/ChangeLog b/ChangeLog
+index c7638c8..88c7a1b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Jul  2 16:07:45 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/Makefile.am src/odbc/error.c src/odbc/odbc.c:
++	- src/odbc/sqlwparams.h
++	- use macros to prepare code for wide encoding
++
+ Fri Jul  2 15:38:06 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
+ 	* src/odbc/odbc_util.c:
+@@ -2554,4 +2559,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3049 2010/07/02 13:38:24 freddy77 Exp $
++$Id: ChangeLog,v 1.3050 2010/07/02 14:07:56 freddy77 Exp $
+diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am
+index 3b84e59..36dd26c 100644
+--- a/src/odbc/Makefile.am
++++ b/src/odbc/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.47 2010/01/25 23:06:59 freddy77 Exp $
++# $Id: Makefile.am,v 1.48 2010/07/02 14:07:57 freddy77 Exp $
+ SUBDIRS		= unittests
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC)
+ 
+@@ -11,7 +11,7 @@ MINGW_SOURCES	=
+ endif
+ libtdsodbc_la_SOURCES=	odbc.c connectparams.c convert_tds2sql.c \
+ 	descriptor.c prepare_query.c odbc_util.c \
+-	native.c sql2tds.c error.c odbc_checks.c sqlwchar.c $(MINGW_SOURCES)
++	native.c sql2tds.c error.c odbc_checks.c sqlwchar.c sqlwparams.h $(MINGW_SOURCES)
+ if MINGW32
+ libtdsodbc_la_LIBADD=	../../win32/setup.res ../tds/libtds.la ../replacements/libreplacements.la $(ODBCINSTLIB) \
+ 	$(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 83f356c..7f52af1 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.60 2010/07/02 13:38:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.61 2010/07/02 14:07:57 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -572,9 +572,9 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	return result;
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLError(SQLHENV henv, SQLHDBC hdbc, SQLHSTMT hstmt, SQLCHAR FAR * szSqlState, SQLINTEGER FAR * pfNativeError,
+-	 SQLCHAR FAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
++#define FUNC NAME(SQLError) (P(SQLHENV,henv), P(SQLHDBC,hdbc), P(SQLHSTMT,hstmt), PCHAR(szSqlState), P(SQLINTEGER FAR *,pfNativeError),\
++	PCHAR(szErrorMsg), P(SQLSMALLINT,cbErrorMsgMax), P(SQLSMALLINT FAR *,pcbErrorMsg) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN result;
+ 	SQLSMALLINT type;
+@@ -623,9 +623,9 @@ SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, S
+ }
+ 
+ 
+-SQLRETURN ODBC_API
+-SQLGetDiagField(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLSMALLINT diagIdentifier, SQLPOINTER buffer,
+-		SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer)
++#define FUNC NAME(SQLGetDiagField) (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord),\
++	P(SQLSMALLINT,diagIdentifier), P(SQLPOINTER,buffer), P(SQLSMALLINT,cbBuffer), P(SQLSMALLINT FAR *,pcbBuffer) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN result = SQL_SUCCESS;
+ 	struct _sql_errors *errs;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index fa6ad3c..23eae1d 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.537 2010/07/02 13:38:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.538 2010/07/02 14:07:57 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -502,9 +502,10 @@ odbc_prepare(TDS_STMT *stmt)
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLDriverConnect(SQLHDBC hdbc, SQLHWND hwnd, SQLCHAR FAR * szConnStrIn, SQLSMALLINT cbConnStrIn, SQLCHAR FAR * szConnStrOut,
+-		 SQLSMALLINT cbConnStrOutMax, SQLSMALLINT FAR * pcbConnStrOut, SQLUSMALLINT fDriverCompletion)
++#define FUNC NAME(SQLDriverConnect) (P(SQLHDBC,hdbc), P(SQLHWND,hwnd), PCHAR(szConnStrIn), P(SQLSMALLINT,cbConnStrIn), \
++	PCHAR(szConnStrOut), P(SQLSMALLINT,cbConnStrOutMax), P(SQLSMALLINT FAR *,pcbConnStrOut), \
++	P(SQLUSMALLINT,fDriverCompletion) WIDE)
++#include "sqlwparams.h"
+ {
+ 	TDSCONNECTION *connection;
+ 	int conlen = odbc_get_string_size(cbConnStrIn, szConnStrIn);
+@@ -617,10 +618,9 @@ SQLBrowseConnect(SQLHDBC hdbc, SQLCHAR FAR * szConnStrIn, SQLSMALLINT cbConnStrI
+ #endif
+ 
+ 
+-SQLRETURN ODBC_API
+-SQLColumnPrivileges(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-		    SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName, SQLCHAR FAR * szColumnName,
+-		    SQLSMALLINT cbColumnName)
++#define FUNC NAME(SQLColumnPrivileges) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName), \
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName), P(SQLSMALLINT,cbTableName), PCHAR(szColumnName), P(SQLSMALLINT,cbColumnName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -710,11 +710,11 @@ SQLExtendedFetch(SQLHSTMT hstmt, SQLUSMALLINT fFetchType, SQLROWOFFSET irow, SQL
+ 	ODBC_RETURN(stmt, ret);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLForeignKeys(SQLHSTMT hstmt, SQLCHAR FAR * szPkCatalogName, SQLSMALLINT cbPkCatalogName, SQLCHAR FAR * szPkSchemaName,
+-	       SQLSMALLINT cbPkSchemaName, SQLCHAR FAR * szPkTableName, SQLSMALLINT cbPkTableName, SQLCHAR FAR * szFkCatalogName,
+-	       SQLSMALLINT cbFkCatalogName, SQLCHAR FAR * szFkSchemaName, SQLSMALLINT cbFkSchemaName, SQLCHAR FAR * szFkTableName,
+-	       SQLSMALLINT cbFkTableName)
++#define FUNC NAME(SQLForeignKeys) (P(SQLHSTMT,hstmt), PCHAR(szPkCatalogName), P(SQLSMALLINT,cbPkCatalogName), PCHAR(szPkSchemaName),\
++	P(SQLSMALLINT,cbPkSchemaName), PCHAR(szPkTableName), P(SQLSMALLINT,cbPkTableName), PCHAR(szFkCatalogName),\
++	P(SQLSMALLINT,cbFkCatalogName), PCHAR(szFkSchemaName), P(SQLSMALLINT,cbFkSchemaName), PCHAR(szFkTableName),\
++	P(SQLSMALLINT,cbFkTableName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -937,9 +937,9 @@ SQLMoreResults(SQLHSTMT hstmt)
+ 	ODBC_RETURN(stmt, SQL_ERROR);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLNativeSql(SQLHDBC hdbc, SQLCHAR FAR * szSqlStrIn, SQLINTEGER cbSqlStrIn, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStrMax,
+-	     SQLINTEGER FAR * pcbSqlStr)
++#define FUNC NAME(SQLNativeSql) (P(SQLHDBC,hdbc), PCHAR(szSqlStrIn), P(SQLINTEGER,cbSqlStrIn), PCHAR(szSqlStr), \
++	P(SQLINTEGER,cbSqlStrMax), P(SQLINTEGER FAR *,pcbSqlStr) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN ret = SQL_SUCCESS;
+ 	DSTR query;
+@@ -996,9 +996,9 @@ SQLParamOptions(SQLHSTMT hstmt, SQLULEN crow, SQLULEN FAR * pirow)
+ 	return _SQLSetStmtAttr(hstmt, SQL_ATTR_PARAMSET_SIZE, (SQLPOINTER) (TDS_INTPTR) crow, 0);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLPrimaryKeys(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-	       SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName)
++#define FUNC NAME(SQLPrimaryKeys) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName),\
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName), P(SQLSMALLINT,cbTableName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -1017,10 +1017,10 @@ SQLPrimaryKeys(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalo
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-		    SQLSMALLINT cbSchemaName, SQLCHAR FAR * szProcName, SQLSMALLINT cbProcName, SQLCHAR FAR * szColumnName,
+-		    SQLSMALLINT cbColumnName)
++#define FUNC NAME(SQLProcedureColumns) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName),\
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szProcName), P(SQLSMALLINT,cbProcName), PCHAR(szColumnName),\
++	P(SQLSMALLINT,cbColumnName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -1047,9 +1047,9 @@ SQLProcedureColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbC
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLProcedures(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-	      SQLSMALLINT cbSchemaName, SQLCHAR FAR * szProcName, SQLSMALLINT cbProcName)
++#define FUNC NAME(SQLProcedures) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName),\
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szProcName), P(SQLSMALLINT,cbProcName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -1188,9 +1188,9 @@ SQLSetPos(SQLHSTMT hstmt, SQLSETPOSIROW irow, SQLUSMALLINT fOption, SQLUSMALLINT
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLTablePrivileges(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-		   SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName)
++#define FUNC NAME(SQLTablePrivileges) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName),\
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName), P(SQLSMALLINT,cbTableName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -1798,9 +1798,9 @@ SQLCancel(SQLHSTMT hstmt)
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * szUID, SQLSMALLINT cbUID, SQLCHAR FAR * szAuthStr,
+-	   SQLSMALLINT cbAuthStr)
++#define FUNC NAME(SQLConnect) (P(SQLHDBC,hdbc), PCHAR(szDSN), P(SQLSMALLINT,cbDSN), PCHAR(szUID), P(SQLSMALLINT,cbUID), \
++	PCHAR(szAuthStr), P(SQLSMALLINT,cbAuthStr) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN result;
+ 	TDSCONNECTION *connection;
+@@ -1880,9 +1880,10 @@ SQLConnect(SQLHDBC hdbc, SQLCHAR FAR * szDSN, SQLSMALLINT cbDSN, SQLCHAR FAR * s
+ 	ODBC_RETURN_(dbc);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLDescribeCol(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLCHAR FAR * szColName, SQLSMALLINT cbColNameMax, SQLSMALLINT FAR * pcbColName,
+-	       SQLSMALLINT FAR * pfSqlType, SQLULEN FAR * pcbColDef, SQLSMALLINT FAR * pibScale, SQLSMALLINT FAR * pfNullable)
++#define FUNC NAME(SQLDescribeCol) (P(SQLHSTMT,hstmt), P(SQLUSMALLINT,icol), PCHAR(szColName), P(SQLSMALLINT,cbColNameMax), \
++	P(SQLSMALLINT FAR *,pcbColName), P(SQLSMALLINT FAR *,pfSqlType), P(SQLULEN FAR *,pcbColDef), \
++	P(SQLSMALLINT FAR *,pibScale), P(SQLSMALLINT FAR *,pfNullable) WIDE)
++#include "sqlwparams.h"
+ {
+ 	TDS_DESC *ird;
+ 	struct _drecord *drec;
+@@ -2361,10 +2362,10 @@ SQLSetDescRec(SQLHDESC hdesc, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLS
+ 	ODBC_RETURN_(desc);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALLINT BufferLength, SQLSMALLINT * StringLength,
+-	      SQLSMALLINT * Type, SQLSMALLINT * SubType, SQLLEN FAR * Length, SQLSMALLINT * Precision, SQLSMALLINT * Scale,
+-	      SQLSMALLINT * Nullable)
++#define FUNC NAME(SQLGetDescRec) (P(SQLHDESC,hdesc), P(SQLSMALLINT,RecordNumber), PCHAR(Name), P(SQLSMALLINT,BufferLength), \
++	P(SQLSMALLINT *,StringLength), P(SQLSMALLINT *,Type), P(SQLSMALLINT *,SubType), P(SQLLEN FAR *,Length), \
++	P(SQLSMALLINT *,Precision), P(SQLSMALLINT *,Scale), P(SQLSMALLINT *,Nullable) WIDE)
++#include "sqlwparams.h"
+ {
+ 	struct _drecord *drec = NULL;
+ 	SQLRETURN rc = SQL_SUCCESS;
+@@ -2409,9 +2410,9 @@ SQLGetDescRec(SQLHDESC hdesc, SQLSMALLINT RecordNumber, SQLCHAR * Name, SQLSMALL
+ 	ODBC_RETURN(desc, rc);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOINTER Value, SQLINTEGER BufferLength,
+-		SQLINTEGER * StringLength)
++#define FUNC NAME(SQLGetDescField) (P(SQLHDESC,hdesc), P(SQLSMALLINT,icol), P(SQLSMALLINT,fDescType), P(SQLPOINTER,Value), \
++	P(SQLINTEGER,BufferLength), P(SQLINTEGER *,StringLength) WIDE)
++#include "sqlwparams.h"
+ {
+ 	struct _drecord *drec;
+ 	SQLRETURN result = SQL_SUCCESS;
+@@ -2615,8 +2616,9 @@ SQLGetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOIN
+ #undef IOUT
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLSetDescField(SQLHDESC hdesc, SQLSMALLINT icol, SQLSMALLINT fDescType, SQLPOINTER Value, SQLINTEGER BufferLength)
++#define FUNC NAME(SQLSetDescField) (P(SQLHDESC,hdesc), P(SQLSMALLINT,icol), P(SQLSMALLINT,fDescType), \
++	P(SQLPOINTER,Value), P(SQLINTEGER,BufferLength) WIDE)
++#include "sqlwparams.h"
+ {
+ 	struct _drecord *drec;
+ 	SQLRETURN result = SQL_SUCCESS;
+@@ -3414,8 +3416,8 @@ _SQLExecute(TDS_STMT * stmt)
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLExecDirect(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
++#define FUNC NAME(SQLExecDirect) (P(SQLHSTMT,hstmt), PCHAR(szSqlStr), P(SQLINTEGER,cbSqlStr) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN res;
+ 
+@@ -4382,8 +4384,8 @@ SQLNumResultCols(SQLHSTMT hstmt, SQLSMALLINT FAR * pccol)
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLPrepare(SQLHSTMT hstmt, SQLCHAR FAR * szSqlStr, SQLINTEGER cbSqlStr)
++#define FUNC NAME(SQLPrepare) (P(SQLHSTMT,hstmt), PCHAR(szSqlStr), P(SQLINTEGER,cbSqlStr) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN retcode;
+ 
+@@ -4473,8 +4475,8 @@ SQLRowCount(SQLHSTMT hstmt, SQLLEN FAR * pcrow)
+ 	return rc;
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLSetCursorName(SQLHSTMT hstmt, SQLCHAR FAR * szCursor, SQLSMALLINT cbCursor)
++#define FUNC NAME(SQLSetCursorName) (P(SQLHSTMT,hstmt), PCHAR(szCursor), P(SQLSMALLINT,cbCursor) WIDE)
++#include "sqlwparams.h"
+ {
+ 	INIT_HSTMT;
+ 
+@@ -4494,8 +4496,8 @@ SQLSetCursorName(SQLHSTMT hstmt, SQLCHAR FAR * szCursor, SQLSMALLINT cbCursor)
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLGetCursorName(SQLHSTMT hstmt, SQLCHAR FAR * szCursor, SQLSMALLINT cbCursorMax, SQLSMALLINT FAR * pcbCursor)
++#define FUNC NAME(SQLGetCursorName) (P(SQLHSTMT,hstmt), PCHAR(szCursor), P(SQLSMALLINT,cbCursorMax), P(SQLSMALLINT FAR *,pcbCursor) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN rc;
+ 
+@@ -4621,12 +4623,12 @@ SQLSetParam(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fCType, SQLSMALLINT f
+  *                 [ , [ @ODBCVer = ] ODBCVer ] 
+  *
+  */
+-SQLRETURN ODBC_API
+-SQLColumns(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName,	/* object_qualifier */
+-	   SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,	/* object_owner */
+-	   SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName,	/* object_name */
+-	   SQLSMALLINT cbTableName, SQLCHAR FAR * szColumnName,	/* column_name */
+-	   SQLSMALLINT cbColumnName)
++#define FUNC NAME(SQLColumns) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName),	/* object_qualifier */ \
++	P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName),	/* object_owner */ \
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName),	/* object_name */ \
++	P(SQLSMALLINT,cbTableName), PCHAR(szColumnName),	/* column_name */ \
++	P(SQLSMALLINT,cbColumnName) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 
+@@ -6438,10 +6440,10 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 	return _SQLSetStmtAttr(hstmt, (SQLINTEGER) fOption, (SQLPOINTER) vParam, SQL_NTS);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLSpecialColumns(SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName,
+-		  SQLCHAR FAR * szSchemaName, SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName,
+-		  SQLUSMALLINT fScope, SQLUSMALLINT fNullable)
++#define FUNC NAME(SQLSpecialColumns) (P(SQLHSTMT,hstmt), P(SQLUSMALLINT,fColType), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), \
++	PCHAR(szSchemaName), P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName), P(SQLSMALLINT,cbTableName), \
++	P(SQLUSMALLINT,fScope), P(SQLUSMALLINT,fNullable) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 	char nullable, scope, col_type;
+@@ -6516,10 +6518,10 @@ SQLSpecialColumns(SQLHSTMT hstmt, SQLUSMALLINT fColType, SQLCHAR FAR * szCatalog
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-SQLRETURN ODBC_API
+-SQLStatistics(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-	      SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName, SQLUSMALLINT fUnique,
+-	      SQLUSMALLINT fAccuracy)
++#define FUNC NAME(SQLStatistics) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName), \
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName), P(SQLSMALLINT,cbTableName), P(SQLUSMALLINT,fUnique), \
++	P(SQLUSMALLINT,fAccuracy) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 	char unique, accuracy;
+@@ -6577,11 +6579,10 @@ SQLStatistics(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalog
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-
+-SQLRETURN ODBC_API
+-SQLTables(SQLHSTMT hstmt, SQLCHAR FAR * szCatalogName, SQLSMALLINT cbCatalogName, SQLCHAR FAR * szSchemaName,
+-	  SQLSMALLINT cbSchemaName, SQLCHAR FAR * szTableName, SQLSMALLINT cbTableName, SQLCHAR FAR * szTableType,
+-	  SQLSMALLINT cbTableType)
++#define FUNC NAME(SQLTables) (P(SQLHSTMT,hstmt), PCHAR(szCatalogName), P(SQLSMALLINT,cbCatalogName), PCHAR(szSchemaName), \
++	P(SQLSMALLINT,cbSchemaName), PCHAR(szTableName), P(SQLSMALLINT,cbTableName), PCHAR(szTableType), \
++	P(SQLSMALLINT,cbTableType) WIDE)
++#include "sqlwparams.h"
+ {
+ 	int retcode;
+ 	char *type = NULL;
+
+commit b12a8c146e6dd22085caa3087e88deeff9515947
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 14:35:22 2010 +0000
+
+    forgot to add
+
+diff --git a/src/odbc/sqlwparams.h b/src/odbc/sqlwparams.h
+new file mode 100644
+index 0000000..aef02d4
+--- /dev/null
++++ b/src/odbc/sqlwparams.h
+@@ -0,0 +1,12 @@
++//#define FUNC NAME(SQLTest) (P(SQLSMALLINT, x), PCHAR(y) WIDE)
++
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) a
++#define WIDE
++#define P(a,b) a b
++#define PCHAR(a) SQLCHAR* a
++SQLRETURN ODBC_API FUNC
++
++#undef FUNC
+
+commit 823b9b2f345bcc0be048fd276d1ae26d843ca49e
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 18:57:27 2010 +0000
+
+    cleanup
+
+diff --git a/ChangeLog b/ChangeLog
+index 88c7a1b..4f3a83c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jul  2 20:57:16 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/token.c src/tds/util.c: cleanup
++
+ Fri Jul  2 16:07:45 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/Makefile.am src/odbc/error.c src/odbc/odbc.c:
+ 	- src/odbc/sqlwparams.h
+@@ -2559,4 +2562,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3050 2010/07/02 14:07:56 freddy77 Exp $
++$Id: ChangeLog,v 1.3051 2010/07/02 18:57:27 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index ebedc0f..8813fbe 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.337 2010/06/27 17:46:43 berryc Exp $ */
++/* $Id: tds.h,v 1.338 2010/07/02 18:57:32 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -317,13 +317,6 @@ typedef enum {	TDSEOK    = TDS_SUCCEED,
+ 		TDSECLOSEIN = 20292 
+ } TDSERRNO;
+ 
+-/*
+- * TDS_ERROR indicates a successful processing, but that a TDS_ERROR_TOKEN or TDS_EED_TOKEN error was encountered.  
+- * TDS_FAIL indicates an unrecoverable failure.
+- */
+-#define TDS_ERROR            3
+-#define TDS_DONT_RETURN      42
+-
+ #define TDS5_PARAMFMT2_TOKEN       32	/* 0x20 */
+ #define TDS_LANGUAGE_TOKEN         33	/* 0x21    TDS 5.0 only              */
+ #define TDS_ORDERBY2_TOKEN         34	/* 0x22 */
+@@ -1570,7 +1563,6 @@ int tds_get_size_by_type(int servertype);
+ int tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum);
+ TDS_STATE tds_set_state(TDSSOCKET * tds, TDS_STATE state);
+ void tds_set_parent(TDSSOCKET * tds, void *the_parent);
+-void *tds_get_parent(TDSSOCKET * tds);
+ int tds_swap_bytes(unsigned char *buf, int bytes);
+ int tds_version(TDSSOCKET * tds_socket, char *pversion_string);
+ unsigned int tds_gettime_ms(void);
+diff --git a/src/tds/token.c b/src/tds/token.c
+index fcfb8b2..52575b4 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.386 2010/06/26 09:14:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.387 2010/07/02 18:57:32 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -2637,7 +2637,7 @@ tds_process_env_chg(TDSSOCKET * tds)
+ /**
+  * tds_process_msg() is called for MSG, ERR, or EED tokens and is responsible
+  * for calling the CLI's message handling routine
+- * returns TDS_SUCCEED if informational, TDS_ERROR if error.
++ * returns TDS_SUCCEED if informational, TDS_FAIL if error.
+  */
+ static int
+ tds_process_msg(TDSSOCKET * tds, int marker)
+@@ -2749,7 +2749,7 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 			case TDS5_PARAMFMT2_TOKEN:
+ 			case TDS5_PARAMS_TOKEN:
+ 				if (tds_process_default_tokens(tds, next_marker) != TDS_SUCCEED)
+-					++rc;
++					--rc;
+ 				continue;
+ 			}
+ 			break;
+@@ -2765,7 +2765,7 @@ tds_process_msg(TDSSOCKET * tds, int marker)
+ 
+ 	if (rc != 0) {
+ 		tds_free_msg(&msg);
+-		return TDS_ERROR;
++		return TDS_FAIL;
+ 	}
+ 	
+ 	/* special case, */
+diff --git a/src/tds/util.c b/src/tds/util.c
+index fffe149..c4b6eb1 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.91 2010/03/02 08:32:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.92 2010/07/02 18:57:34 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -74,12 +74,6 @@ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+ 		tds->parent = the_parent;
+ }
+ 
+-void *
+-tds_get_parent(TDSSOCKET * tds)
+-{
+-	return (tds->parent);
+-}
+-
+ /**
+  * Set state of TDS connection, with logging and checking.
+  * \param tds	  state information for the socket and the TDS protocol
+
+commit ebba6843584f317d56ddd4aae33749219c2ea92b
+Author: freddy77 <freddy77>
+Date:   Fri Jul 2 23:55:50 2010 +0000
+
+    cleanup iconv replacement
+
+diff --git a/ChangeLog b/ChangeLog
+index 4f3a83c..ff202b1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jul  3 01:55:38 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsiconv.h src/replacements/iconv.c:
++	- cleanup iconv replacement
++
+ Fri Jul  2 20:57:16 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/token.c src/tds/util.c: cleanup
+ 
+@@ -2562,4 +2566,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3051 2010/07/02 18:57:27 freddy77 Exp $
++$Id: ChangeLog,v 1.3052 2010/07/02 23:55:50 freddy77 Exp $
+diff --git a/include/tdsiconv.h b/include/tdsiconv.h
+index 3ca83f6..ed0131c 100644
+--- a/include/tdsiconv.h
++++ b/include/tdsiconv.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_iconv_h_
+ #define _tds_iconv_h_
+ 
+-/* $Id: tdsiconv.h,v 1.38 2010/01/25 23:05:58 freddy77 Exp $ */
++/* $Id: tdsiconv.h,v 1.39 2010/07/02 23:55:56 freddy77 Exp $ */
+ 
+ #if HAVE_ICONV
+ #include <iconv.h>
+@@ -60,50 +60,6 @@ extern "C"
+ #endif
+ 
+ #if ! HAVE_ICONV
+-
+-	/* FYI, the first 4 entries look like this:
+-	 *      {"ISO-8859-1",  1, 1}, -> 0
+-	 *      {"US-ASCII",    1, 4}, -> 1
+-	 *      {"UCS-2LE",     2, 2}, -> 2
+-	 *      {"UCS-2BE",     2, 2}, -> 3
+-	 *
+-	 * These conversions are supplied by src/replacements/iconv.c for the sake of those who don't 
+-	 * have or otherwise need an iconv.
+-	 */
+-enum ICONV_CD_VALUE
+-{
+-	  Like_to_Like = 0x100
+-	, Latin1_ASCII  = 0x01
+-	, ASCII_Latin1  = 0x10
+-
+-	, Latin1_UCS2LE = 0x02
+-	, UCS2LE_Latin1 = 0x20
+-	, ASCII_UCS2LE  = 0x12
+-	, UCS2LE_ASCII  = 0x21
+-
+-	, Latin1_UTF8	= 0x03
+-	, UTF8_Latin1	= 0x30
+-	, ASCII_UTF8	= 0x13
+-	, UTF8_ASCII	= 0x31
+-	, UCS2LE_UTF8	= 0x23
+-	, UTF8_UCS2LE	= 0x32
+-
+-#ifdef DOS32X
+-	, WinEE_UCS2LE  = 0x42
+-	, UCS2LE_WinEE  = 0x24
+-	, WinCYR_UCS2LE = 0x52
+-	, UCS2LE_WinCYR = 0x25
+-	, WinTUR_UCS2LE = 0x62
+-	, UCS2LE_WinTUR = 0x26
+-	, WinARA_UCS2LE = 0x72
+-	, UCS2LE_WinARA = 0x27
+-#endif
+-	/* these aren't needed 
+-	 * , Latin1_UCS2BE = 0x03
+-	 * , UCS2BE_Latin1 = 0x30
+-	 */
+-};
+-
+ iconv_t tds_sys_iconv_open(const char *tocode, const char *fromcode);
+ size_t tds_sys_iconv(iconv_t cd, const char **inbuf, size_t * inbytesleft, char **outbuf, size_t * outbytesleft);
+ int tds_sys_iconv_close(iconv_t cd);
+diff --git a/src/replacements/iconv.c b/src/replacements/iconv.c
+index 80fe192..8f9a1ae 100644
+--- a/src/replacements/iconv.c
++++ b/src/replacements/iconv.c
+@@ -53,13 +53,47 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.16 2008/01/20 14:23:59 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.17 2010/07/02 23:55:56 freddy77 Exp $");
+ 
+ /**
+  * \addtogroup conv
+  * @{ 
+  */
+ 
++	/* FYI, the first 4 entries look like this:
++	 *      {"ISO-8859-1",  1, 1}, -> 0
++	 *      {"US-ASCII",    1, 4}, -> 1
++	 *      {"UCS-2LE",     2, 2}, -> 2
++	 *      {"UCS-2BE",     2, 2}, -> 3
++	 *
++	 * These conversions are supplied by src/replacements/iconv.c for the sake of those who don't
++	 * have or otherwise need an iconv.
++	 */
++enum ICONV_CD_VALUE
++{
++	  Like_to_Like = 0x100
++	, Latin1_ASCII  = 0x01
++	, ASCII_Latin1  = 0x10
++
++	, Latin1_UCS2LE = 0x02
++	, UCS2LE_Latin1 = 0x20
++	, ASCII_UCS2LE  = 0x12
++	, UCS2LE_ASCII  = 0x21
++
++	, Latin1_UTF8	= 0x03
++	, UTF8_Latin1	= 0x30
++	, ASCII_UTF8	= 0x13
++	, UTF8_ASCII	= 0x31
++	, UCS2LE_UTF8	= 0x23
++	, UTF8_UCS2LE	= 0x32
++
++	/* these aren't needed
++	 * , Latin1_UCS2BE = 0x03
++	 * , UCS2BE_Latin1 = 0x30
++	 */
++};
++
++
+ /** 
+  * Inputs are FreeTDS canonical names, no other. No alias list is consulted.  
+  */
+
+commit 7d08003fe0af9d7747bd122a4ca86dc3a7fa1dee
+Author: freddy77 <freddy77>
+Date:   Sat Jul 3 06:57:01 2010 +0000
+
+    other wide encoding merges
+
+diff --git a/ChangeLog b/ChangeLog
+index ff202b1..c815f77 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jul  3 08:56:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/error.c src/odbc/odbc.c src/odbc/sqlwparams.h:
++	- other wide encoding merges
++
+ Sat Jul  3 01:55:38 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsiconv.h src/replacements/iconv.c:
+ 	- cleanup iconv replacement
+@@ -2566,4 +2570,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3052 2010/07/02 23:55:50 freddy77 Exp $
++$Id: ChangeLog,v 1.3053 2010/07/03 06:57:01 freddy77 Exp $
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 7f52af1..f2dd7f6 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.61 2010/07/02 14:07:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.62 2010/07/03 06:57:02 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -500,9 +500,9 @@ sqlstate2to3(char *state)
+ 	SQLS_MAP("S1T00", "HYT00");
+ }
+ 
+-static SQLRETURN
+-_SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState,
+-	       SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
++#define FUNC NAME(SQLGetDiagRec) (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord), PCHAR(szSqlState),\
++	P(SQLINTEGER FAR *,pfNativeError), PCHAR(szErrorMsg), P(SQLSMALLINT,cbErrorMsgMax), P(SQLSMALLINT FAR *,pcbErrorMsg) WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLRETURN result;
+ 	struct _sql_errors *errs;
+@@ -514,6 +514,9 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 
+ 	SQLINTEGER odbc_ver = SQL_OV_ODBC2;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n",
++			handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
++
+ 	if (numRecord <= 0 || cbErrorMsgMax < 0)
+ 		return SQL_ERROR;
+ 
+@@ -551,9 +554,9 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 
+ 	if (szSqlState) {
+ 		if (odbc_ver == SQL_OV_ODBC3)
+-			strcpy((char *) szSqlState, errs->errs[numRecord].state3);
++			odbc_set_string(dbc, szSqlState, 24, NULL, errs->errs[numRecord].state3, -1 _wide);
+ 		else
+-			strcpy((char *) szSqlState, errs->errs[numRecord].state2);
++			odbc_set_string(dbc, szSqlState, 24, NULL, errs->errs[numRecord].state2, -1 _wide);
+ 	}
+ 
+ 	msg = errs->errs[numRecord].msg;
+@@ -605,24 +608,6 @@ _SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord,
+ 	return result;
+ }
+ 
+-#if (ODBCVER >= 0x0300)
+-SQLRETURN ODBC_API
+-SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, SQLCHAR FAR * szSqlState,
+-	      SQLINTEGER FAR * pfNativeError, SQLCHAR * szErrorMsg, SQLSMALLINT cbErrorMsgMax, SQLSMALLINT FAR * pcbErrorMsg)
+-{
+-	SQLRETURN ret;
+-	
+-	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec(%d, %p, %d, %p, %p, %p, %d, %p)\n", 
+-			handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+-	
+-	ret =_SQLGetDiagRec(handleType, handle, numRecord, szSqlState, pfNativeError, szErrorMsg, cbErrorMsgMax, pcbErrorMsg);
+-	
+-	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec returning %d\n", ret);
+-	
+-	return ret;
+-}
+-
+-
+ #define FUNC NAME(SQLGetDiagField) (P(SQLSMALLINT,handleType), P(SQLHANDLE,handle), P(SQLSMALLINT,numRecord),\
+ 	P(SQLSMALLINT,diagIdentifier), P(SQLPOINTER,buffer), P(SQLSMALLINT,cbBuffer), P(SQLSMALLINT FAR *,pcbBuffer) WIDE)
+ #include "sqlwparams.h"
+@@ -803,4 +788,4 @@ SQLGetDiagRec(SQLSMALLINT handleType, SQLHANDLE handle, SQLSMALLINT numRecord, S
+ 	}
+ 	return result;
+ }
+-#endif
++
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 23eae1d..0a782af 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -60,7 +60,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.538 2010/07/02 14:07:57 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.539 2010/07/03 06:57:02 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -71,9 +71,6 @@ static SQLRETURN _SQLFreeEnv(SQLHENV henv);
+ static SQLRETURN _SQLFreeStmt(SQLHSTMT hstmt, SQLUSMALLINT fOption, int force);
+ static SQLRETURN _SQLFreeDesc(SQLHDESC hdesc);
+ static SQLRETURN _SQLExecute(TDS_STMT * stmt);
+-static SQLRETURN _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength,
+-					    SQLINTEGER * StringLength);
+-static SQLRETURN _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength _WIDE);
+ static SQLRETURN _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength);
+ static SQLRETURN _SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength,
+ 					 SQLINTEGER * StringLength);
+@@ -256,7 +253,7 @@ change_autocommit(TDS_DBC * dbc, int state)
+ }
+ 
+ static SQLRETURN
+-change_database(TDS_DBC * dbc, char *database, int database_len)
++change_database(TDS_DBC * dbc, const char *database, int database_len)
+ {
+ 	TDSSOCKET *tds = dbc->tds_socket;
+ 
+@@ -518,7 +515,7 @@ odbc_prepare(TDS_STMT *stmt)
+ 
+ #ifdef TDS_NO_DM
+ 	/* Check string length */
+-	if (!IS_VALID_LEN(conlen) || conlen == 0) {
++	if (!IS_VALID_LEN(cbConnStrIn) || cbConnStrIn == 0) {
+ 		odbc_errs_add(&dbc->errs, "HY090", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+@@ -1834,7 +1831,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 	}
+ 
+ 	/* data source name */
+-	if (szDSN || (*szDSN))
++	if (odbc_get_string_size(cbDSN, szDSN _wide))
+ 		odbc_dstr_copy(dbc, &dbc->dsn, cbDSN, szDSN _wide);
+ 	else
+ 		tds_dstr_copy(&dbc->dsn, "DEFAULT");
+@@ -1853,7 +1850,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 	 * so you do not check in ini file
+ 	 */
+ 	/* user id */
+-	if (szUID && (*szUID)) {
++	if (odbc_get_string_size(cbUID, szUID _wide)) {
+ 		if (!odbc_dstr_copy(dbc, &connection->user_name, cbUID, szUID _wide)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+@@ -2184,7 +2181,7 @@ SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLColAttribute(%p, %u, %u, %p, %d, %p, %p)\n", 
+ 			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
+ 
+-	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
++	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc _wide0);
+ }
+ #endif
+ 
+@@ -4655,8 +4652,9 @@ SQLSetParam(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fCType, SQLSMALLINT f
+ 	ODBC_RETURN_(stmt);
+ }
+ 
+-static SQLRETURN
+-_SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)
++#define FUNC NAME(SQLGetConnectAttr) (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOINTER,Value), P(SQLINTEGER,BufferLength),\
++	P(SQLINTEGER *,StringLength) WIDE)
++#include "sqlwparams.h"
+ {
+ 	const char *p = NULL;
+ 	SQLRETURN rc;
+@@ -4734,17 +4732,6 @@ _SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTE
+ 	ODBC_RETURN(dbc, rc);
+ }
+ 
+-#if ODBCVER >= 0x300
+-SQLRETURN ODBC_API
+-SQLGetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)
+-{
+-	tdsdump_log(TDS_DBG_FUNC, "SQLGetConnectAttr(%p, %d, %p, %d, %p)\n", 
+-			hdbc, (int)Attribute, Value, (int)BufferLength, StringLength);
+-
+-	return _SQLGetConnectAttr(hdbc, Attribute, Value, BufferLength, StringLength);
+-}
+-#endif
+-
+ SQLRETURN ODBC_API
+ SQLGetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam)
+ {
+@@ -6034,8 +6021,8 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ }
+ 
+ 
+-static SQLRETURN
+-_SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength _WIDE)
++#define FUNC NAME(SQLSetConnectAttr) (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOINTER,ValuePtr), P(SQLINTEGER,StringLength) _WIDE)
++#include "sqlwparams.h"
+ {
+ 	SQLULEN u_value = (SQLULEN) (TDS_INTPTR) ValuePtr;
+ 	int len = 0;
+@@ -6124,15 +6111,6 @@ _SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLI
+ }
+ 
+ SQLRETURN ODBC_API
+-SQLSetConnectAttr(SQLHDBC hdbc, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength)
+-{
+-	tdsdump_log(TDS_DBG_FUNC, "SQLSetConnectAttr(%p, %d, %p, %d)\n", 
+-			hdbc, (int)Attribute, ValuePtr, (int)StringLength);
+-
+-	return _SQLSetConnectAttr(hdbc, Attribute, ValuePtr, StringLength _wide0);
+-}
+-
+-SQLRETURN ODBC_API
+ SQLSetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLSetConnectOption(%p, %d, %u)\n", hdbc, fOption, (unsigned)vParam);
+diff --git a/src/odbc/sqlwparams.h b/src/odbc/sqlwparams.h
+index aef02d4..ad0fd36 100644
+--- a/src/odbc/sqlwparams.h
++++ b/src/odbc/sqlwparams.h
+@@ -1,5 +1,19 @@
+ //#define FUNC NAME(SQLTest) (P(SQLSMALLINT, x), PCHAR(y) WIDE)
+ 
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) _ ## a
++#define WIDE
++#define P(a,b) a b
++#define PCHAR(a) SQLCHAR* a
++static SQLRETURN FUNC;
++
++
++
++#undef NAME
+ #undef WIDE
+ #undef P
+ #undef PCHAR
+@@ -7,6 +21,30 @@
+ #define WIDE
+ #define P(a,b) a b
+ #define PCHAR(a) SQLCHAR* a
+-SQLRETURN ODBC_API FUNC
++SQLRETURN ODBC_API FUNC {
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) _ ## a
++#define WIDE
++#define P(a,b) b
++#define PCHAR(a) a
++	return FUNC;
++}
++
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) _ ## a
++#define WIDE
++#define P(a,b) a b
++#define PCHAR(a) SQLCHAR* a
++static SQLRETURN FUNC
++
++
+ 
+ #undef FUNC
+
+commit a3054eb29333b25f0039b0a398491ed841832112
+Author: freddy77 <freddy77>
+Date:   Sat Jul 3 06:57:56 2010 +0000
+
+    rewrote iconv replacement adding support for ucs4
+
+diff --git a/ChangeLog b/ChangeLog
+index c815f77..9a6fb71 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jul  3 08:57:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/replacements/iconv.c:
++	- rewrote iconv replacement adding support for ucs4
++
+ Sat Jul  3 08:56:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/error.c src/odbc/odbc.c src/odbc/sqlwparams.h:
+ 	- other wide encoding merges
+@@ -2570,4 +2574,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3053 2010/07/03 06:57:01 freddy77 Exp $
++$Id: ChangeLog,v 1.3054 2010/07/03 06:57:56 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 07d133f..392c4d0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.49 2010/06/27 05:58:09 freddy77 Exp $
++dnl $Id: configure.ac,v 1.50 2010/07/03 06:57:56 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.49 $)
++AC_REVISION($Revision: 1.50 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -100,6 +100,7 @@ if test "$use_libiconv" = "yes" ; then
+ 	AM_ICONV
+ else 
+ 	AC_MSG_NOTICE(libiconv disabled)	
++	AC_DEFINE_UNQUOTED(ICONV_CONST, const, [Define as const if the declaration of iconv() needs const.])
+ fi
+ 
+ 
+diff --git a/src/replacements/iconv.c b/src/replacements/iconv.c
+index 8f9a1ae..0ea8445 100644
+--- a/src/replacements/iconv.c
++++ b/src/replacements/iconv.c
+@@ -22,12 +22,7 @@
+  * Its purpose is to allow ASCII clients to communicate with Microsoft servers
+  * that encode their metadata in Unicode (UCS-2).  
+  *
+- * The conversion algorithm relies on the fact that UCS-2 shares codepoints
+- * between 0 and 255 with ISO-8859-1.  To create UCS-2, we add a high byte
+- * whose value is zero.  To create ISO-8859-1, we strip the high byte.  
+- *
+- * If we receive an input character whose value is greater than 255, we return an 
+- * out-of-range error.  The caller (tds_iconv) should emit an error message.  
++ * It supports ISO-8859-1, ASCII, UCS-2, UCS-4 and UTF-8
+  */
+ 
+ #if HAVE_CONFIG_H
+@@ -47,52 +42,257 @@
+ #include <ctype.h>
+ 
+ #include "tds.h"
++#include "tdsbytes.h"
+ #include "tdsiconv.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.17 2010/07/02 23:55:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.18 2010/07/03 06:57:56 freddy77 Exp $");
+ 
+ /**
+  * \addtogroup conv
+  * @{ 
+  */
+ 
+-	/* FYI, the first 4 entries look like this:
+-	 *      {"ISO-8859-1",  1, 1}, -> 0
+-	 *      {"US-ASCII",    1, 4}, -> 1
+-	 *      {"UCS-2LE",     2, 2}, -> 2
+-	 *      {"UCS-2BE",     2, 2}, -> 3
+-	 *
+-	 * These conversions are supplied by src/replacements/iconv.c for the sake of those who don't
+-	 * have or otherwise need an iconv.
+-	 */
+ enum ICONV_CD_VALUE
+ {
+-	  Like_to_Like = 0x100
+-	, Latin1_ASCII  = 0x01
+-	, ASCII_Latin1  = 0x10
+-
+-	, Latin1_UCS2LE = 0x02
+-	, UCS2LE_Latin1 = 0x20
+-	, ASCII_UCS2LE  = 0x12
+-	, UCS2LE_ASCII  = 0x21
+-
+-	, Latin1_UTF8	= 0x03
+-	, UTF8_Latin1	= 0x30
+-	, ASCII_UTF8	= 0x13
+-	, UTF8_ASCII	= 0x31
+-	, UCS2LE_UTF8	= 0x23
+-	, UTF8_UCS2LE	= 0x32
+-
+-	/* these aren't needed
+-	 * , Latin1_UCS2BE = 0x03
+-	 * , UCS2BE_Latin1 = 0x30
+-	 */
++	Like_to_Like = 0x100
++};
++
++typedef TDS_UINT ICONV_CHAR;
++
++static const unsigned char utf_lengths[256] = {
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
++	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
++	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
++	2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
++	3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
++	4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 0, 0,
++};
++
++static const unsigned char utf_masks[7] = {
++	0, 0x7f, 0x1f, 0x0f, 0x07, 0x03, 0x01
+ };
+ 
++static int
++get_utf(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	ICONV_CHAR uc;
++	int l;
++
++	l = utf_lengths[p[0]];
++	if (TDS_UNLIKELY(l == 0))
++		return -EILSEQ;
++	if (TDS_UNLIKELY(len < l))
++		return -EINVAL;
++
++	len = l;
++	uc = *p++ & utf_masks[l];
++	while(--l)
++		uc = (uc << 6) | (*p++ & 0x3f);
++	*out = uc;
++	return len;
++}
++
++static int
++put_utf(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++#define MASK(n) ((0xffffffffu << (n)) & 0xffffffffu)
++	int o_len;
++	unsigned mask;
++
++	if ((c & MASK(7)) == 0) {
++		if (buf_len < 1)
++			return -E2BIG;
++		*buf = (unsigned char) c;
++		return 1;
++	}
++
++	o_len = 2;
++	for (;;) {
++		if ((c & MASK(11)) == 0)
++			break;
++		++o_len;
++		if ((c & MASK(16)) == 0)
++			break;
++		++o_len;
++		if ((c & MASK(21)) == 0)
++			break;
++		++o_len;
++		if ((c & MASK(26)) == 0)
++			break;
++		++o_len;
++		if ((c & MASK(31)) != 0)
++			return -EINVAL;
++	}
++
++	if (buf_len < o_len)
++		return -E2BIG;
++	buf += o_len;
++	mask = 0xff80;
++	for (;;) {
++		*--buf = 0x80 | (c & 0x3f);
++		c >>= 6;
++		mask >>= 1;
++		if (c < 0x40) {
++			*--buf = mask | c;
++			break;
++		}
++	}
++	return o_len;
++}
++
++static int
++get_ucs4le(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	if (len < 4)
++		return -EINVAL;
++	*out = TDS_GET_A4LE(p);
++	return 4;
++}
++
++static int
++put_ucs4le(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	if (buf_len < 4)
++		return -E2BIG;
++	TDS_PUT_A4LE(buf, c);
++	return 4;
++}
++
++static int
++get_ucs4be(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	if (len < 4)
++		return -EINVAL;
++	*out = TDS_GET_A4BE(p);
++	return 4;
++}
++
++static int
++put_ucs4be(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	if (buf_len < 4)
++		return -E2BIG;
++	TDS_PUT_A4BE(buf, c);
++	return 4;
++}
++
++static int
++get_ucs2le(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	if (len < 2)
++		return -EINVAL;
++	*out = TDS_GET_A2LE(p);
++	return 2;
++}
++
++static int
++put_ucs2le(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	if (c >= 0x10000u)
++		return -EINVAL;
++	if (buf_len < 2)
++		return -E2BIG;
++	TDS_PUT_A2LE(buf, c);
++	return 2;
++}
++
++static int
++get_ucs2be(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	if (len < 2)
++		return -EINVAL;
++	*out = TDS_GET_A2BE(p);
++	return 2;
++}
++
++static int
++put_ucs2be(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	if (c >= 0x10000u)
++		return -EINVAL;
++	if (buf_len < 2)
++		return -E2BIG;
++	TDS_PUT_A2BE(buf, c);
++	return 2;
++}
++
++static int
++get_iso1(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	if (len < 1)
++		return -EINVAL;
++	*out = p[0];
++	return 1;
++}
++
++static int
++put_iso1(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	if (c >= 0x100u)
++		return -EINVAL;
++	if (buf_len < 1)
++		return -E2BIG;
++	buf[0] = (unsigned char) c;
++	return 1;
++}
++
++static int
++get_ascii(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	if (len < 1)
++		return -EINVAL;
++	if (p[0] >= 0x80)
++		return -EILSEQ;
++	*out = p[0];
++	return 1;
++}
++
++static int
++put_ascii(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	if (c >= 0x80u)
++		return -EINVAL;
++	if (buf_len < 1)
++		return -E2BIG;
++	buf[0] = (unsigned char) c;
++	return 1;
++}
++
++static int
++get_err(const unsigned char *p, int len, ICONV_CHAR *out)
++{
++	return -EILSEQ;
++}
++
++static int
++put_err(unsigned char *buf, int buf_len, ICONV_CHAR c)
++{
++	return -EINVAL;
++}
++
++typedef int (*iconv_get_t)(const unsigned char *p, int len,     ICONV_CHAR *out);
++typedef int (*iconv_put_t)(unsigned char *buf,     int buf_len, ICONV_CHAR c);
++
++static const iconv_get_t iconv_gets[8] = {
++	get_iso1, get_ascii, get_ucs2le, get_ucs2be, get_ucs4le, get_ucs4be, get_utf, get_err
++};
++static const iconv_put_t iconv_puts[8] = {
++	put_iso1, put_ascii, put_ucs2le, put_ucs2be, put_ucs4le, put_ucs4be, put_utf, put_err
++};
+ 
+ /** 
+  * Inputs are FreeTDS canonical names, no other. No alias list is consulted.  
+@@ -103,7 +303,7 @@ tds_sys_iconv_open (const char* tocode, const char* fromcode)
+ 	int i;
+ 	unsigned int fromto;
+ 	const char *enc_name;
+-	unsigned char encodings[2] = { 0xFF, 0xFF };
++	unsigned char encodings[2];
+ 
+ 	static char first_time = 1;
+ 
+@@ -115,48 +315,39 @@ tds_sys_iconv_open (const char* tocode, const char* fromcode)
+ 	/* match both inputs to our canonical names */
+ 	enc_name = fromcode;
+ 	for (i=0; i < 2; ++i) {
+-
+-		if (strcmp(enc_name, "ISO-8859-1") == 0) {
+-			encodings[i] = 0;
+-		} else if (strcmp(enc_name, "US-ASCII") == 0) {
+-			encodings[i] = 1;
+-		} else if (strcmp(enc_name, "UCS-2LE") == 0) {
+-			encodings[i] = 2;
+-		} else if (strcmp(enc_name, "UTF-8") == 0) {
+-			encodings[i] = 3;
++		unsigned char encoding;
++
++		if (strcmp(enc_name, "ISO-8859-1") == 0)
++			encoding = 0;
++		else if (strcmp(enc_name, "US-ASCII") == 0)
++			encoding = 1;
++		else if (strcmp(enc_name, "UCS-2LE") == 0)
++			encoding = 2;
++		else if (strcmp(enc_name, "UCS-2BE") == 0)
++			encoding = 3;
++		else if (strcmp(enc_name, "UCS-4LE") == 0)
++			encoding = 4;
++		else if (strcmp(enc_name, "UCS-4BE") == 0)
++			encoding = 5;
++		else if (strcmp(enc_name, "UTF-8") == 0)
++			encoding = 6;
++		else {
++			errno = EINVAL;
++			return (iconv_t)(-1);
+ 		}
++		encodings[i] = encoding;
+ 
+ 		enc_name = tocode;
+ 	}
+-	
++
+ 	fromto = (encodings[0] << 4) | (encodings[1] & 0x0F);
+ 
+ 	/* like to like */
+ 	if (encodings[0] == encodings[1]) {
+ 		fromto = Like_to_Like;
+ 	}
+-	
+-	switch (fromto) {
+-	case Like_to_Like:
+-	case Latin1_ASCII:
+-	case ASCII_Latin1:
+-	case Latin1_UCS2LE:
+-	case UCS2LE_Latin1:
+-	case ASCII_UCS2LE:
+-	case UCS2LE_ASCII:
+-	case Latin1_UTF8:
+-	case UTF8_Latin1:
+-	case ASCII_UTF8:
+-	case UTF8_ASCII:
+-	case UCS2LE_UTF8:
+-	case UTF8_UCS2LE:
+-		return (iconv_t) (TDS_INTPTR) fromto;
+-		break;
+-	default:
+-		break;
+-	}
+-	errno = EINVAL;
+-	return (iconv_t)(-1);
++
++	return (iconv_t) (TDS_INTPTR) fromto;
+ } 
+ 
+ int 
+@@ -168,10 +359,6 @@ tds_sys_iconv_close (iconv_t cd)
+ size_t 
+ tds_sys_iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * outbuf, size_t *outbytesleft)
+ {
+-	size_t copybytes;
+-	const unsigned char *p;
+-	unsigned char ascii_mask = 0;
+-	unsigned int n;
+ 	const unsigned char *ib;
+ 	unsigned char *ob;
+ 	size_t il, ol;
+@@ -198,198 +385,39 @@ tds_sys_iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * out
+ 	ib = (const unsigned char*) *inbuf;
+ 	ob = (unsigned char*) *outbuf;
+ 
+-	copybytes = (il < ol)? il : ol;
++	if (CD == Like_to_Like) {
++		size_t copybytes = (il < ol)? il : ol;
+ 
+-	switch (CD) {
+-	case ASCII_UTF8:
+-	case UTF8_ASCII:
+-	case Latin1_ASCII:
+-		for (p = ib; p < ib + il; ++p) {
+-			if (*p & 0x80) {
+-				local_errno = EILSEQ;
+-				copybytes = p - ib;
+-				break;
+-			}
+-		}
+-		/* fall through */
+-	case ASCII_Latin1:
+-	case Like_to_Like:
+ 		memcpy(ob, ib, copybytes);
+ 		ob += copybytes;
+ 		ol -= copybytes;
+ 		ib += copybytes;
+ 		il -= copybytes;
+-		break;
+-	case ASCII_UCS2LE:
+-	case Latin1_UCS2LE:
+-		if (CD == ASCII_UCS2LE)
+-			ascii_mask = 0x80;
+-		while (il > 0 && ol > 1) {
+-			if ((ib[0] & ascii_mask) != 0) {
+-				local_errno = EILSEQ;
+-				break;
+-			}
+-			*ob++ = *ib++;
+-			*ob++ = '\0';
+-			ol -= 2;
+-			--il;
+-		}
+-		break;
+-	case UCS2LE_ASCII:
+-	case UCS2LE_Latin1:
+-		if (CD == UCS2LE_ASCII)
+-			ascii_mask = 0x80;
+-		while (il > 1 && ol > 0) {
+-			if ( ib[1] || (ib[0] & ascii_mask) != 0) {
+-				local_errno = EILSEQ;
+-				break;
+-			}
+-			*ob++ = *ib;
+-			--ol;
+-
+-			ib += 2;
+-			il -= 2;
+-		}
+-		/* input should be an even number of bytes */
+-		if (!local_errno && il == 1 && ol > 0)
+-			local_errno = EINVAL;
+-		break;
+-	case UTF8_Latin1:
+-		while (il > 0 && ol > 0) {
+-			/* silly case, ASCII */
+-			if ( (ib[0] & 0x80) == 0) {
+-				*ob++ = *ib++;
+-				--il;
+-				--ol;
+-				continue;
+-			}
+-
+-			if (il == 1) {
+-				local_errno = EINVAL;
+-				break;
+-			}
+-
+-			if ( ib[0] > 0xC3 || ib[0] < 0xC0 || (ib[1] & 0xC0) != 0x80) {
+-				local_errno = EILSEQ;
+-				break;
+-			}
+-
+-			*ob++ = (*ib) << 6 | (ib[1] & 0x3F);
+-			--ol;
+-			ib += 2;
+-			il -= 2;
+-		}
+-		break;
+-	case Latin1_UTF8:
+-		while (il > 0 && ol > 0) {
+-			/* silly case, ASCII */
+-			if ( (ib[0] & 0x80) == 0) {
+-				*ob++ = *ib++;
+-				--il;
+-				--ol;
+-				continue;
+-			}
+-
+-			if (ol == 1)
+-				break;
+-			*ob++ = 0xC0 | (ib[0] >> 6);
+-			*ob++ = 0x80 | (ib[0] & 0x3F);
+-			ol -= 2;
+-			++ib;
+-			--il;
+-		}
+-		break;
+-	case UTF8_UCS2LE:
+-		while (il > 0 && ol > 1) {
+-			/* silly case, ASCII */
+-			if ( (ib[0] & 0x80) == 0) {
+-				*ob++ = *ib++;
+-				*ob++ = 0;
+-				il -= 1;
+-				ol -= 2;
+-				continue;
+-			}
+-
+-			if (il == 1) {
+-				local_errno = EINVAL;
+-				break;
+-			}
++	} else if (CD & ~0x77) {
++		local_errno = EINVAL;
++	} else {
++		iconv_get_t get_func = iconv_gets[(CD>>4) & 7];
++		iconv_put_t put_func = iconv_puts[ CD     & 7];
+ 
+-			if ( (ib[0] & 0xE0) == 0xC0) {
+-				if ( (ib[1] & 0xC0) != 0x80) {
+-					local_errno = EILSEQ;
+-					break;
+-				}
+-
+-				*ob++ = ((ib[0] & 0x3) << 6) | (ib[1] & 0x3F);
+-				*ob++ = (ib[0] & 0x1F) >> 2;
+-				ol -= 2;
+-				ib += 2;
+-				il -= 2;
+-				continue;
+-			}
++		while (il) {
++			ICONV_CHAR out_c;
++			int readed = get_func(ib, il, &out_c), written;
+ 
+-			if (il == 2) {
+-				local_errno = EINVAL;
++			if (TDS_UNLIKELY(readed < 0)) {
++				local_errno = -readed;
+ 				break;
+ 			}
+ 
+-			if ( (ib[0] & 0xF0) == 0xE0) {
+-				if ( (ib[1] & 0xC0) != 0x80 || (ib[2] & 0xC0) != 0x80) {
+-					local_errno = EILSEQ;
+-					break;
+-				}
+-
+-				*ob++ = ((ib[1] & 0x3) << 6) | (ib[2] & 0x3F);
+-				*ob++ = (ib[0] & 0xF) << 4 | ((ib[1] & 0x3F) >> 2);
+-				ol -= 2;
+-				ib += 3;
+-				il -= 3;
+-				continue;
+-			}
+-
+-			local_errno = EILSEQ;
+-			break;
+-		}
+-		break;
+-	case UCS2LE_UTF8:
+-		while (il > 1 && ol > 0) {
+-			n = ((unsigned int)ib[1]) << 8 | ib[0];
+-			/* ASCII */
+-			if ( n < 0x80 ) {
+-				*ob++ = n;
+-				ol -= 1;
+-				ib += 2;
+-				il -= 2;
+-				continue;
+-			}
+-
+-			if (ol == 1)
++			written = put_func(ob, ol, out_c);
++			if (TDS_UNLIKELY(written < 0)) {
++				local_errno = -readed;
+ 				break;
+-
+-			if ( n < 0x800 ) {
+-				*ob++ = 0xC0 | (n >> 6);
+-				*ob++ = 0x80 | (n & 0x3F);
+-				ol -= 2;
+-				ib += 2;
+-				il -= 2;
+-				continue;
+ 			}
+-
+-			if (ol == 2)
+-				break;
+-
+-			*ob++ = 0xE0 | (n >> 12);
+-			*ob++ = 0x80 | ((n >> 6) & 0x3F);
+-			*ob++ = 0x80 | (n & 0x3F);
+-			ol -= 3;
+-			ib += 2;
+-			il -= 2;
++			il -= readed;
++			ib += readed;
++			ol -= written;
++			ob += written;
+ 		}
+-		break;
+-	default:
+-		local_errno = EINVAL;
+-		break;
+ 	}
+ 
+ 	/* back to source */
+
+commit 27cc5fdaa9d3aaaa1e8a21ec7481740443d1d18f
+Author: freddy77 <freddy77>
+Date:   Sat Jul 3 08:53:13 2010 +0000
+
+    fix return codes from replacement iconv
+
+diff --git a/ChangeLog b/ChangeLog
+index 9a6fb71..f1d23be 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul  3 10:53:03 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/replacements/iconv.c: fix return codes from replacement iconv
++
+ Sat Jul  3 08:57:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/replacements/iconv.c:
+ 	- rewrote iconv replacement adding support for ucs4
+@@ -2574,4 +2577,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3054 2010/07/03 06:57:56 freddy77 Exp $
++$Id: ChangeLog,v 1.3055 2010/07/03 08:53:13 freddy77 Exp $
+diff --git a/src/replacements/iconv.c b/src/replacements/iconv.c
+index 0ea8445..b6d79e2 100644
+--- a/src/replacements/iconv.c
++++ b/src/replacements/iconv.c
+@@ -49,7 +49,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.18 2010/07/03 06:57:56 freddy77 Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.19 2010/07/03 08:53:13 freddy77 Exp $");
+ 
+ /**
+  * \addtogroup conv
+@@ -203,7 +203,7 @@ static int
+ put_ucs2le(unsigned char *buf, int buf_len, ICONV_CHAR c)
+ {
+ 	if (c >= 0x10000u)
+-		return -EINVAL;
++		return -EILSEQ;
+ 	if (buf_len < 2)
+ 		return -E2BIG;
+ 	TDS_PUT_A2LE(buf, c);
+@@ -223,7 +223,7 @@ static int
+ put_ucs2be(unsigned char *buf, int buf_len, ICONV_CHAR c)
+ {
+ 	if (c >= 0x10000u)
+-		return -EINVAL;
++		return -EILSEQ;
+ 	if (buf_len < 2)
+ 		return -E2BIG;
+ 	TDS_PUT_A2BE(buf, c);
+@@ -243,7 +243,7 @@ static int
+ put_iso1(unsigned char *buf, int buf_len, ICONV_CHAR c)
+ {
+ 	if (c >= 0x100u)
+-		return -EINVAL;
++		return -EILSEQ;
+ 	if (buf_len < 1)
+ 		return -E2BIG;
+ 	buf[0] = (unsigned char) c;
+@@ -265,7 +265,7 @@ static int
+ put_ascii(unsigned char *buf, int buf_len, ICONV_CHAR c)
+ {
+ 	if (c >= 0x80u)
+-		return -EINVAL;
++		return -EILSEQ;
+ 	if (buf_len < 1)
+ 		return -E2BIG;
+ 	buf[0] = (unsigned char) c;
+@@ -281,7 +281,7 @@ get_err(const unsigned char *p, int len, ICONV_CHAR *out)
+ static int
+ put_err(unsigned char *buf, int buf_len, ICONV_CHAR c)
+ {
+-	return -EINVAL;
++	return -EILSEQ;
+ }
+ 
+ typedef int (*iconv_get_t)(const unsigned char *p, int len,     ICONV_CHAR *out);
+@@ -410,7 +410,7 @@ tds_sys_iconv (iconv_t cd, const char* * inbuf, size_t *inbytesleft, char* * out
+ 
+ 			written = put_func(ob, ol, out_c);
+ 			if (TDS_UNLIKELY(written < 0)) {
+-				local_errno = -readed;
++				local_errno = -written;
+ 				break;
+ 			}
+ 			il -= readed;
+
+commit c7e066e72fab46e7a31660762cffd5f1e523fbd8
+Author: freddy77 <freddy77>
+Date:   Sat Jul 3 09:14:36 2010 +0000
+
+    add ODBC wide support (disabled by default and still experimental)
+
+diff --git a/ChangeLog b/ChangeLog
+index f1d23be..58ea7f1 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,10 @@
++Sat Jul  3 11:14:29 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tdsodbc.h src/odbc/convert_tds2sql.c:
++	* src/odbc/odbc.c src/odbc/odbc_util.c src/odbc/sql2tds.c:
++	* src/odbc/sqlwparams.h:
++	- add ODBC wide support (disabled by default and still
++	  experimental)
++
+ Sat Jul  3 10:53:03 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/replacements/iconv.c: fix return codes from replacement iconv
+ 
+@@ -2577,4 +2584,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3055 2010/07/03 08:53:13 freddy77 Exp $
++$Id: ChangeLog,v 1.3056 2010/07/03 09:14:36 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 392c4d0..245e377 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.50 2010/07/03 06:57:56 freddy77 Exp $
++dnl $Id: configure.ac,v 1.51 2010/07/03 09:14:36 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.50 $)
++AC_REVISION($Revision: 1.51 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -769,6 +769,15 @@ if test "$enable_developing" = "yes" ; then
+ 	AC_DEFINE_UNQUOTED(ENABLE_DEVELOPING, 1, [Define to enable work in progress code])
+ fi
+ 
++AC_ARG_ENABLE(odbc-wide,
++  AS_HELP_STRING([--enable-odbc-wide], [enable wide string support in odbc [experimental]]))
++if test "$enable_odbc_wide" = "yes" ; then
++	if test "$use_libiconv" != "yes" ; then
++		AC_MSG_ERROR([iconv required for ODBC wide support.])
++	fi
++	AC_DEFINE_UNQUOTED(ENABLE_ODBC_WIDE, 1, [Define to enable ODBC wide string support. Require libiconv!])
++fi
++
+ AC_ARG_ENABLE(distcheck_build,
+   AS_HELP_STRING([--enable-distcheck-build], [used internally for testing]))
+ if test "$enable_distcheck_build" = "yes" ; then
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 8dba90e..8d0d972 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.122 2010/07/02 13:38:24 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.123 2010/07/03 09:14:36 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -250,6 +250,11 @@ struct _hdbc
+ 	TDSSOCKET *tds_socket;
+ 	DSTR dsn;
+ 	DSTR server;		/* aka Instance */
++#ifdef ENABLE_ODBC_WIDE
++	DSTR original_charset;
++	TDSICONV *mb_conv;
++#endif
++
+ 	/**
+ 	 * Statement executing. This should be set AFTER sending query
+ 	 * to avoid race condition and assure to not overwrite it if
+@@ -531,13 +536,24 @@ void odbc_check_desc_extra(TDS_DESC * desc);
+ /*
+  * odbc_util.h
+  */
++
+ /* helpers for ODBC wide string support */
+ #undef _wide
+ #undef _WIDE
++#ifdef ENABLE_ODBC_WIDE
++typedef union {
++	char mb[1];
++	SQLWCHAR wide[1];
++} ODBC_CHAR;
++# define _wide ,wide
++# define _wide0 ,0
++# define _WIDE ,int wide
++#else
+ # define _wide
+ # define _wide0
+ # define _WIDE
+ # define ODBC_CHAR SQLCHAR
++#endif
+ int odbc_set_stmt_query(struct _hstmt *stmt, const ODBC_CHAR *sql, int sql_len _WIDE);
+ int odbc_set_stmt_prepared_query(struct _hstmt *stmt, const ODBC_CHAR *sql, int sql_len _WIDE);
+ void odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row);
+@@ -556,10 +572,17 @@ SQLINTEGER odbc_get_param_len(const struct _drecord *drec_axd, const struct _dre
+ DSTR* odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE);
+ 
+ SQLRETURN odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag);
++#ifdef ENABLE_ODBC_WIDE
++static inline SQLRETURN odbc_set_string(TDS_DBC *dbc, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len _WIDE)
++{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0|wide); }
++static inline SQLRETURN odbc_set_string_i(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len _WIDE)
++{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0x10|wide); }
++#else
+ static inline SQLRETURN odbc_set_string(TDS_DBC *dbc, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len _WIDE)
+ { return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0); }
+ static inline SQLRETURN odbc_set_string_i(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len _WIDE)
+ { return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0x10); }
++#endif
+ 
+ SQLSMALLINT odbc_get_concise_sql_type(SQLSMALLINT type, SQLSMALLINT interval);
+ SQLRETURN odbc_set_concise_sql_type(SQLSMALLINT concise_type, struct _drecord *drec, int check_only);
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index e523362..57e3af2 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -37,12 +37,13 @@
+ #include "tdsodbc.h"
+ #include "tdsconvert.h"
+ #include "tdsiconv.h"
++#include "tdsstring.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.70 2010/01/07 13:56:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.71 2010/07/03 09:14:36 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -66,6 +67,10 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ 		conv = tds_iconv_get(tds, ODBC_WIDE_NAME, conv->server_charset.name);
+ 		if (!conv)
+ 			conv = tds_iconv_get(tds, ODBC_WIDE_NAME, "ISO-8859-1");
++#ifdef ENABLE_ODBC_WIDE
++	} else {
++		conv = tds_iconv_get(tds, tds_dstr_cstr(&stmt->dbc->original_charset), conv->server_charset.name);
++#endif
+ 	}
+ 
+ 	ib = src;
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0a782af..a190a76 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -52,6 +52,7 @@
+ #include <ctype.h>
+ 
+ #include "tdsodbc.h"
++#include "tdsiconv.h"
+ #include "tdsstring.h"
+ #include "tdsconvert.h"
+ #include "replacements.h"
+@@ -60,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.539 2010/07/03 06:57:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.540 2010/07/03 09:14:36 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -365,6 +366,9 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ {
+ 	TDS_ENV *env = dbc->env;
+ 
++#ifdef ENABLE_ODBC_WIDE
++	dbc->mb_conv = NULL;
++#endif
+ 	dbc->tds_socket = tds_alloc_socket(env->tds_ctx, 512);
+ 	if (!dbc->tds_socket) {
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+@@ -380,12 +384,21 @@ odbc_connect(TDS_DBC * dbc, TDSCONNECTION * connection)
+ 
+ 	connection->connect_timeout = dbc->attr.connection_timeout;
+ 
++#ifdef ENABLE_ODBC_WIDE
++	/* force utf-8 in order to support wide characters */
++	tds_dstr_dup(&dbc->original_charset, &connection->client_charset);
++	tds_dstr_copy(&connection->client_charset, "UTF-8");
++#endif
++
+ 	if (tds_connect_and_login(dbc->tds_socket, connection) != TDS_SUCCEED) {
+ 		tds_free_socket(dbc->tds_socket);
+ 		dbc->tds_socket = NULL;
+ 		odbc_errs_add(&dbc->errs, "08001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
++#ifdef ENABLE_ODBC_WIDE
++	dbc->mb_conv = tds_iconv_get(dbc->tds_socket, tds_dstr_cstr(&dbc->original_charset), "UTF-8");
++#endif
+ 
+ 	dbc->default_query_timeout = dbc->tds_socket->query_timeout;
+ 
+@@ -505,8 +518,8 @@ odbc_prepare(TDS_STMT *stmt)
+ #include "sqlwparams.h"
+ {
+ 	TDSCONNECTION *connection;
+-	int conlen = odbc_get_string_size(cbConnStrIn, szConnStrIn);
+ 	TDS_PARSED_PARAM params[ODBC_PARAM_SIZE];
++	DSTR conn_str;
+ 
+ 	INIT_HDBC;
+ 
+@@ -533,8 +546,15 @@ odbc_prepare(TDS_STMT *stmt)
+ 	}
+ #endif
+ 
++	tds_dstr_init(&conn_str);
++	if (!odbc_dstr_copy(dbc, &conn_str, cbConnStrIn, szConnStrIn _wide)) {
++		odbc_errs_add(&dbc->errs, "HY001", NULL);
++		ODBC_RETURN(dbc, SQL_ERROR);
++	}
++
+ 	connection = tds_alloc_connection(dbc->env->tds_ctx->locale);
+ 	if (!connection) {
++		tds_dstr_free(&conn_str);
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+@@ -543,11 +563,14 @@ odbc_prepare(TDS_STMT *stmt)
+ 		tds_dstr_dup(&connection->database, &dbc->attr.current_catalog);
+ 
+ 	/* parse the DSN string */
+-	if (!odbc_parse_connect_string(&dbc->errs, (const char *) szConnStrIn, (const char *) szConnStrIn + conlen,
+-				       connection, params))
++	if (!odbc_parse_connect_string(&dbc->errs, tds_dstr_buf(&conn_str), tds_dstr_buf(&conn_str) + tds_dstr_len(&conn_str),
++				       connection, params)) {
++		tds_dstr_free(&conn_str);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
++	}
+ 
+-	odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, (const char *) szConnStrIn, conlen _wide);
++	odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, tds_dstr_buf(&conn_str), tds_dstr_len(&conn_str) _wide);
++	tds_dstr_free(&conn_str);
+ 
+ 	/* add login info */
+ 	if (hwnd && fDriverCompletion != SQL_DRIVER_NOPROMPT
+@@ -1492,6 +1515,9 @@ _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc)
+ 	tds_dstr_init(&dbc->attr.tracefile);
+ #endif
+ 	tds_dstr_init(&dbc->attr.translate_lib);
++#ifdef ENABLE_ODBC_WIDE
++	tds_dstr_init(&dbc->original_charset);
++#endif
+ 	dbc->attr.translate_option = 0;
+ 	dbc->attr.txn_isolation = SQL_TXN_READ_COMMITTED;
+ 
+@@ -2178,11 +2204,27 @@ SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
+ #endif
+ 	)
+ {
+-	tdsdump_log(TDS_DBG_FUNC, "SQLColAttribute(%p, %u, %u, %p, %d, %p, %p)\n", 
+-			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
+ 
+ 	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc _wide0);
+ }
++
++#ifdef ENABLE_ODBC_WIDE
++SQLRETURN ODBC_API
++SQLColAttributeW(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
++		SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT FAR * pcbDesc,
++#ifdef TDS_SQLCOLATTRIBUTE_SQLLEN
++		SQLLEN FAR * pfDesc
++#else
++		SQLPOINTER pfDesc
++#endif
++	)
++{
++	tdsdump_log(TDS_DBG_FUNC, "SQLColAttributeW(%p, %u, %u, %p, %d, %p, %p)\n",
++			hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc);
++
++	return _SQLColAttribute(hstmt, icol, fDescType, rgbDesc, cbDescMax, pcbDesc, pfDesc, 1);
++}
++#endif
+ #endif
+ 
+ SQLRETURN ODBC_API
+@@ -2206,6 +2248,9 @@ SQLDisconnect(SQLHDBC hdbc)
+ 		}
+ 	}
+ 
++#ifdef ENABLE_ODBC_WIDE
++	dbc->mb_conv = NULL;
++#endif
+ 	tds_free_socket(dbc->tds_socket);
+ 	dbc->tds_socket = NULL;
+ 	dbc->cursor_support = 0;
+@@ -3976,6 +4021,9 @@ _SQLFreeConnect(SQLHDBC hdbc)
+ 	tds_dstr_free(&dbc->attr.current_catalog);
+ 	tds_dstr_free(&dbc->attr.translate_lib);
+ 
++#ifdef ENABLE_ODBC_WIDE
++	tds_dstr_free(&dbc->original_charset);
++#endif
+ 	tds_dstr_free(&dbc->server);
+ 	tds_dstr_free(&dbc->dsn);
+ 
+@@ -5769,6 +5817,21 @@ SQLGetInfo(SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMA
+ 
+ 	ODBC_RETURN(dbc, _SQLGetInfo(dbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue _wide0));
+ }
++
++#ifdef ENABLE_ODBC_WIDE
++SQLRETURN ODBC_API
++SQLGetInfoW(SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMALLINT cbInfoValueMax,
++	   SQLSMALLINT FAR * pcbInfoValue)
++{
++	INIT_HDBC;
++
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetInfo(%p, %d, %p, %d, %p)\n",
++			hdbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue);
++
++	ODBC_RETURN(dbc, _SQLGetInfo(dbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue, 1));
++}
++#endif
++
+ static void
+ tds_ascii_strupr(char *s)
+ {
+@@ -6025,7 +6088,6 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ #include "sqlwparams.h"
+ {
+ 	SQLULEN u_value = (SQLULEN) (TDS_INTPTR) ValuePtr;
+-	int len = 0;
+ 
+ 	INIT_HDBC;
+ 
+@@ -6049,8 +6111,19 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 			odbc_errs_add(&dbc->errs, "HY090", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
+-		len = odbc_get_string_size(StringLength, (SQLCHAR *) ValuePtr);
+-		ODBC_RETURN(dbc, change_database(dbc, (char *) ValuePtr, len));
++		{
++			DSTR s;
++			SQLRETURN ret;
++
++			tds_dstr_init(&s);
++			if (!odbc_dstr_copy(dbc, &s, StringLength, ValuePtr _wide)) {
++				odbc_errs_add(&dbc->errs, "HY001", NULL);
++				ODBC_RETURN(dbc, SQL_ERROR);
++			}
++			ret = change_database(dbc, tds_dstr_cstr(&s), tds_dstr_len(&s));
++			tds_dstr_free(&s);
++			ODBC_RETURN(dbc, ret);
++		}
+ 		break;
+ 	case SQL_ATTR_CURSOR_TYPE:
+ 		if (dbc->cursor_support) {
+@@ -6484,7 +6557,7 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 	retcode =
+ 		odbc_stat_execute(stmt _wide, "sp_special_columns ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 7 : 4, "O", szTableName,
+ 				  cbTableName, "O", szSchemaName, cbSchemaName, "O@qualifier", szCatalogName, cbCatalogName,
+-				  "@col_type", &col_type, 1, "@scope", &scope, 1, "@nullable", &nullable, 1,
++				  "!@col_type", &col_type, 1, "!@scope", &scope, 1, "!@nullable", &nullable, 1,
+ 				  "V@ODBCVer", (char*) NULL, 0);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 5, "COLUMN_SIZE");
+@@ -6547,7 +6620,7 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 	retcode =
+ 		odbc_stat_execute(stmt _wide, "sp_statistics ", TDS_IS_MSSQL(stmt->dbc->tds_socket) ? 5 : 4, "O@table_qualifier",
+ 				  szCatalogName, cbCatalogName, "O@table_owner", szSchemaName, cbSchemaName, "O@table_name",
+-				  szTableName, cbTableName, "@is_unique", &unique, 1, "@accuracy", &accuracy, 1);
++				  szTableName, cbTableName, "!@is_unique", &unique, 1, "!@accuracy", &accuracy, 1);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "TABLE_CAT");
+ 		odbc_col_setname(stmt, 2, "TABLE_SCHEM");
+@@ -6563,37 +6636,50 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ #include "sqlwparams.h"
+ {
+ 	int retcode;
+-	char *type = NULL;
+ 	const char *proc = NULL;
+ 	int wildcards;
+ 	TDSSOCKET *tds;
++	DSTR schema_name, catalog_name, table_type;
+ 
+ 	INIT_HSTMT;
+ 
++	tds_dstr_init(&schema_name);
++	tds_dstr_init(&catalog_name);
++	tds_dstr_init(&table_type);
++
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLTables(%p, %p, %d, %p, %d, %p, %d, %p, %d)\n", 
+ 			hstmt, szCatalogName, cbCatalogName, szSchemaName, cbSchemaName, szTableName, cbTableName, szTableType, cbTableType);
+ 
+ 	tds = stmt->dbc->tds_socket;
+ 
+-	/* fix for processing */
+-	if (cbCatalogName == SQL_NULL_DATA)
+-		szCatalogName = NULL;
+-	cbCatalogName = odbc_get_string_size(cbCatalogName, szCatalogName);
++	if (!odbc_dstr_copy(stmt->dbc, &catalog_name, cbCatalogName, szCatalogName _wide)
++	    || !odbc_dstr_copy(stmt->dbc, &schema_name, cbSchemaName, szSchemaName _wide)
++	    || !odbc_dstr_copy(stmt->dbc, &table_type, cbTableType, szTableType _wide)) {
++		tds_dstr_free(&schema_name);
++		tds_dstr_free(&catalog_name);
++		tds_dstr_free(&table_type);
++		odbc_errs_add(&stmt->errs, "HY001", NULL);
++		ODBC_RETURN(stmt, SQL_ERROR);
++	}
++
++	cbCatalogName = tds_dstr_len(&catalog_name);
++	cbSchemaName = tds_dstr_len(&schema_name);
++	cbTableType = tds_dstr_len(&table_type);
+ 
+ 	/* support wildcards on catalog (only odbc 3) */
+ 	wildcards = 0;
+ 	if (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3 && stmt->dbc->attr.metadata_id == SQL_FALSE &&
+-	    (memchr(szCatalogName, '%', cbCatalogName) || memchr(szCatalogName, '_', cbCatalogName)))
++	    (strchr(tds_dstr_cstr(&catalog_name), '%') || strchr(tds_dstr_cstr(&catalog_name), '_')))
+ 		wildcards = 1;
+ 
+ 	proc = "sp_tables ";
+-	if (cbCatalogName > 0 && (cbCatalogName != 1 || szCatalogName[0] != '%' || cbTableName > 0 || cbSchemaName > 0)) {
++	if (cbCatalogName > 0) {
+ 		if (wildcards) {
+ 			/* if catalog specified and wildcards use sp_tableswc under mssql2k */
+ 			if (TDS_IS_MSSQL(tds) && tds->product_version >= TDS_MS_VER(8,0,0)) {
+ 				proc = "sp_tableswc ";
+ 				if (cbSchemaName == SQL_NULL_DATA) {
+-					szSchemaName = (SQLCHAR *) "%";
++					tds_dstr_copy(&schema_name, "%");
+ 					cbSchemaName = 1;
+ 				}
+ 			}
+@@ -6611,15 +6697,14 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 	}
+ 
+ 	/* fix type if needed quoting it */
+-	if (szTableType && cbTableType != SQL_NULL_DATA) {
+-		int len = odbc_get_string_size(cbTableType, szTableType);
++	if (cbTableType > 0) {
+ 		int to_fix = 0;
+ 		int elements = 0;
+-		char *p = (char *) szTableType;
+-		char *const end = p + len;
++		const char *p = tds_dstr_cstr(&table_type);
++		const char *const end = p + tds_dstr_len(&table_type);
+ 
+ 		for (;;) {
+-			char *begin = p;
++			const char *begin = p;
+ 
+ 			p = memchr(p, ',', end - p);
+ 			if (!p)
+@@ -6632,20 +6717,20 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 			++p;
+ 		}
+ 		/* fix it */
+-		tdsdump_log(TDS_DBG_INFO1, "len %d to_fix %d elements %d\n", len, to_fix, elements);
+-		if (len && to_fix) {
+-			char *dst;
++		tdsdump_log(TDS_DBG_INFO1, "to_fix %d elements %d\n", to_fix, elements);
++		if (to_fix) {
++			char *dst, *type;
+ 
+ 			tdsdump_log(TDS_DBG_INFO1, "fixing type elements\n");
+-			type = (char *) malloc(len + elements * 2);
++			type = (char *) malloc(tds_dstr_len(&table_type) + elements * 2 + 3);
+ 			if (!type) {
+ 				odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 				ODBC_RETURN(stmt, SQL_ERROR);
+ 			}
+-			p = (char *) szTableType;
++			p = tds_dstr_cstr(&table_type);
+ 			dst = type;
+ 			for (;;) {
+-				char *begin = p;
++				const char *begin = p;
+ 
+ 				p = memchr(p, ',', end - p);
+ 				if (!p)
+@@ -6663,16 +6748,19 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 					break;
+ 				*dst++ = *p++;
+ 			}
+-			cbTableType = dst - type;
+-			szTableType = (SQLCHAR *) type;
++			*dst = 0;
++			tds_dstr_set(&table_type, type);
++			cbTableType = tds_dstr_len(&table_type);
+ 		}
+ 	}
+ 
+ 	retcode =
+-		odbc_stat_execute(stmt, proc, 4, "P@table_name", szTableName, cbTableName, "P@table_owner", szSchemaName,
+-				  cbSchemaName, "P@table_qualifier", szCatalogName, cbCatalogName, "@table_type", szTableType,
+-				  cbTableType);
+-	free(type);
++		odbc_stat_execute(stmt _wide, proc, 4, "P@table_name", szTableName, cbTableName, "!P@table_owner", tds_dstr_cstr(&schema_name),
++				  cbSchemaName, "!P@table_qualifier", tds_dstr_cstr(&catalog_name), cbCatalogName,
++				  "!@table_type", tds_dstr_cstr(&table_type), cbTableType);
++	tds_dstr_free(&schema_name);
++	tds_dstr_free(&catalog_name);
++	tds_dstr_free(&table_type);
+ 	if (SQL_SUCCEEDED(retcode) && stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) {
+ 		odbc_col_setname(stmt, 1, "TABLE_CAT");
+ 		odbc_col_setname(stmt, 2, "TABLE_SCHEM");
+@@ -6767,10 +6855,12 @@ odbc_log_unimplemented_type(const char function_name[], int fType)
+ }
+ 
+ static int
+-odbc_quote_metadata(TDS_DBC * dbc, char type, char *dest, const char *s, int len)
++odbc_quote_metadata(TDS_DBC * dbc, char type, char *dest, DSTR * dstr)
+ {
+ 	int unquote = 0;
+ 	char prev, buf[1200], *dst;
++	const char *s = tds_dstr_cstr(dstr);
++	int len = tds_dstr_len(dstr);
+ 
+ 	if (!type || (type == 'O' && dbc->attr.metadata_id == SQL_FALSE))
+ 		return tds_quote_string(dbc->tds_socket, dest, s, len);
+@@ -6858,9 +6948,8 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ {
+ 	struct param
+ 	{
++		DSTR value;
+ 		char *name;
+-		char *value;
+-		int len;
+ 		char type;
+ 	}
+ 	params[ODBC_MAX_STAT_PARAM];
+@@ -6876,10 +6965,16 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ 	va_start(marker, nparams);
+ 	len = strlen(begin) + 2;
+ 	for (i = 0; i < nparams; ++i) {
+-		int param_len;
++		int param_len, convert = 1;
++		DSTR *out;
+ 
+ 		p = va_arg(marker, char *);
+ 
++		if (*p == '!') {
++			convert = 0;
++			++p;
++		}
++
+ 		switch (*p) {
+ 		case 'V':	/* ODBC version */
+ 			len += strlen(p) + 3;
+@@ -6893,18 +6988,31 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ 		}
+ 		params[i].name = p;
+ 
+-		params[i].value = va_arg(marker, char *);
++		p = va_arg(marker, char *);
+ 		param_len = va_arg(marker, int);
+-		if (params[i].value && param_len != SQL_NULL_DATA) {
+-			params[i].len = odbc_get_string_size(param_len, (SQLCHAR *) params[i].value);
++		tds_dstr_init(&params[i].value);
++#ifdef ENABLE_ODBC_WIDE
++		if (!convert)
++			out = tds_dstr_copyn(&params[i].value, p, param_len);
++		else
++			out = odbc_dstr_copy(stmt->dbc, &params[i].value, param_len, (ODBC_CHAR *) p _wide);
++#else
++		out = odbc_dstr_copy(stmt->dbc, &params[i].value, param_len, (ODBC_CHAR *) p _wide);
++#endif
++		if (!out) {
++			while (--i >= 0)
++				tds_dstr_free(&params[i].value);
++			odbc_errs_add(&stmt->errs, "HY001", NULL);
++			ODBC_RETURN(stmt, SQL_ERROR);
++		}
++		if (!tds_dstr_isempty(&params[i].value)) {
+ 			len += strlen(params[i].name) + odbc_quote_metadata(stmt->dbc, params[i].type, NULL, 
+-									    params[i].value, params[i].len) + 3;
++									    &params[i].value) + 3;
+ 			if (begin[0] == '.' && strstr(params[i].name, "qualifier")) {
+-				len += tds_quote_id(stmt->dbc->tds_socket, NULL, params[i].value, params[i].len);
++				len += tds_quote_id(stmt->dbc->tds_socket, NULL,
++						    tds_dstr_cstr(&params[param_qualifier].value), tds_dstr_len(&params[param_qualifier].value));
+ 				param_qualifier = i;
+ 			}
+-		} else {
+-			params[i].value = NULL;
+ 		}
+ 
+ 	}
+@@ -6912,6 +7020,8 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ 
+ 	/* allocate space for string */
+ 	if (!(proc = (char *) malloc(len))) {
++		for (i = 0; i < nparams; ++i)
++			tds_dstr_free(&params[i].value);
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -6919,11 +7029,11 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ 	/* build string */
+ 	p = proc;
+ 	if (param_qualifier >= 0)
+-		p += tds_quote_id(stmt->dbc->tds_socket, p, params[param_qualifier].value, params[param_qualifier].len);
++		p += tds_quote_id(stmt->dbc->tds_socket, p, tds_dstr_cstr(&params[param_qualifier].value), tds_dstr_len(&params[param_qualifier].value));
+ 	strcpy(p, begin);
+ 	p += strlen(begin);
+ 	for (i = 0; i < nparams; ++i) {
+-		if (!params[i].value && params[i].type != 'V')
++		if (tds_dstr_isempty(&params[i].value) && params[i].type != 'V')
+ 			continue;
+ 		if (params[i].name[0]) {
+ 			strcpy(p, params[i].name);
+@@ -6931,15 +7041,17 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ 			*p++ = '=';
+ 		}
+ 		if (params[i].type != 'V')
+-			p += odbc_quote_metadata(stmt->dbc, params[i].type, p, params[i].value, params[i].len);
++			p += odbc_quote_metadata(stmt->dbc, params[i].type, p, &params[i].value);
+ 		else
+ 			*p++ = (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3) ? '3': '2';
+ 		*p++ = ',';
++		tds_dstr_free(&params[i].value);
+ 	}
+ 	*--p = '\0';
+ 	assert(p - proc + 1 <= len);
+ 
+ 	/* set it */
++	/* FIXME is neither mb or wide, is always utf encoded !!! */
+ 	retcode = odbc_set_stmt_query(stmt, (ODBC_CHAR *) proc, p - proc _wide0);
+ 	free(proc);
+ 
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 3dc1f9e..0992ed0 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -33,6 +33,7 @@
+ #include <assert.h>
+ 
+ #include "tdsodbc.h"
++#include "tdsiconv.h"
+ #include "tdsstring.h"
+ #include "tdsconvert.h"
+ 
+@@ -40,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.114 2010/07/02 13:38:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.115 2010/07/03 09:14:36 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -53,6 +54,22 @@ TDS_RCSID(var, "$Id: odbc_util.c,v 1.114 2010/07/02 13:38:24 freddy77 Exp $");
+  * @{ 
+  */
+ 
++#ifdef ENABLE_ODBC_WIDE
++static char *odbc_iso2utf(const char *s, int len);
++static char *odbc_mb2utf(TDS_DBC *dbc, const char *s, int len);
++static char *odbc_wide2utf(const SQLWCHAR *s, int len);
++#else
++static char *odbc_strndup(const char *s, int len)
++{
++	char *out = (char*) malloc(len+1);
++	if (!out)
++		return NULL;
++	memcpy(out, s, len);
++	out[len] = 0;
++	return out;
++}
++#endif
++
+ static int
+ odbc_set_stmt(TDS_STMT * stmt, char **dest, const ODBC_CHAR *sql, int sql_len _WIDE)
+ {
+@@ -61,7 +78,11 @@ odbc_set_stmt(TDS_STMT * stmt, char **dest, const ODBC_CHAR *sql, int sql_len _W
+ 	assert(dest == &stmt->prepared_query || dest == &stmt->query);
+ 
+ 	if (sql_len == SQL_NTS)
++#ifdef ENABLE_ODBC_WIDE
++		sql_len = wide ? sqlwcslen(sql->wide) : strlen(sql->mb);
++#else
+ 		sql_len = strlen((const char*) sql);
++#endif
+ 	else if (sql_len <= 0)
+ 		return SQL_ERROR;
+ 
+@@ -83,17 +104,14 @@ odbc_set_stmt(TDS_STMT * stmt, char **dest, const ODBC_CHAR *sql, int sql_len _W
+ 	if (stmt->query)
+ 		TDS_ZERO_FREE(stmt->query);
+ 
+-	*dest = p = (char *) malloc(sql_len + 1);
++#ifdef ENABLE_ODBC_WIDE
++	*dest = p = wide ? odbc_wide2utf(sql->wide, sql_len) : odbc_mb2utf(stmt->dbc, sql->mb, sql_len);
++#else
++	*dest = p = odbc_strndup((const char*) sql, sql_len);
++#endif
+ 	if (!p)
+ 		return SQL_ERROR;
+ 
+-	if (sql) {
+-		memcpy(p, sql, sql_len);
+-		p[sql_len] = 0;
+-	} else {
+-		p[0] = 0;
+-	}
+-
+ 	return SQL_SUCCESS;
+ }
+ 
+@@ -110,6 +128,319 @@ odbc_set_stmt_prepared_query(TDS_STMT * stmt, const ODBC_CHAR *sql, int sql_len
+ 	return odbc_set_stmt(stmt, &stmt->prepared_query, sql, sql_len _wide);
+ }
+ 
++int
++odbc_get_string_size(int size, ODBC_CHAR * str _WIDE)
++{
++	if (str) {
++		if (size == SQL_NTS)
++#ifdef ENABLE_ODBC_WIDE
++			return wide ? sqlwcslen(str->wide) : strlen(str->mb);
++#else
++			return strlen((const char*) str);
++#endif
++		if (size >= 0)
++			return size;
++	}
++	/* SQL_NULL_DATA or any other strange value */
++	return 0;
++}
++
++#ifdef ENABLE_ODBC_WIDE
++static char *
++odbc_iso2utf(const char *s, int len)
++{
++	int i, o_len = len + 1;
++	char *out, *p;
++
++	for (i = 0; i < len; ++i)
++		if ((s[i] & 0x80) != 0)
++			++o_len;
++
++	out = (char *) malloc(o_len);
++	if (!out) return NULL;
++
++	for (p = out; len > 0; --len) {
++		unsigned char u = (unsigned char) *s++;
++		if ((u & 0x80) != 0) {
++			*p++ = 0xc0 | (0x1f & (u >> 6));
++			*p++ = 0x80 | (0x3f & u);
++		} else {
++			*p++ = u;
++		}
++	}
++	*p = 0;
++	return out;
++}
++
++static char *
++odbc_wide2utf(const SQLWCHAR *s, int len)
++{
++	int i, o_len = len + 1;
++	char *out, *p;
++#if SIZEOF_SQLWCHAR > 2
++# define MASK(n) ((0xffffffffu << (n)) & 0xffffffffu)
++#else
++# define MASK(n) ((0xffffu << (n)) & 0xffffu)
++#endif
++
++	for (i = 0; i < len; ++i) {
++		if ((s[i] & MASK(7)) == 0)
++			continue;
++		++o_len;
++		if ((s[i] & MASK(11)) == 0)
++			continue;
++		++o_len;
++#if SIZEOF_SQLWCHAR > 2
++		if ((s[i] & MASK(16)) == 0)
++			continue;
++		++o_len;
++		if ((s[i] & MASK(21)) == 0)
++			continue;
++		++o_len;
++		if ((s[i] & MASK(26)) == 0)
++			continue;
++		++o_len;
++#endif
++	}
++
++	out = (char *) malloc(o_len);
++	if (!out) return NULL;
++
++	for (p = out; len > 0; --len) {
++		SQLWCHAR u = *s++;
++		if ((u & MASK(7)) == 0) {
++			*p++ = u;
++			continue;
++		}
++		if ((u & MASK(11)) == 0) {
++			*p++ = 0xc0 | (0x1f & (u >> 6));
++		} else {
++#if SIZEOF_SQLWCHAR > 2
++			if ((u & MASK(16)) == 0) {
++				*p++ = 0xe0 | (0x0f & (u >> 12));
++			} else {
++				if ((u & MASK(21)) == 0) {
++					if ((u & MASK(26)) == 0) {
++						*p++ = 0xfc | (0x01 & (u >> 30));
++						*p++ = 0x80 | (0x3f & (u >> 24));
++					} else {
++						*p++ = 0xf8 | (0x03 & (u >> 24));
++					}
++					*p++ = 0x80 | (0x3f & (u >> 18));
++				} else {
++					*p++ = 0xf0 | (0x07 & (u >> 18));
++				}
++				*p++ = 0x80 | (0x3f & (u >> 12));
++			}
++			*p++ = 0x80 | (0x3f & (u >> 6));
++#else
++			*p++ = 0xe0 | (0x0f & (u >> 12));
++			*p++ = 0x80 | (0x3f & (u >> 6));
++#endif
++		}
++		*p++ = 0x80 | (0x3f & u);
++	}
++	*p = 0;
++	return out;
++}
++
++static char *
++odbc_mb2utf(TDS_DBC *dbc, const char *s, int len)
++{
++	char *buf;
++
++	const char *ib;
++	char *ob;
++	size_t il, ol;
++	TDSICONV *char_conv = dbc->mb_conv;
++
++	if (!char_conv)
++		return odbc_iso2utf(s, len);
++
++	il = len;
++
++	/* allocate needed buffer (+1 is to exclude 0 case) */
++	ol = il * char_conv->server_charset.max_bytes_per_char / char_conv->client_charset.min_bytes_per_char + 1;
++	buf = (char *) malloc(ol);
++	if (!buf)
++		return NULL;
++
++	ib = s;
++	ob = buf;
++	--ol; /* leave space for terminator */
++
++	/* char_conv is only mostly const */
++	memset((TDS_ERRNO_MESSAGE_FLAGS*) &char_conv->suppress, 0, sizeof(char_conv->suppress));
++	if (tds_iconv(dbc->tds_socket, char_conv, to_server, &ib, &il, &ob, &ol) == (size_t)-1) {
++		free(buf);
++		return NULL;
++	}
++	*ob = 0;
++	return buf;
++}
++#endif
++
++DSTR*
++odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE)
++{
++#ifdef ENABLE_ODBC_WIDE
++	int len = odbc_get_string_size(size, str _wide);
++	char *buf;
++
++	if (wide)
++		buf = odbc_wide2utf(str->wide, len);
++	else
++		buf = odbc_mb2utf(dbc, str->mb, len);
++	if (!buf)
++		return NULL;
++
++	return tds_dstr_set(s, buf);
++#else
++	return tds_dstr_copyn(s, (const char *) str, odbc_get_string_size(size, str));
++#endif
++}
++
++/**
++ * Copy a string to client setting size according to ODBC convenction
++ * @param dbc       database connection. Can be NULL
++ * @param buffer    client buffer
++ * @param cbBuffer  client buffer size (in bytes)
++ * @param pcbBuffer pointer to SQLSMALLINT to hold string size
++ * @param s         string to copy
++ * @param len       len of string to copy. <0 null terminated
++ * @param flag      set of flag 0x10 SQLINTEGER
++ */
++SQLRETURN
++odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag)
++{
++	SQLRETURN result = SQL_SUCCESS;
++	int out_len = 0;
++
++	if (len < 0)
++		len = strlen(s);
++
++#ifdef ENABLE_ODBC_WIDE
++	if ((flag & 1) != 0) {
++		/* wide characters */
++		const unsigned char *p = (const unsigned char*) s;
++		SQLWCHAR *dest = (SQLWCHAR*) buffer;
++
++		cbBuffer = cbBuffer >= 0 ? cbBuffer / SIZEOF_SQLWCHAR : 0;
++		while (len) {
++			unsigned char mask;
++			unsigned u;
++			int l;
++
++			if (!(p[0] & 0x80)) {
++				mask = 0x7f; l = 1;
++			} else if ((p[0] & 0xe0) == 0xc0) {
++				mask = 0x1f; l = 2;
++			} else if ((p[0] & 0xf0) == 0xe0) {
++				mask = 0x0f; l = 3;
++			} else if ((p[0] & 0xf8) == 0xf0) {
++				mask = 0x07; l = 4;
++			} else if ((p[0] & 0xfc) == 0xf8) {
++				mask = 0x03; l = 5;
++			} else {
++				mask = 0x7f; l = 1;
++			}
++			if (len < l)
++				break;
++			len -= l;
++			u = *p++ & mask;
++			while(--l)
++				u = (u << 6) | (*p++ & 0x3f);
++			++out_len;
++			if (!dest)
++				continue;
++			if (cbBuffer > 1) {
++				*dest++ = (SQLWCHAR) u;
++				--cbBuffer;
++				continue;
++			}
++			result = SQL_SUCCESS_WITH_INFO;
++		}
++		/* terminate buffer */
++		if (dest && cbBuffer)
++			*dest = 0;
++		out_len *= SIZEOF_SQLWCHAR;
++	} else if (1 || !dbc || !dbc->mb_conv) {
++		/* to ISO-8859-1 */
++		const unsigned char *p = (const unsigned char*) s;
++		unsigned char *dest = (unsigned char*) buffer;
++
++		while (len) {
++			unsigned char mask;
++			unsigned u;
++			int l;
++
++			if (!(p[0] & 0x80)) {
++				mask = 0x7f; l = 1;
++			} else if ((p[0] & 0xe0) == 0xc0) {
++				mask = 0x1f; l = 2;
++			} else if ((p[0] & 0xf0) == 0xe0) {
++				mask = 0x0f; l = 3;
++			} else if ((p[0] & 0xf8) == 0xf0) {
++				mask = 0x07; l = 4;
++			} else if ((p[0] & 0xfc) == 0xf8) {
++				mask = 0x03; l = 5;
++			} else {
++				mask = 0x7f; l = 1;
++			}
++			if (len < l)
++				break;
++			len -= l;
++			u = *p++ & mask;
++			while(--l)
++				u = (u << 6) | (*p++ & 0x3f);
++			++out_len;
++			if (!dest)
++				continue;
++			if (cbBuffer > 1) {
++				*dest++ = u > 0x100 ? '?' : u;
++				--cbBuffer;
++				continue;
++			}
++			result = SQL_SUCCESS_WITH_INFO;
++		}
++		/* terminate buffer */
++		if (dest && cbBuffer)
++			*dest = 0;
++	} else {
++		/* TODO convert and set correctly length !!! */
++		if (len >= cbBuffer) {
++			len = cbBuffer - 1;
++			result = SQL_SUCCESS_WITH_INFO;
++		}
++		if (buffer && len >= 0) {
++			/* buffer can overlap, use memmove, thanks to Valgrind */
++			memmove((char *) buffer, s, len);
++			((char *) buffer)[len] = 0;
++		}
++	}
++#else
++	out_len = len;
++	if (len >= cbBuffer) {
++		len = cbBuffer - 1;
++		result = SQL_SUCCESS_WITH_INFO;
++	}
++	if (buffer && len >= 0) {
++		/* buffer can overlap, use memmove, thanks to Valgrind */
++		memmove((char *) buffer, s, len);
++		((char *) buffer)[len] = 0;
++	}
++#endif
++
++	/* set output length */
++	if (pcbBuffer) {
++		if (flag & 0x10)
++			*((SQLINTEGER *) pcbBuffer) = out_len;
++		else
++			*((SQLSMALLINT *) pcbBuffer) = out_len;
++	}
++	return result;
++}
++
+ 
+ void
+ odbc_set_return_status(struct _hstmt *stmt, unsigned int n_row)
+@@ -232,25 +563,6 @@ odbc_set_return_params(struct _hstmt *stmt, unsigned int n_row)
+ 	}
+ }
+ 
+-int
+-odbc_get_string_size(int size, ODBC_CHAR * str _WIDE)
+-{
+-	if (str) {
+-		if (size == SQL_NTS)
+-			return strlen((const char *) str);
+-		if (size >= 0)
+-			return size;
+-	}
+-	/* SQL_NULL_DATA or any other strange value */
+-	return 0;
+-}
+-
+-DSTR*
+-odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE)
+-{
+-	return tds_dstr_copyn(s, (const char *) str, odbc_get_string_size(size, str));
+-}
+-
+ /**
+  * Convert type from database to ODBC
+  */
+@@ -754,42 +1066,6 @@ odbc_sql_to_server_type(TDSSOCKET * tds, int sql_type)
+ 	}
+ }
+ 
+-/**
+- * Copy a string to client setting size according to ODBC convenction
+- * @param dbc       database connection. Can be NULL
+- * @param buffer    client buffer
+- * @param cbBuffer  client buffer size (in bytes)
+- * @param pcbBuffer pointer to SQLSMALLINT to hold string size
+- * @param s         string to copy
+- * @param len       len of string to copy. <0 null terminated
+- * @param flag      set of flag 0x10 SQLINTEGER
+- */
+-SQLRETURN
+-odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag)
+-{
+-	SQLRETURN result = SQL_SUCCESS;
+-
+-	if (len < 0)
+-		len = strlen(s);
+-
+-	if (pcbBuffer) {
+-		if (flag & 0x10)
+-			*((SQLINTEGER *) pcbBuffer) = len;
+-		else
+-			*((SQLSMALLINT *) pcbBuffer) = len;
+-	}
+-	if (len >= cbBuffer) {
+-		len = cbBuffer - 1;
+-		result = SQL_SUCCESS_WITH_INFO;
+-	}
+-	if (buffer && len >= 0) {
+-		/* buffer can overlap, use memmove, thanks to Valgrind */
+-		memmove((char *) buffer, s, len);
+-		((char *) buffer)[len] = 0;
+-	}
+-	return result;
+-}
+-
+ /** Returns the version of the RDBMS in the ODBC format */
+ void
+ odbc_rdbms_version(TDSSOCKET * tds, char *pversion_string)
+diff --git a/src/odbc/sql2tds.c b/src/odbc/sql2tds.c
+index d5493e5..d06c308 100644
+--- a/src/odbc/sql2tds.c
++++ b/src/odbc/sql2tds.c
+@@ -48,12 +48,13 @@
+ #include "tdsodbc.h"
+ #include "tdsconvert.h"
+ #include "tdsiconv.h"
++#include "tdsstring.h"
+ 
+ #ifdef DMALLOC
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: sql2tds.c,v 1.84 2009/08/26 12:32:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: sql2tds.c,v 1.85 2010/07/03 09:14:36 freddy77 Exp $");
+ 
+ static TDS_INT
+ convert_datetime2server(int bindtype, const void *src, TDS_DATETIME * dt)
+@@ -211,10 +212,20 @@ odbc_sql2tds(TDS_STMT * stmt, const struct _drecord *drec_ipd, const struct _dre
+                 curcol->char_conv = tds_iconv_get(tds, ODBC_WIDE_NAME, conv->server_charset.name);
+ 		memcpy(curcol->column_collation, tds->collation, sizeof(tds->collation));
+ 	} else {
++#ifdef ENABLE_ODBC_WIDE
++		TDSSOCKET *tds = dbc->tds_socket;
++		TDSICONV *conv = tds->char_convs[is_unicode_type(dest_type) ? client2ucs2 : client2server_chardata];
++
++		tds_set_param_type(tds, curcol, dest_type);
++		/* use binary format for binary to char */
++		if (is_char_type(dest_type))
++			curcol->char_conv = sql_src_type == SQL_C_BINARY ? NULL : tds_iconv_get(tds, tds_dstr_cstr(&dbc->original_charset), conv->server_charset.name);
++#else
+ 		tds_set_param_type(dbc->tds_socket, curcol, dest_type);
+ 		/* use binary format for binary to char */
+ 		if (sql_src_type == SQL_C_BINARY && is_char_type(dest_type))
+ 			curcol->char_conv = NULL;
++#endif
+ 	}
+ 	if (is_numeric_type(curcol->column_type)) {
+ 		curcol->column_prec = drec_ipd->sql_desc_precision;
+diff --git a/src/odbc/sqlwparams.h b/src/odbc/sqlwparams.h
+index ad0fd36..8a83f67 100644
+--- a/src/odbc/sqlwparams.h
++++ b/src/odbc/sqlwparams.h
+@@ -1,5 +1,76 @@
+ //#define FUNC NAME(SQLTest) (P(SQLSMALLINT, x), PCHAR(y) WIDE)
+ 
++#ifdef ENABLE_ODBC_WIDE
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) _ ## a
++#define WIDE , int wide
++#define P(a,b) a b
++#define PCHAR(a) ODBC_CHAR* a
++static SQLRETURN FUNC;
++
++
++
++#undef NAME
++#undef WIDE
++#undef PCHAR
++#define NAME(a) a
++#define WIDE
++#define PCHAR(a) SQLCHAR* a
++SQLRETURN ODBC_API FUNC {
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) _ ## a
++#define WIDE ,0
++#define P(a,b) b
++#define PCHAR(a) (ODBC_CHAR*) a
++	return FUNC;
++}
++
++
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) a ## W
++#define WIDE
++#define P(a,b) a b
++#define PCHAR(a) SQLWCHAR * a
++SQLRETURN ODBC_API FUNC {
++
++#undef NAME
++#undef WIDE
++#undef P
++#undef PCHAR
++#define NAME(a) _ ## a
++#define WIDE ,1
++#define P(a,b) b
++#define PCHAR(a) (ODBC_CHAR*) a
++	return FUNC;
++}
++
++
++
++#undef WIDE
++#undef P
++#undef PCHAR
++#define WIDE , int wide
++#define P(a,b) a b
++#define PCHAR(a) ODBC_CHAR* a
++static SQLRETURN FUNC
++
++
++
++#else
++
++
+ 
+ #undef NAME
+ #undef WIDE
+@@ -45,6 +116,8 @@ SQLRETURN ODBC_API FUNC {
+ #define PCHAR(a) SQLCHAR* a
+ static SQLRETURN FUNC
+ 
++#endif
+ 
+ 
+ #undef FUNC
++
+
+commit 4180d772d749af76a265b51b6bc61d9ccfdf9f35
+Author: freddy77 <freddy77>
+Date:   Sat Jul 3 09:49:11 2010 +0000
+
+    minor issues
+
+diff --git a/ChangeLog b/ChangeLog
+index 58ea7f1..d14cd87 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul  3 11:49:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/odbc.c: minor issues
++
+ Sat Jul  3 11:14:29 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac include/tdsodbc.h src/odbc/convert_tds2sql.c:
+ 	* src/odbc/odbc.c src/odbc/odbc_util.c src/odbc/sql2tds.c:
+@@ -2584,4 +2587,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3056 2010/07/03 09:14:36 freddy77 Exp $
++$Id: ChangeLog,v 1.3057 2010/07/03 09:49:11 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 245e377..6c797be 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.51 2010/07/03 09:14:36 freddy77 Exp $
++dnl $Id: configure.ac,v 1.52 2010/07/03 09:49:12 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.51 $)
++AC_REVISION($Revision: 1.52 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -772,10 +772,7 @@ fi
+ AC_ARG_ENABLE(odbc-wide,
+   AS_HELP_STRING([--enable-odbc-wide], [enable wide string support in odbc [experimental]]))
+ if test "$enable_odbc_wide" = "yes" ; then
+-	if test "$use_libiconv" != "yes" ; then
+-		AC_MSG_ERROR([iconv required for ODBC wide support.])
+-	fi
+-	AC_DEFINE_UNQUOTED(ENABLE_ODBC_WIDE, 1, [Define to enable ODBC wide string support. Require libiconv!])
++	AC_DEFINE_UNQUOTED(ENABLE_ODBC_WIDE, 1, [Define to enable ODBC wide string support])
+ fi
+ 
+ AC_ARG_ENABLE(distcheck_build,
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a190a76..a030452 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.540 2010/07/03 09:14:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.541 2010/07/03 09:49:12 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -6084,7 +6084,7 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ }
+ 
+ 
+-#define FUNC NAME(SQLSetConnectAttr) (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOINTER,ValuePtr), P(SQLINTEGER,StringLength) _WIDE)
++#define FUNC NAME(SQLSetConnectAttr) (P(SQLHDBC,hdbc), P(SQLINTEGER,Attribute), P(SQLPOINTER,ValuePtr), P(SQLINTEGER,StringLength) WIDE)
+ #include "sqlwparams.h"
+ {
+ 	SQLULEN u_value = (SQLULEN) (TDS_INTPTR) ValuePtr;
+
+commit ac0e3d61eb6822054a142306370d75de65c5a2f3
+Author: freddy77 <freddy77>
+Date:   Mon Jul 5 06:59:35 2010 +0000
+
+    fix possible problem using utf8 on Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index d14cd87..4929407 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul  5 08:58:59 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix possible problem using utf8 on Sybase
++
+ Sat Jul  3 11:49:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/odbc/odbc.c: minor issues
+ 
+@@ -2587,4 +2590,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3057 2010/07/03 09:49:11 freddy77 Exp $
++$Id: ChangeLog,v 1.3058 2010/07/05 06:59:35 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a030452..6a4fa48 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.541 2010/07/03 09:49:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.542 2010/07/05 06:59:36 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -5997,6 +5997,8 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 		resinfo = tds->current_results;
+ 		colinfo = resinfo->columns[0];
+ 		name = (char *) colinfo->column_data;
++		if (is_blob_col(colinfo))
++			name = (char*) ((TDSBLOB *) name)->textvalue;
+ 		/* skip nvarchar and sysname */
+ 		if (colinfo->column_cur_size == 7 && memcmp("varchar", name, 7) == 0) {
+ 			varchar_pos = n;
+
+commit 2b39278ad43df263482e2837061ac040e00c9604
+Author: freddy77 <freddy77>
+Date:   Mon Jul 5 07:20:47 2010 +0000
+
+    move to/from sqlwchar to common code
+
+diff --git a/ChangeLog b/ChangeLog
+index 4929407..d1cfad5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Mon Jul  5 09:20:20 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c src/odbc/unittests/common.c:
++	* src/odbc/unittests/common.h:
++	- move to/from sqlwchar to common code
++
+ Mon Jul  5 08:58:59 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix possible problem using utf8 on Sybase
+ 
+@@ -2590,4 +2595,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3058 2010/07/05 06:59:35 freddy77 Exp $
++$Id: ChangeLog,v 1.3059 2010/07/05 07:20:47 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 2339bea..549943a 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.20 2009/05/21 21:58:43 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.21 2010/07/05 07:20:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -119,26 +119,6 @@ readBlob(test_info *t)
+ 		failed = 1;
+ }
+ 
+-static int
+-to_sqlwchar(SQLWCHAR *dst, const char *src, int n)
+-{
+-	int i = n;
+-	while (--i >= 0)
+-		dst[i] = (unsigned char) src[i];
+-	return n * sizeof(SQLWCHAR);
+-}
+-
+-static int
+-from_sqlwchar(char *dst, const SQLWCHAR *src, int n)
+-{
+-	int i;
+-	for (i = 0; i < n; ++i) {
+-		assert(src[i] < 256);
+-		dst[i] = src[i];
+-	}
+-	return n;
+-}
+-
+ static void
+ readBlobAsChar(test_info *t, int step, int wide)
+ {
+@@ -178,7 +158,7 @@ readBlobAsChar(test_info *t, int step, int wide)
+ 
+ 		if (wide) {
+ 			len /= sizeof(SQLWCHAR);
+-			from_sqlwchar((char *) buf, (SQLWCHAR *) buf, len + 1);
++			odbc_from_sqlwchar((char *) buf, (SQLWCHAR *) buf, len + 1);
+ 		}
+ 
+ 		check =	check_hex(buf, len, 2*t->gen1 + total, t->gen2);
+@@ -324,7 +304,7 @@ main(int argc, char **argv)
+ 					fill_hex(p, NBYTES, t->gen1, t->gen2);
+ 					if (t->c_type == SQL_C_WCHAR) {
+ 						char_len = sizeof(SQLWCHAR);
+-						to_sqlwchar((SQLWCHAR*) p, p, NBYTES * 2);
++						odbc_to_sqlwchar((SQLWCHAR*) p, p, NBYTES * 2);
+ 					}
+ 
+ 					CHKPutData(p, (NBYTES - (i&1)) * char_len, "S");
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index a2f7f70..433205c 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -4,6 +4,7 @@
+ #include <unistd.h>
+ #endif /* HAVE_UNISTD_H */
+ 
++#include <assert.h>
+ #include <ctype.h>
+ 
+ #ifndef _WIN32
+@@ -12,7 +13,7 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.57 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.58 2010/07/05 07:20:47 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ HENV Environment;
+@@ -453,3 +454,23 @@ ReadError(void)
+ 	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+ }
+ 
++int
++odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, int n)
++{
++	int i = n;
++	while (--i >= 0)
++		dst[i] = (unsigned char) src[i];
++	return n * sizeof(SQLWCHAR);
++}
++
++int
++odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, int n)
++{
++	int i;
++	for (i = 0; i < n; ++i) {
++		assert(src[i] < 256);
++		dst[i] = src[i];
++	}
++	return n;
++}
++
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 4b246f2..7de56da 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.32 2010/03/02 15:41:37 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.33 2010/07/05 07:20:47 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -171,3 +171,7 @@ void odbc_setenv(const char *name, const char *value, int overwrite);
+ 
+ #define setenv odbc_setenv
+ #endif
++
++int odbc_to_sqlwchar(SQLWCHAR *dst, const char *src, int n);
++int odbc_from_sqlwchar(char *dst, const SQLWCHAR *src, int n);
++
+
+commit 055ce1c0a7f06c01a346222b5fdfafab06def8c0
+Author: freddy77 <freddy77>
+Date:   Mon Jul 5 09:20:32 2010 +0000
+
+    normalize unittest function names
+
+diff --git a/ChangeLog b/ChangeLog
+index d1cfad5..0139514 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,44 @@
++Mon Jul  5 11:19:56 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
++	* src/odbc/unittests/attributes.c src/odbc/unittests/base.c:
++	* src/odbc/unittests/binary_test.c src/odbc/unittests/blob1.c:
++	* src/odbc/unittests/cancel.c src/odbc/unittests/common.c:
++	* src/odbc/unittests/common.h src/odbc/unittests/compute.c:
++	* src/odbc/unittests/connect.c src/odbc/unittests/connect2.c:
++	* src/odbc/unittests/const_params.c:
++	* src/odbc/unittests/convert_error.c src/odbc/unittests/copydesc.c:
++	* src/odbc/unittests/cursor1.c src/odbc/unittests/cursor2.c:
++	* src/odbc/unittests/cursor3.c src/odbc/unittests/cursor4.c:
++	* src/odbc/unittests/cursor5.c src/odbc/unittests/cursor6.c:
++	* src/odbc/unittests/cursor7.c src/odbc/unittests/data.c:
++	* src/odbc/unittests/date.c src/odbc/unittests/descrec.c:
++	* src/odbc/unittests/describecol.c src/odbc/unittests/earlybind.c:
++	* src/odbc/unittests/error.c src/odbc/unittests/freeclose.c:
++	* src/odbc/unittests/funccall.c src/odbc/unittests/genparams.c:
++	* src/odbc/unittests/getdata.c src/odbc/unittests/hidden.c:
++	* src/odbc/unittests/insert_speed.c:
++	* src/odbc/unittests/lang_error.c:
++	* src/odbc/unittests/moreandcount.c src/odbc/unittests/norowset.c:
++	* src/odbc/unittests/paramcore.c src/odbc/unittests/params.c:
++	* src/odbc/unittests/prepare_results.c:
++	* src/odbc/unittests/prepclose.c src/odbc/unittests/preperror.c:
++	* src/odbc/unittests/print.c src/odbc/unittests/putdata.c:
++	* src/odbc/unittests/raiserror.c src/odbc/unittests/rebindpar.c:
++	* src/odbc/unittests/rownumber.c src/odbc/unittests/rowset.c:
++	* src/odbc/unittests/rpc.c src/odbc/unittests/scroll.c:
++	* src/odbc/unittests/stats.c src/odbc/unittests/t0001.c:
++	* src/odbc/unittests/t0002.c src/odbc/unittests/t0003.c:
++	* src/odbc/unittests/t0004.c src/odbc/unittests/tables.c:
++	* src/odbc/unittests/test64.c src/odbc/unittests/testodbc.c:
++	* src/odbc/unittests/timeout.c src/odbc/unittests/timeout2.c:
++	* src/odbc/unittests/timeout3.c src/odbc/unittests/timeout4.c:
++	* src/odbc/unittests/transaction.c:
++	* src/odbc/unittests/transaction2.c src/odbc/unittests/type.c:
++	* src/odbc/unittests/typeinfo.c src/odbc/unittests/utf8.c:
++	* src/odbc/unittests/utf8_2.c src/odbc/unittests/warning.c:
++	* src/odbc/unittests/wchar.c:
++	- normalize unittest function names
++
+ Mon Jul  5 09:20:20 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c src/odbc/unittests/common.c:
+ 	* src/odbc/unittests/common.h:
+@@ -2595,4 +2636,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3059 2010/07/05 07:20:47 freddy77 Exp $
++$Id: ChangeLog,v 1.3060 2010/07/05 09:20:32 freddy77 Exp $
+diff --git a/src/odbc/unittests/array.c b/src/odbc/unittests/array.c
+index 9b0fd8d..fdb559c 100644
+--- a/src/odbc/unittests/array.c
++++ b/src/odbc/unittests/array.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array.c,v 1.15 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: array.c,v 1.16 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -37,18 +37,18 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ 	char status[20];
+ 	int failure = 0;
+ 
+-	assert(Statement != SQL_NULL_HSTMT);
+-	ResetStatement();
++	assert(odbc_stmt != SQL_NULL_HSTMT);
++	odbc_reset_statement();
+ 
+-	CommandWithResult(Statement, "drop table #tmp1");
+-	Command("create table #tmp1 (id tinyint, value char(20))");
++	odbc_command_with_result(odbc_stmt, "drop table #tmp1");
++	odbc_command("create table #tmp1 (id tinyint, value char(20))");
+ 
+-	SQLSetStmtAttr(Statement, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
+-	SQLSetStmtAttr(Statement, SQL_ATTR_PARAMSET_SIZE, (void *) ARRAY_SIZE, 0);
+-	SQLSetStmtAttr(Statement, SQL_ATTR_PARAM_STATUS_PTR, statuses, 0);
+-	SQLSetStmtAttr(Statement, SQL_ATTR_PARAMS_PROCESSED_PTR, &processed, 0);
+-	SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens);
+-	SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, DESC_LEN - 1, 0, descs, DESC_LEN, desc_lens);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAM_BIND_TYPE, SQL_PARAM_BIND_BY_COLUMN, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAMSET_SIZE, (void *) ARRAY_SIZE, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAM_STATUS_PTR, statuses, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_PARAMS_PROCESSED_PTR, &processed, 0);
++	SQLBindParameter(odbc_stmt, 1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens);
++	SQLBindParameter(odbc_stmt, 2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, DESC_LEN - 1, 0, descs, DESC_LEN, desc_lens);
+ 
+ 	processed = ARRAY_SIZE + 1;
+ 	for (i = 0; i < ARRAY_SIZE; i++) {
+@@ -60,10 +60,10 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ 	}
+ 
+ 	if (!prepare) {
+-		ret = SQLExecDirect(Statement, (SQLCHAR *) test_query, SQL_NTS);
++		ret = SQLExecDirect(odbc_stmt, (SQLCHAR *) test_query, SQL_NTS);
+ 	} else {
+-		SQLPrepare(Statement, (SQLCHAR *) test_query, SQL_NTS);
+-		ret = SQLExecute(Statement);
++		SQLPrepare(odbc_stmt, (SQLCHAR *) test_query, SQL_NTS);
++		ret = SQLExecute(odbc_stmt);
+ 	}
+ 	if (ret != expected) {
+ 		char buf[256];
+@@ -73,7 +73,7 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ 	}
+ 
+ 	for (i = 0; i < ARRAY_SIZE; i++)
+-		SQLMoreResults(Statement);
++		SQLMoreResults(odbc_stmt);
+ 
+ 	if (processed > ARRAY_SIZE) {
+ 		char buf[256];
+@@ -112,7 +112,7 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ 		failure = 1;
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	free(ids);
+ 	free(descs);
+@@ -120,7 +120,7 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ 	free(desc_lens);
+ 	free(statuses);
+ 	if (failure) {
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ }
+@@ -128,24 +128,24 @@ query_test(int prepare, SQLRETURN expected, const char *expected_status)
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 		test_query = "INSERT INTO #tmp1 (id, value) VALUES (?, ?)";
+ 		query_test(0, SQL_ERROR, "VV!!!!!!!!");
+ 		/* FIXME test why is different and what should be correct result */
+-		query_test(1, driver_is_freetds() ? SQL_ERROR : SQL_SUCCESS_WITH_INFO, "VV!!!!!!!!");
++		query_test(1, odbc_driver_is_freetds() ? SQL_ERROR : SQL_SUCCESS_WITH_INFO, "VV!!!!!!!!");
+ 
+ 		test_query = "INSERT INTO #tmp1 (id) VALUES (?) UPDATE #tmp1 SET value = ?";
+ 		query_test(0, SQL_SUCCESS_WITH_INFO, "VVVV!V!V!V");
+ 		/* FIXME test why is different and what should be correct result */
+-		query_test(1, driver_is_freetds() ? SQL_ERROR : SQL_SUCCESS_WITH_INFO, "VV!!!!!!!!");
++		query_test(1, odbc_driver_is_freetds() ? SQL_ERROR : SQL_SUCCESS_WITH_INFO, "VV!!!!!!!!");
+ 
+ 		/* with result, see how SQLMoreResult work */
+ 		test_query = "INSERT INTO #tmp1 (id) VALUES (?) SELECT * FROM #tmp1 UPDATE #tmp1 SET value = ?";
+ 		/* IMHO our driver is better here -- freddy77 */
+-		query_test(0, SQL_SUCCESS, driver_is_freetds() ? "VVVVV!V!V!" : "VVVVVV!VVV");
++		query_test(0, SQL_SUCCESS, odbc_driver_is_freetds() ? "VVVVV!V!V!" : "VVVVVV!VVV");
+ #ifdef ENABLE_DEVELOPING
+ 		query_test(1, SQL_SUCCESS, "VVVVVVVVVV");
+ #endif
+@@ -157,7 +157,7 @@ main(int argc, char *argv[])
+ 
+ 	/* TODO record binding, array fetch, sqlputdata */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Success!.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/array_out.c b/src/odbc/unittests/array_out.c
+index 3c802b9..4b8dc1b 100644
+--- a/src/odbc/unittests/array_out.c
++++ b/src/odbc/unittests/array_out.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test using array binding */
+ 
+-static char software_version[] = "$Id: array_out.c,v 1.15 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: array_out.c,v 1.16 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char *test_query = NULL;
+@@ -32,13 +32,13 @@ query_test(const char* expected, const char *expected_status)
+ 	Record *rec = NULL;
+ 	char status[20];
+ 
+-	assert(Statement != SQL_NULL_HSTMT);
+-	ResetStatement();
++	assert(odbc_stmt != SQL_NULL_HSTMT);
++	odbc_reset_statement();
+ 
+-	SQLSetStmtAttr(Statement, SQL_ATTR_ROW_STATUS_PTR, statuses, 0);
+-	SQLSetStmtAttr(Statement, SQL_ATTR_ROW_ARRAY_SIZE, (void *) ARRAY_SIZE, 0);
+-	SQLSetStmtAttr(Statement, SQL_ATTR_ROWS_FETCHED_PTR, &processed, 0);
+-	SQLSetStmtAttr(Statement, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_STATUS_PTR, statuses, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_ARRAY_SIZE, (void *) ARRAY_SIZE, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROWS_FETCHED_PTR, &processed, 0);
++	SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_BIND_TYPE, SQL_BIND_BY_COLUMN, 0);
+ 
+ 	if (!record_bind) {
+ 		ids = (SQLUINTEGER *) malloc(sizeof(SQLUINTEGER) * ARRAY_SIZE);
+@@ -48,7 +48,7 @@ query_test(const char* expected, const char *expected_status)
+ 		assert(descs && ids && desc_lens && id_lens);
+ 	} else {
+ 		rec_size = sizeof(Record) + ((sizeof(SQLCHAR) * desc_len + sizeof(SQLINTEGER) - 1) & ~(sizeof(SQLINTEGER) - 1));
+-		SQLSetStmtAttr(Statement, SQL_ATTR_ROW_BIND_TYPE, int2ptr(rec_size), 0);
++		SQLSetStmtAttr(odbc_stmt, SQL_ATTR_ROW_BIND_TYPE, int2ptr(rec_size), 0);
+ 		rec = (Record *) malloc(rec_size * ARRAY_SIZE);
+ 		ids = &rec->id;
+ 		id_lens = &rec->id_len;
+@@ -70,8 +70,8 @@ query_test(const char* expected, const char *expected_status)
+ 		DESC_LENS(i) = -i;
+ 	}
+ 
+-	SQLBindCol(Statement, 1, SQL_C_ULONG, &IDS(0), 0, &ID_LENS(0));
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, DESCS(0), desc_len, &DESC_LENS(0));
++	SQLBindCol(odbc_stmt, 1, SQL_C_ULONG, &IDS(0), 0, &ID_LENS(0));
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, DESCS(0), desc_len, &DESC_LENS(0));
+ 
+ 	CHKExecDirect((SQLCHAR *) test_query, SQL_NTS, "S");
+ 
+@@ -132,18 +132,18 @@ main(int argc, char *argv[])
+ {
+ 	int i;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #odbc_test(i INT, t TEXT)");
++	odbc_command("CREATE TABLE #odbc_test(i INT, t TEXT)");
+ 	for (i = 0; i < 10; ++i) {
+ 		char buf[128];
+ 
+ 		sprintf(buf, "INSERT INTO #odbc_test(i, t) VALUES(%d, '%crow number %d')", i + 1, 'a' + i, i * 13);
+-		Command(buf);
++		odbc_command(buf);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	test_query = "SELECT * FROM #odbc_test ORDER BY i";
+ 	printf("test line %d\n", __LINE__);
+@@ -166,7 +166,7 @@ main(int argc, char *argv[])
+ 
+ 	/* TODO bind offset, SQLGetData, no bind, error */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Success!.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/attributes.c b/src/odbc/unittests/attributes.c
+index 5e80352..8d18cbe 100644
+--- a/src/odbc/unittests/attributes.c
++++ b/src/odbc/unittests/attributes.c
+@@ -5,7 +5,7 @@
+  * SQLSetStmtAttr
+  */
+ 
+-static char software_version[] = "$Id: attributes.c,v 1.5 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: attributes.c,v 1.6 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -232,16 +232,16 @@ get_attr_stmt(ATTR_PARAMS)
+ 	case type_INTEGER:
+ 	case type_UINTEGER:
+ 		i = 0xdeadbeef;
+-		ret = SQLGetStmtAttr(Statement, attr->value, (SQLPOINTER) & i, sizeof(SQLINTEGER), &ind);
++		ret = SQLGetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) & i, sizeof(SQLINTEGER), &ind);
+ 		break;
+ 	case type_SMALLINT:
+ 		si = 0xbeef;
+-		ret = SQLGetStmtAttr(Statement, attr->value, (SQLPOINTER) & si, sizeof(SQLSMALLINT), &ind);
++		ret = SQLGetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) & si, sizeof(SQLSMALLINT), &ind);
+ 		i = si;
+ 		break;
+ 	case type_LEN:
+ 		li = 0xdeadbeef;
+-		ret = SQLGetStmtAttr(Statement, attr->value, (SQLPOINTER) & li, sizeof(SQLLEN), &ind);
++		ret = SQLGetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) & li, sizeof(SQLLEN), &ind);
+ 		i = li;
+ 		break;
+ 	case type_VOIDP:
+@@ -275,12 +275,12 @@ main(int argc, char *argv[])
+ 	SQLLEN len;
+ 	get_attr_t get_attr_p = get_attr_stmt;
+ 
+-	Connect();
++	odbc_connect();
+ 	/* TODO find another way */
+-	CheckCursor();
+-	Command("SET TEXTSIZE 4096");
++	odbc_check_cursor();
++	odbc_command("SET TEXTSIZE 4096");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
++	SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 
+ 	f = fopen(in_file, "r");
+ 	if (!f)
+@@ -307,12 +307,12 @@ main(int argc, char *argv[])
+ 		if (strcmp(cmd, "odbc") == 0) {
+ 			int odbc3 = get_int(strtok(NULL, SEP)) == 3 ? 1 : 0;
+ 
+-			if (use_odbc_version3 != odbc3) {
+-				use_odbc_version3 = odbc3;
+-				Disconnect();
+-				Connect();
+-				Command("SET TEXTSIZE 4096");
+-				SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
++			if (odbc_use_version3 != odbc3) {
++				odbc_use_version3 = odbc3;
++				odbc_disconnect();
++				odbc_connect();
++				odbc_command("SET TEXTSIZE 4096");
++				SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 			}
+ 			continue;
+ 		}
+@@ -330,19 +330,19 @@ main(int argc, char *argv[])
+ 			switch (attr->type) {
+ 			case type_UINTEGER:
+ 			case type_INTEGER:
+-				ret = SQLSetStmtAttr(Statement, attr->value, int2ptr(lookup(value, attr->lookup)),
++				ret = SQLSetStmtAttr(odbc_stmt, attr->value, int2ptr(lookup(value, attr->lookup)),
+ 						      sizeof(SQLINTEGER));
+ 				break;
+ 			case type_SMALLINT:
+-				ret = SQLSetStmtAttr(Statement, attr->value, int2ptr(lookup(value, attr->lookup)),
++				ret = SQLSetStmtAttr(odbc_stmt, attr->value, int2ptr(lookup(value, attr->lookup)),
+ 						      sizeof(SQLSMALLINT));
+ 				break;
+ 			case type_LEN:
+-				ret = SQLSetStmtAttr(Statement, attr->value, int2ptr(lookup(value, attr->lookup)),
++				ret = SQLSetStmtAttr(odbc_stmt, attr->value, int2ptr(lookup(value, attr->lookup)),
+ 						      sizeof(SQLLEN));
+ 				break;
+ 			case type_CHARP:
+-				ret = SQLSetStmtAttr(Statement, attr->value, (SQLPOINTER) value, SQL_NTS);
++				ret = SQLSetStmtAttr(odbc_stmt, attr->value, (SQLPOINTER) value, SQL_NTS);
+ 				break;
+ 			case type_VOIDP:
+ 			case type_DESC:
+@@ -372,7 +372,7 @@ main(int argc, char *argv[])
+ 		}
+ 
+ 		if (strcmp(cmd, "reset") == 0) {
+-			ResetStatement();
++			odbc_reset_statement();
+ 			continue;
+ 		}
+ 
+@@ -380,7 +380,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	fclose(f);
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return g_result;
+diff --git a/src/odbc/unittests/base.c b/src/odbc/unittests/base.c
+index f4b365f..2431474 100644
+--- a/src/odbc/unittests/base.c
++++ b/src/odbc/unittests/base.c
+@@ -2,18 +2,18 @@
+ 
+ /* TODO place comment here */
+ 
+-static char software_version[] = "$Id: base.c,v 1.1 2008/01/28 13:36:07 freddy77 Exp $";
++static char software_version[] = "$Id: base.c,v 1.2 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+ main(int argc, char *argv[])
+ {
+ 	/* TODO remove if not neeeded */
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	/* TODO write your test */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/binary_test.c b/src/odbc/unittests/binary_test.c
+index 87f5123..edb6fd3 100644
+--- a/src/odbc/unittests/binary_test.c
++++ b/src/odbc/unittests/binary_test.c
+@@ -7,7 +7,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: binary_test.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: binary_test.c,v 1.9 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define ERR_BUF_SIZE 256
+@@ -36,21 +36,21 @@ static void
+ clean_up(void)
+ {
+ 	free(buf);
+-	Disconnect();
++	odbc_disconnect();
+ }
+ 
+ static int
+ test_insert(void *buf, SQLLEN buflen)
+ {
+-	SQLHSTMT Statement = SQL_NULL_HSTMT;
++	SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
+ 	SQLLEN strlen_or_ind;
+ 	const char *qstr = "insert into " TEST_TABLE_NAME " values (?)";
+ 
+-	assert(Connection);
+-	assert(Environment);
++	assert(odbc_conn);
++	assert(odbc_env);
+ 
+ 	/* allocate new statement handle */
+-	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "SI");
++	CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
+ 
+ 	/* execute query */
+ 	CHKPrepare((SQLCHAR *) qstr, SQL_NTS, "SI");
+@@ -62,9 +62,9 @@ test_insert(void *buf, SQLLEN buflen)
+ 	CHKExecute("SI");
+ 
+ 	/* this command shouldn't fail */
+-	Command("DECLARE @i INT");
++	odbc_command("DECLARE @i INT");
+ 
+-	SQLFreeHandle(SQL_HANDLE_STMT, Statement);
++	SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
+ 	return 0;
+ }
+ 
+@@ -72,15 +72,15 @@ test_insert(void *buf, SQLLEN buflen)
+ static int
+ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ {
+-	SQLHSTMT Statement = SQL_NULL_HSTMT;
++	SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
+ 	SQLLEN strlen_or_ind = 0;
+ 	const char *qstr = "select * from " TEST_TABLE_NAME;
+ 
+-	assert(Connection);
+-	assert(Environment);
++	assert(odbc_conn);
++	assert(odbc_env);
+ 
+ 	/* allocate new statement handle */
+-	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "SI");
++	CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "SI");
+ 
+ 	/* execute query */
+ 	CHKExecDirect((SQLCHAR *) qstr, SQL_NTS, "SINo");
+@@ -96,7 +96,7 @@ test_select(void *buf, SQLINTEGER buflen, SQLLEN * bytes_returned)
+ 	/* ensure that this was the only row */
+ 	CHKFetch("No");
+ 
+-	SQLFreeHandle(SQL_HANDLE_STMT, Statement);
++	SQLFreeHandle(SQL_HANDLE_STMT, odbc_stmt);
+ 	return 0;
+ }
+ 
+@@ -111,10 +111,10 @@ main(int argc, char **argv)
+ 	/* do not allocate so big memory in stack */
+ 	buf = (unsigned char *) malloc(TEST_BUF_LEN);
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("create table " TEST_TABLE_NAME " (im IMAGE)");
+-	Command("SET TEXTSIZE 1000000");
++	odbc_command("create table " TEST_TABLE_NAME " (im IMAGE)");
++	odbc_command("SET TEXTSIZE 1000000");
+ 
+ 	/* populate test buffer with ramp */
+ 	for (i = 0; i < TEST_BUF_LEN; i++) {
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index 549943a..e2c5de7 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.21 2010/07/05 07:20:47 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.22 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -229,7 +229,7 @@ int
+ main(int argc, char **argv)
+ {
+ 	SQLRETURN RetCode;
+-	SQLHSTMT old_Statement = SQL_NULL_HSTMT;
++	SQLHSTMT old_odbc_stmt = SQL_NULL_HSTMT;
+ 	int i;
+ 
+ 	int key;
+@@ -238,8 +238,8 @@ main(int argc, char **argv)
+ 	char sql[256];
+ 	test_info *t = NULL;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	/* tests (W)CHAR/BINARY -> (W)CHAR/BINARY (9 cases) */
+ 	add_test(SQL_C_BINARY, SQL_LONGVARCHAR,   "TEXT",  123, 1 );
+@@ -248,7 +248,7 @@ main(int argc, char **argv)
+ 	add_test(SQL_C_CHAR,   SQL_LONGVARCHAR,   "TEXT",  343, 47);
+ 	add_test(SQL_C_WCHAR,  SQL_LONGVARBINARY, "IMAGE", 561, 29);
+ 	add_test(SQL_C_WCHAR,  SQL_LONGVARCHAR,   "TEXT",  698, 24);
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 		add_test(SQL_C_BINARY, SQL_WLONGVARCHAR, "NTEXT", 765, 12);
+ 		add_test(SQL_C_CHAR,   SQL_WLONGVARCHAR, "NTEXT", 237, 71);
+ 		add_test(SQL_C_WCHAR,  SQL_WLONGVARCHAR, "NTEXT", 687, 68);
+@@ -258,19 +258,19 @@ main(int argc, char **argv)
+ 	for (t = test_infos; t < test_infos+num_tests; ++t)
+ 		sprintf(strchr(sql, 0), ",f%u %s", t->num, t->db_type);
+ 	strcat(sql, ",v INT)");
+-	Command(sql);
++	odbc_command(sql);
+ 
+-	old_Statement = Statement;
+-	Statement = SQL_NULL_HSTMT;
++	old_odbc_stmt = odbc_stmt;
++	odbc_stmt = SQL_NULL_HSTMT;
+ 
+ 	/* Insert rows ... */
+ 
+ 	for (i = 0; i < cnt; i++) {
+ 		/* MS do not save correctly char -> binary */
+-		if (!driver_is_freetds() && i)
++		if (!odbc_driver_is_freetds() && i)
+ 			continue;
+ 
+-		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
++		CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "S");
+ 
+ 		strcpy(sql, "INSERT INTO #tt VALUES(?");
+ 		for (t = test_infos; t < test_infos+num_tests; ++t)
+@@ -322,8 +322,8 @@ main(int argc, char **argv)
+ 			}
+ 		}
+ 
+-		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+-		Statement = SQL_NULL_HSTMT;
++		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
++		odbc_stmt = SQL_NULL_HSTMT;
+ 	}
+ 
+ 	/* Now fetch rows ... */
+@@ -331,13 +331,13 @@ main(int argc, char **argv)
+ 	for (wide = 0; wide < 2; ++wide)
+ 	for (i = 0; i < cnt; i++) {
+ 		/* MS do not save correctly char -> binary */
+-		if (!driver_is_freetds() && i)
++		if (!odbc_driver_is_freetds() && i)
+ 			continue;
+ 
+ 
+-		CHKAllocHandle(SQL_HANDLE_STMT, Connection, &Statement, "S");
++		CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &odbc_stmt, "S");
+ 
+-		if (db_is_microsoft()) {
++		if (odbc_db_is_microsoft()) {
+ 			CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
+ 			CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+ 		}
+@@ -371,14 +371,14 @@ main(int argc, char **argv)
+ 		}
+ 
+ 		CHKCloseCursor("S");
+-		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+-		Statement = SQL_NULL_HSTMT;
++		CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
++		odbc_stmt = SQL_NULL_HSTMT;
+ 	}
+ 
+-	Statement = old_Statement;
++	odbc_stmt = old_odbc_stmt;
+ 
+ 	free_tests();
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	if (!failed)
+ 		printf("ok!\n");
+diff --git a/src/odbc/unittests/cancel.c b/src/odbc/unittests/cancel.c
+index 1f9a4b8..1d8db59 100644
+--- a/src/odbc/unittests/cancel.c
++++ b/src/odbc/unittests/cancel.c
+@@ -105,22 +105,22 @@ Test(int use_threads)
+ 	} else {
+ 		pthread_join(wait_thread, NULL);
+ 	}
+-	getErrorInfo(SQL_HANDLE_STMT, Statement);
++	getErrorInfo(SQL_HANDLE_STMT, odbc_stmt);
+ 	if (strcmp(sqlstate, "HY008") != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+-	Command("SELECT name FROM sysobjects WHERE 0=1");
++	odbc_command("SELECT name FROM sysobjects WHERE 0=1");
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+ 	/*
+@@ -128,11 +128,11 @@ main(int argc, char **argv)
+ 	 * is better to do it before connect cause uniODBC cache INIs
+ 	 * the name must be odbcinst.ini cause unixODBC accept only this name
+ 	 */
+-	if (DRIVER[0]) {
++	if (odbc_driver[0]) {
+ 		FILE *f = fopen("odbcinst.ini", "w");
+ 
+ 		if (f) {
+-			fprintf(f, "[FreeTDS]\nDriver = %s\nThreading = 0\n", DRIVER);
++			fprintf(f, "[FreeTDS]\nDriver = %s\nThreading = 0\n", odbc_driver);
+ 			fclose(f);
+ 			/* force iODBC */
+ 			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
+@@ -142,13 +142,13 @@ main(int argc, char **argv)
+ 		}
+ 	}
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	Test(0);
+ 	Test(1);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+ 
+diff --git a/src/odbc/unittests/common.c b/src/odbc/unittests/common.c
+index 433205c..aeefb4f 100644
+--- a/src/odbc/unittests/common.c
++++ b/src/odbc/unittests/common.c
+@@ -13,20 +13,20 @@
+ #define TDS_SDIR_SEPARATOR "\\"
+ #endif
+ 
+-static char software_version[] = "$Id: common.c,v 1.58 2010/07/05 07:20:47 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.59 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-HENV Environment;
+-HDBC Connection;
+-HSTMT Statement;
+-int use_odbc_version3 = 0;
++HENV odbc_env;
++HDBC odbc_conn;
++HSTMT odbc_stmt;
++int odbc_use_version3 = 0;
+ void (*odbc_set_conn_attr)(void) = NULL;
+ 
+-char USER[512];
+-char SERVER[512];
+-char PASSWORD[512];
+-char DATABASE[512];
+-char DRIVER[1024];
++char odbc_user[512];
++char odbc_server[512];
++char odbc_password[512];
++char odbc_database[512];
++char odbc_driver[1024];
+ 
+ #ifndef _WIN32
+ static int
+@@ -61,7 +61,7 @@ odbc_setenv(const char *name, const char *value, int overwrite)
+ #endif
+ 
+ int
+-read_login_info(void)
++odbc_read_login_info(void)
+ {
+ 	static const char *PWD = "../../../PWD";
+ 	FILE *in = NULL;
+@@ -93,13 +93,13 @@ read_login_info(void)
+ 		if (!s1 || !s2)
+ 			continue;
+ 		if (!strcmp(s1, "UID")) {
+-			strcpy(USER, s2);
++			strcpy(odbc_user, s2);
+ 		} else if (!strcmp(s1, "SRV")) {
+-			strcpy(SERVER, s2);
++			strcpy(odbc_server, s2);
+ 		} else if (!strcmp(s1, "PWD")) {
+-			strcpy(PASSWORD, s2);
++			strcpy(odbc_password, s2);
+ 		} else if (!strcmp(s1, "DB")) {
+-			strcpy(DATABASE, s2);
++			strcpy(odbc_database, s2);
+ 		}
+ 	}
+ 	fclose(in);
+@@ -124,12 +124,12 @@ read_login_info(void)
+ 	    && !check_lib(path, ".libs/libtdsodbc.dll") && !check_lib(path, ".libs/libtdsodbc.dylib")
+ 	    && !check_lib(path, "_libs/libtdsodbc.exe"))
+ 		return 0;
+-	strcpy(DRIVER, path);
++	strcpy(odbc_driver, path);
+ 
+ 	/* craft out odbc.ini, avoid to read wrong one */
+ 	in = fopen("odbc.ini", "w");
+ 	if (in) {
+-		fprintf(in, "[%s]\nDriver = %s\nDatabase = %s\nServername = %s\n", SERVER, DRIVER, DATABASE, SERVER);
++		fprintf(in, "[%s]\nDriver = %s\nDatabase = %s\nServername = %s\n", odbc_server, odbc_driver, odbc_database, odbc_server);
+ 		fclose(in);
+ 		setenv("ODBCINI", "./odbc.ini", 1);
+ 		setenv("SYSODBCINI", "./odbc.ini", 1);
+@@ -139,7 +139,7 @@ read_login_info(void)
+ }
+ 
+ void
+-ReportError(const char *errmsg, int line, const char *file)
++odbc_report_error(const char *errmsg, int line, const char *file)
+ {
+ 	SQLSMALLINT handletype;
+ 	SQLHANDLE handle;
+@@ -148,15 +148,15 @@ ReportError(const char *errmsg, int line, const char *file)
+ 	unsigned char msg[256];
+ 
+ 
+-	if (Statement) {
++	if (odbc_stmt) {
+ 		handletype = SQL_HANDLE_STMT;
+-		handle = Statement;
+-	} else if (Connection) {
++		handle = odbc_stmt;
++	} else if (odbc_conn) {
+ 		handletype = SQL_HANDLE_DBC;
+-		handle = Connection;
++		handle = odbc_conn;
+ 	} else {
+ 		handletype = SQL_HANDLE_ENV;
+-		handle = Environment;
++		handle = odbc_env;
+ 	}
+ 	if (errmsg[0]) {
+ 		if (line)
+@@ -167,7 +167,7 @@ ReportError(const char *errmsg, int line, const char *file)
+ 	ret = SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+ 	if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
+ 		fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
+-	Disconnect();
++	odbc_disconnect();
+ 	exit(1);
+ }
+ 
+@@ -188,73 +188,73 @@ ReportODBCError(const char *errmsg, SQLSMALLINT handletype, SQLHANDLE handle, SQ
+ 	ret = SQLGetDiagRec(handletype, handle, 1, sqlstate, NULL, msg, sizeof(msg), NULL);
+ 	if (ret == SQL_SUCCESS || ret == SQL_SUCCESS_WITH_INFO)
+ 		fprintf(stderr, "SQL error %s -- %s\n", sqlstate, msg);
+-	Disconnect();
++	odbc_disconnect();
+ 	exit(1);
+ }
+ 
+ int
+-Connect(void)
++odbc_connect(void)
+ {
+ 	char command[512];
+ 
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+-	if (use_odbc_version3) {
+-		CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &Environment, "S");
+-		SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-		CHKAllocHandle(SQL_HANDLE_DBC, Environment, &Connection, "S");
++	if (odbc_use_version3) {
++		CHKAllocHandle(SQL_HANDLE_ENV, SQL_NULL_HANDLE, &odbc_env, "S");
++		SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++		CHKAllocHandle(SQL_HANDLE_DBC, odbc_env, &odbc_conn, "S");
+ 	} else {
+-		CHKAllocEnv(&Environment, "S");
+-		CHKAllocConnect(&Connection, "S");
++		CHKAllocEnv(&odbc_env, "S");
++		CHKAllocConnect(&odbc_conn, "S");
+ 	}
+ 
+ 	printf("odbctest\n--------\n\n");
+ 	printf("connection parameters:\nserver:   '%s'\nuser:     '%s'\npassword: '%s'\ndatabase: '%s'\n",
+-	       SERVER, USER, "????" /* PASSWORD */ , DATABASE);
++	       odbc_server, odbc_user, "????" /* odbc_password */ , odbc_database);
+ 
+ 	if (odbc_set_conn_attr)
+ 		(*odbc_set_conn_attr)();
+ 
+-	CHKR(SQLConnect, (Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS), "SI");
++	CHKR(SQLConnect, (odbc_conn, (SQLCHAR *) odbc_server, SQL_NTS, (SQLCHAR *) odbc_user, SQL_NTS, (SQLCHAR *) odbc_password, SQL_NTS), "SI");
+ 
+-	CHKAllocStmt(&Statement, "S");
++	CHKAllocStmt(&odbc_stmt, "S");
+ 
+-	sprintf(command, "use %s", DATABASE);
++	sprintf(command, "use %s", odbc_database);
+ 	printf("%s\n", command);
+ 
+ 	CHKExecDirect((SQLCHAR *) command, SQL_NTS, "SI");
+ 
+ #ifndef TDS_NO_DM
+ 	/* unixODBC seems to require it */
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ #endif
+ 	return 0;
+ }
+ 
+ int
+-Disconnect(void)
++odbc_disconnect(void)
+ {
+-	if (Statement) {
+-		SQLFreeStmt(Statement, SQL_DROP);
+-		Statement = SQL_NULL_HSTMT;
++	if (odbc_stmt) {
++		SQLFreeStmt(odbc_stmt, SQL_DROP);
++		odbc_stmt = SQL_NULL_HSTMT;
+ 	}
+ 
+-	if (Connection) {
+-		SQLDisconnect(Connection);
+-		SQLFreeConnect(Connection);
+-		Connection = SQL_NULL_HDBC;
++	if (odbc_conn) {
++		SQLDisconnect(odbc_conn);
++		SQLFreeConnect(odbc_conn);
++		odbc_conn = SQL_NULL_HDBC;
+ 	}
+ 
+-	if (Environment) {
+-		SQLFreeEnv(Environment);
+-		Environment = SQL_NULL_HENV;
++	if (odbc_env) {
++		SQLFreeEnv(odbc_env);
++		odbc_env = SQL_NULL_HENV;
+ 	}
+ 	return 0;
+ }
+ 
+ SQLRETURN
+-CommandWithResult(HSTMT stmt, const char *command)
++odbc_command_with_result(HSTMT stmt, const char *command)
+ {
+ 	printf("%s\n", command);
+ 	return SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS);
+@@ -262,7 +262,7 @@ CommandWithResult(HSTMT stmt, const char *command)
+ 
+ static int ms_db = -1;
+ int
+-db_is_microsoft(void)
++odbc_db_is_microsoft(void)
+ {
+ 	char buf[64];
+ 	SQLSMALLINT len;
+@@ -270,7 +270,7 @@ db_is_microsoft(void)
+ 
+ 	if (ms_db < 0) {
+ 		buf[0] = 0;
+-		SQLGetInfo(Connection, SQL_DBMS_NAME, buf, sizeof(buf), &len);
++		SQLGetInfo(odbc_conn, SQL_DBMS_NAME, buf, sizeof(buf), &len);
+ 		for (i = 0; buf[i]; ++i)
+ 			buf[i] = tolower(buf[i]);
+ 		ms_db = (strstr(buf, "microsoft") != NULL);
+@@ -280,7 +280,7 @@ db_is_microsoft(void)
+ 
+ static int freetds_driver = -1;
+ int
+-driver_is_freetds(void)
++odbc_driver_is_freetds(void)
+ {
+ 	char buf[64];
+ 	SQLSMALLINT len;
+@@ -288,7 +288,7 @@ driver_is_freetds(void)
+ 
+ 	if (freetds_driver < 0) {
+ 		buf[0] = 0;
+-		SQLGetInfo(Connection, SQL_DRIVER_NAME, buf, sizeof(buf), &len);
++		SQLGetInfo(odbc_conn, SQL_DRIVER_NAME, buf, sizeof(buf), &len);
+ 		for (i = 0; buf[i]; ++i)
+ 			buf[i] = tolower(buf[i]);
+ 		freetds_driver = (strstr(buf, "tds") != NULL);
+@@ -298,22 +298,22 @@ driver_is_freetds(void)
+ 
+ static char db_str_version[32];
+ 
+-const char *db_version(void)
++const char *odbc_db_version(void)
+ {
+ 	SQLSMALLINT version_len;
+ 
+ 	if (!db_str_version[0])
+-		CHKR(SQLGetInfo, (Connection, SQL_DBMS_VER, db_str_version, sizeof(db_str_version), &version_len), "S");
++		CHKR(SQLGetInfo, (odbc_conn, SQL_DBMS_VER, db_str_version, sizeof(db_str_version), &version_len), "S");
+ 
+ 	return db_str_version;
+ }
+ 
+-unsigned int db_version_int(void)
++unsigned int odbc_db_version_int(void)
+ {
+ 	unsigned int h, l;
+-	if (sscanf(db_version(), "%u.%u.", &h, &l) != 2) {
+-		fprintf(stderr, "Wrong db version: %s\n", db_version());
+-		Disconnect();
++	if (sscanf(odbc_db_version(), "%u.%u.", &h, &l) != 2) {
++		fprintf(stderr, "Wrong db version: %s\n", odbc_db_version());
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ 
+@@ -321,7 +321,7 @@ unsigned int db_version_int(void)
+ }
+ 
+ void
+-CheckCols(int n, int line, const char * file)
++odbc_check_cols(int n, int line, const char * file)
+ {
+ 	SQLSMALLINT cols;
+ 
+@@ -332,13 +332,13 @@ CheckCols(int n, int line, const char * file)
+ 	CHKNumResultCols(&cols, "S");
+ 	if (cols != n) {
+ 		fprintf(stderr, "%s:%d: Expected %d columns returned %d\n", file, line, n, (int) cols);
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ }
+ 
+ void
+-CheckRows(int n, int line, const char * file)
++odbc_check_rows(int n, int line, const char * file)
+ {
+ 	SQLLEN rows;
+ 
+@@ -350,43 +350,43 @@ CheckRows(int n, int line, const char * file)
+ 	CHKRowCount(&rows, "S");
+ 	if (rows != n) {
+ 		fprintf(stderr, "%s:%d: Expected %d rows returned %d\n", file, line, n, (int) rows);
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ }
+ 
+ void
+-ResetStatementProc(SQLHSTMT *stmt, const char *file, int line)
++odbc_reset_statement_proc(SQLHSTMT *stmt, const char *file, int line)
+ {
+ 	SQLFreeStmt(*stmt, SQL_DROP);
+ 	*stmt = SQL_NULL_HSTMT;
+-	CheckRes(file, line, SQLAllocStmt(Connection, stmt), SQL_HANDLE_DBC, Connection, "SQLAllocStmt", "S");
++	odbc_check_res(file, line, SQLAllocStmt(odbc_conn, stmt), SQL_HANDLE_DBC, odbc_conn, "SQLAllocStmt", "S");
+ }
+ 
+ void
+-CheckCursor(void)
++odbc_check_cursor(void)
+ {
+ 	SQLRETURN retcode;
+ 
+-	retcode = SQLSetStmtAttr(Statement, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
++	retcode = SQLSetStmtAttr(odbc_stmt, SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0);
+ 	if (retcode != SQL_SUCCESS) {
+ 		char output[256];
+ 		unsigned char sqlstate[6];
+ 
+-		CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL, "S");
++		CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, (SQLCHAR *) output, sizeof(output), NULL, "S");
+ 		sqlstate[5] = 0;
+ 		if (strcmp((const char*) sqlstate, "01S02") == 0) {
+ 			printf("Your connection seems to not support cursors, probably you are using wrong protocol version or Sybase\n");
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(0);
+ 		}
+-		ReportODBCError("SQLSetStmtAttr", SQL_HANDLE_STMT, Statement, retcode, __LINE__, __FILE__);
++		ReportODBCError("SQLSetStmtAttr", SQL_HANDLE_STMT, odbc_stmt, retcode, __LINE__, __FILE__);
+ 	}
+-	ResetStatement();
++	odbc_reset_statement();
+ }
+ 
+ SQLRETURN
+-CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res)
++odbc_check_res(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res)
+ {
+ 	const char *p = res;
+ 	for (;;) {
+@@ -413,7 +413,7 @@ CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLH
+ 		} else if (!*p) {
+ 			break;
+ 		} else {
+-			ReportError("Wrong results specified", line, file);
++			odbc_report_error("Wrong results specified", line, file);
+ 			return rc;
+ 		}
+ 	}
+@@ -422,7 +422,7 @@ CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLH
+ }
+ 
+ SQLSMALLINT
+-AllocHandleErrType(SQLSMALLINT type)
++odbc_alloc_handle_err_type(SQLSMALLINT type)
+ {
+ 	switch (type) {
+ 	case SQL_HANDLE_DESC:
+@@ -436,21 +436,21 @@ AllocHandleErrType(SQLSMALLINT type)
+ }
+ 
+ SQLRETURN
+-CommandProc(HSTMT stmt, const char *command, const char *file, int line, const char *res)
++odbc_command_proc(HSTMT stmt, const char *command, const char *file, int line, const char *res)
+ {
+ 	printf("%s\n", command);
+-	return CheckRes(file, line, SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS), SQL_HANDLE_STMT, stmt, "Command", res);
++	return odbc_check_res(file, line, SQLExecDirect(stmt, (SQLCHAR *) command, SQL_NTS), SQL_HANDLE_STMT, stmt, "odbc_command", res);
+ }
+ 
+ char odbc_err[512];
+ char odbc_sqlstate[6];
+ 
+ void
+-ReadError(void)
++odbc_read_error(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+ 	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+ }
+ 
+diff --git a/src/odbc/unittests/common.h b/src/odbc/unittests/common.h
+index 7de56da..b55a3b3 100644
+--- a/src/odbc/unittests/common.h
++++ b/src/odbc/unittests/common.h
+@@ -21,7 +21,7 @@
+ #include <sql.h>
+ #include <sqlext.h>
+ 
+-static char rcsid_common_h[] = "$Id: common.h,v 1.33 2010/07/05 07:20:47 freddy77 Exp $";
++static char rcsid_common_h[] = "$Id: common.h,v 1.34 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_warn };
+ 
+ #ifndef HAVE_SQLLEN
+@@ -33,135 +33,135 @@ static void *no_unused_common_h_warn[] = { rcsid_common_h, no_unused_common_h_wa
+ #endif
+ #endif
+ 
+-extern HENV Environment;
+-extern HDBC Connection;
+-extern HSTMT Statement;
+-extern int use_odbc_version3;
++extern HENV odbc_env;
++extern HDBC odbc_conn;
++extern HSTMT odbc_stmt;
++extern int odbc_use_version3;
+ extern void (*odbc_set_conn_attr)(void);
+ extern char odbc_err[512];
+ extern char odbc_sqlstate[6];
+ 
+ 
+-extern char USER[512];
+-extern char SERVER[512];
+-extern char PASSWORD[512];
+-extern char DATABASE[512];
+-extern char DRIVER[1024];
++extern char odbc_user[512];
++extern char odbc_server[512];
++extern char odbc_password[512];
++extern char odbc_database[512];
++extern char odbc_driver[1024];
+ 
+-int read_login_info(void);
+-void ReportError(const char *msg, int line, const char *file);
+-void ReadError(void);
++int odbc_read_login_info(void);
++void odbc_report_error(const char *msg, int line, const char *file);
++void odbc_read_error(void);
+ 
+ 
+-void CheckCols(int n, int line, const char * file);
+-void CheckRows(int n, int line, const char * file);
+-#define CHECK_ROWS(n) CheckRows(n, __LINE__, __FILE__)
+-#define CHECK_COLS(n) CheckCols(n, __LINE__, __FILE__)
+-void ResetStatementProc(SQLHSTMT *stmt, const char *file, int line);
+-#define ResetStatement() ResetStatementProc(&Statement, __FILE__, __LINE__)
+-void CheckCursor(void);
++void odbc_check_cols(int n, int line, const char * file);
++void odbc_check_rows(int n, int line, const char * file);
++#define ODBC_CHECK_ROWS(n) odbc_check_rows(n, __LINE__, __FILE__)
++#define ODBC_CHECK_COLS(n) odbc_check_cols(n, __LINE__, __FILE__)
++void odbc_reset_statement_proc(SQLHSTMT *stmt, const char *file, int line);
++#define odbc_reset_statement() odbc_reset_statement_proc(&odbc_stmt, __FILE__, __LINE__)
++void odbc_check_cursor(void);
+ 
+-#define ODBC_REPORT_ERROR(msg) ReportError(msg, __LINE__, __FILE__)
++#define ODBC_REPORT_ERROR(msg) odbc_report_error(msg, __LINE__, __FILE__)
+ 
+-SQLRETURN CheckRes(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res);
++SQLRETURN odbc_check_res(const char *file, int line, SQLRETURN rc, SQLSMALLINT handle_type, SQLHANDLE handle, const char *func, const char *res);
+ #define CHKR(func, params, res) \
+-	CheckRes(__FILE__, __LINE__, (func params), 0, 0, #func, res)
++	odbc_check_res(__FILE__, __LINE__, (func params), 0, 0, #func, res)
+ #define CHKR2(func, params, type, handle, res) \
+-	CheckRes(__FILE__, __LINE__, (func params), type, handle, #func, res)
++	odbc_check_res(__FILE__, __LINE__, (func params), type, handle, #func, res)
+ 
+-SQLSMALLINT AllocHandleErrType(SQLSMALLINT type);
++SQLSMALLINT odbc_alloc_handle_err_type(SQLSMALLINT type);
+ 
+ #define CHKAllocConnect(a,res) \
+-	CHKR2(SQLAllocConnect, (Environment,a), SQL_HANDLE_ENV, Environment, res)
++	CHKR2(SQLAllocConnect, (odbc_env,a), SQL_HANDLE_ENV, odbc_env, res)
+ #define CHKAllocEnv(a,res) \
+ 	CHKR2(SQLAllocEnv, (a), 0, 0, res)
+ #define CHKAllocStmt(a,res) \
+-	CHKR2(SQLAllocStmt, (Connection,a), SQL_HANDLE_DBC, Connection, res)
++	CHKR2(SQLAllocStmt, (odbc_conn,a), SQL_HANDLE_DBC, odbc_conn, res)
+ #define CHKAllocHandle(a,b,c,res) \
+-	CHKR2(SQLAllocHandle, (a,b,c), AllocHandleErrType(a), b, res)
++	CHKR2(SQLAllocHandle, (a,b,c), odbc_alloc_handle_err_type(a), b, res)
+ #define CHKBindCol(a,b,c,d,e,res) \
+-	CHKR2(SQLBindCol, (Statement,a,b,c,d,e), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLBindCol, (odbc_stmt,a,b,c,d,e), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKBindParameter(a,b,c,d,e,f,g,h,i,res) \
+-	CHKR2(SQLBindParameter, (Statement,a,b,c,d,e,f,g,h,i), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLBindParameter, (odbc_stmt,a,b,c,d,e,f,g,h,i), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKCancel(res) \
+-	CHKR2(SQLCancel, (Statement), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLCancel, (odbc_stmt), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKCloseCursor(res) \
+-	CHKR2(SQLCloseCursor, (Statement), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLCloseCursor, (odbc_stmt), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKColAttribute(a,b,c,d,e,f,res) \
+-	CHKR2(SQLColAttribute, (Statement,a,b,c,d,e,f), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLColAttribute, (odbc_stmt,a,b,c,d,e,f), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKDescribeCol(a,b,c,d,e,f,g,h,res) \
+-	CHKR2(SQLDescribeCol, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLDescribeCol, (odbc_stmt,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKDriverConnect(a,b,c,d,e,f,g,res) \
+-	CHKR2(SQLDriverConnect, (Connection,a,b,c,d,e,f,g), SQL_HANDLE_DBC, Connection, res)
++	CHKR2(SQLDriverConnect, (odbc_conn,a,b,c,d,e,f,g), SQL_HANDLE_DBC, odbc_conn, res)
+ #define CHKEndTran(a,b,c,res) \
+ 	CHKR2(SQLEndTran, (a,b,c), a, b, res)
+ #define CHKExecDirect(a,b,res) \
+-	CHKR2(SQLExecDirect, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLExecDirect, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKExecute(res) \
+-	CHKR2(SQLExecute, (Statement), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLExecute, (odbc_stmt), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKExtendedFetch(a,b,c,d,res) \
+-	CHKR2(SQLExtendedFetch, (Statement,a,b,c,d), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLExtendedFetch, (odbc_stmt,a,b,c,d), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKFetch(res) \
+-	CHKR2(SQLFetch, (Statement), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLFetch, (odbc_stmt), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKFetchScroll(a,b,res) \
+-	CHKR2(SQLFetchScroll, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLFetchScroll, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKFreeHandle(a,b,res) \
+ 	CHKR2(SQLFreeHandle, (a,b), a, b, res)
+ #define CHKFreeStmt(a,res) \
+-	CHKR2(SQLFreeStmt, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLFreeStmt, (odbc_stmt,a), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKGetConnectAttr(a,b,c,d,res) \
+-	CHKR2(SQLGetConnectAttr, (Connection,a,b,c,d), SQL_HANDLE_DBC, Connection, res)
++	CHKR2(SQLGetConnectAttr, (odbc_conn,a,b,c,d), SQL_HANDLE_DBC, odbc_conn, res)
+ #define CHKGetDiagRec(a,b,c,d,e,f,g,h,res) \
+ 	CHKR2(SQLGetDiagRec, (a,b,c,d,e,f,g,h), a, b, res)
+ #define CHKGetStmtAttr(a,b,c,d,res) \
+-	CHKR2(SQLGetStmtAttr, (Statement,a,b,c,d), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLGetStmtAttr, (odbc_stmt,a,b,c,d), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKGetTypeInfo(a,res) \
+-	CHKR2(SQLGetTypeInfo, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLGetTypeInfo, (odbc_stmt,a), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKGetData(a,b,c,d,e,res) \
+-	CHKR2(SQLGetData, (Statement,a,b,c,d,e), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLGetData, (odbc_stmt,a,b,c,d,e), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKMoreResults(res) \
+-	CHKR2(SQLMoreResults, (Statement), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLMoreResults, (odbc_stmt), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKNumResultCols(a,res) \
+-	CHKR2(SQLNumResultCols, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLNumResultCols, (odbc_stmt,a), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKParamData(a,res) \
+-	CHKR2(SQLParamData, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLParamData, (odbc_stmt,a), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKParamOptions(a,b,res) \
+-	CHKR2(SQLParamOptions, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLParamOptions, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKPrepare(a,b,res) \
+-	CHKR2(SQLPrepare, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLPrepare, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKPutData(a,b,res) \
+-	CHKR2(SQLPutData, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLPutData, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKRowCount(a,res) \
+-	CHKR2(SQLRowCount, (Statement,a), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLRowCount, (odbc_stmt,a), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKSetConnectAttr(a,b,c,res) \
+-	CHKR2(SQLSetConnectAttr, (Connection,a,b,c), SQL_HANDLE_DBC, Connection, res)
++	CHKR2(SQLSetConnectAttr, (odbc_conn,a,b,c), SQL_HANDLE_DBC, odbc_conn, res)
+ #define CHKSetCursorName(a,b,res) \
+-	CHKR2(SQLSetCursorName, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLSetCursorName, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKSetPos(a,b,c,res) \
+-	CHKR2(SQLSetPos, (Statement,a,b,c), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLSetPos, (odbc_stmt,a,b,c), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKSetStmtAttr(a,b,c,res) \
+-	CHKR2(SQLSetStmtAttr, (Statement,a,b,c), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLSetStmtAttr, (odbc_stmt,a,b,c), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKSetStmtOption(a,b,res) \
+-	CHKR2(SQLSetStmtOption, (Statement,a,b), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLSetStmtOption, (odbc_stmt,a,b), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKTables(a,b,c,d,e,f,g,h,res) \
+-	CHKR2(SQLTables, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLTables, (odbc_stmt,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKProcedureColumns(a,b,c,d,e,f,g,h,res) \
+-	CHKR2(SQLProcedureColumns, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLProcedureColumns, (odbc_stmt,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKColumns(a,b,c,d,e,f,g,h,res) \
+-	CHKR2(SQLColumns, (Statement,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, Statement, res)
++	CHKR2(SQLColumns, (odbc_stmt,a,b,c,d,e,f,g,h), SQL_HANDLE_STMT, odbc_stmt, res)
+ #define CHKGetDescRec(a,b,c,d,e,f,g,h,i,j,res) \
+ 	CHKR2(SQLGetDescRec, (Descriptor,a,b,c,d,e,f,g,h,i,j), SQL_HANDLE_STMT, Descriptor, res)
+ 
+-int Connect(void);
+-int Disconnect(void);
+-SQLRETURN CommandProc(HSTMT stmt, const char *command, const char *file, int line, const char *res);
+-#define Command(cmd) CommandProc(Statement, cmd, __FILE__, __LINE__, "SNo")
+-#define Command2(cmd, res) CommandProc(Statement, cmd, __FILE__, __LINE__, res)
+-SQLRETURN CommandWithResult(HSTMT stmt, const char *command);
+-int db_is_microsoft(void);
+-const char *db_version(void);
+-unsigned int db_version_int(void);
+-int driver_is_freetds(void);
++int odbc_connect(void);
++int odbc_disconnect(void);
++SQLRETURN odbc_command_proc(HSTMT stmt, const char *command, const char *file, int line, const char *res);
++#define odbc_command(cmd) odbc_command_proc(odbc_stmt, cmd, __FILE__, __LINE__, "SNo")
++#define odbc_command2(cmd, res) odbc_command_proc(odbc_stmt, cmd, __FILE__, __LINE__, res)
++SQLRETURN odbc_command_with_result(HSTMT stmt, const char *command);
++int odbc_db_is_microsoft(void);
++const char *odbc_db_version(void);
++unsigned int odbc_db_version_int(void);
++int odbc_driver_is_freetds(void);
+ 
+ #define int2ptr(i) ((void*)(((char*)0)+(i)))
+ #define ptr2int(p) ((int)(((char*)(p))-((char*)0)))
+diff --git a/src/odbc/unittests/compute.c b/src/odbc/unittests/compute.c
+index 1ade523..52679ab 100644
+--- a/src/odbc/unittests/compute.c
++++ b/src/odbc/unittests/compute.c
+@@ -9,7 +9,7 @@
+  * and declared in odbcss.h
+  */
+ 
+-static char software_version[] = "$Id: compute.c,v 1.12 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: compute.c,v 1.13 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char col1[256], col2[256];
+@@ -40,7 +40,7 @@ TestName(SQLSMALLINT index, const char *expected_name)
+ 
+ 	/* retrieve with SQLColAttribute */
+ 	CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		NAME_TEST;
+ 	CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
+ 	NAME_TEST;
+@@ -76,14 +76,14 @@ CheckFetch(const char *c1name, const char *c1, const char *c2)
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+-	Command("create table #tmp1 (c varchar(20), i int)");
+-	Command("insert into #tmp1 values('pippo', 12)");
+-	Command("insert into #tmp1 values('pippo', 34)");
+-	Command("insert into #tmp1 values('pluto', 1)");
+-	Command("insert into #tmp1 values('pluto', 2)");
+-	Command("insert into #tmp1 values('pluto', 3)");
++	odbc_command("create table #tmp1 (c varchar(20), i int)");
++	odbc_command("insert into #tmp1 values('pippo', 12)");
++	odbc_command("insert into #tmp1 values('pippo', 34)");
++	odbc_command("insert into #tmp1 values('pluto', 1)");
++	odbc_command("insert into #tmp1 values('pluto', 2)");
++	odbc_command("insert into #tmp1 values('pluto', 3)");
+ 
+ 
+ 	/* 
+@@ -93,9 +93,9 @@ main(int argc, char *argv[])
+ 
+ 
+ 	/* select * from #tmp1 compute sum(i) */
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+-	Command("select * from #tmp1 order by c, i compute sum(i)");
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	odbc_command("select * from #tmp1 order by c, i compute sum(i)");
+ 	CheckFetch("c", "pippo", "12");
+ 	CheckFetch("c", "pippo", "34");
+ 	CheckFetch("c", "pluto", "1");
+@@ -105,8 +105,8 @@ main(int argc, char *argv[])
+ 	CHKMoreResults("S");
+ 
+ 	/* why I need to rebind ?? ms bug of feature ?? */
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	col2[0] = '@';
+ 	CheckFetch("sum", "52", "@");
+ 	CHKFetch("No");
+@@ -116,38 +116,38 @@ main(int argc, char *argv[])
+ 
+ 
+ 	/* select * from #tmp1 order by c compute sum(i) by c */
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+-	Command("select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	odbc_command("select c as mao, i from #tmp1 order by c, i compute sum(i) by c compute max(i)");
+ 	CheckFetch("mao", "pippo", "12");
+ 	CheckFetch("mao", "pippo", "34");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	strcpy(col2, "##");
+ 	CheckFetch("sum", "46", "##");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	CheckFetch("mao", "pluto", "1");
+ 	CheckFetch("mao", "pluto", "2");
+ 	CheckFetch("mao", "pluto", "3");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	strcpy(col2, "%");
+ 	CheckFetch("sum", "6", "%");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	strcpy(col2, "&");
+ 	CheckFetch("max", "34", "&");
+ 	CHKFetch("No");
+@@ -158,9 +158,9 @@ main(int argc, char *argv[])
+ 	/* test skip recordset with computed rows */
+ 
+ 	/* select * from #tmp1 where i = 2 compute min(i) */
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+-	Command("select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	odbc_command("select * from #tmp1 where i = 2 or i = 34 order by c, i compute min(i) by c");
+ 	CheckFetch("c", "pippo", "34");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+@@ -168,8 +168,8 @@ main(int argc, char *argv[])
+ 	/* here just skip results, before a row */
+ 	CHKMoreResults("S");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, col1, sizeof(col1), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, col2, sizeof(col2), &ind2);
+ 	CheckFetch("c", "pluto", "2");
+ 	CHKFetch("No");
+ 	CHKMoreResults("S");
+@@ -178,6 +178,6 @@ main(int argc, char *argv[])
+ 	CHKMoreResults("No");
+ 
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c
+index 119ac37..99090fa 100644
+--- a/src/odbc/unittests/connect.c
++++ b/src/odbc/unittests/connect.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: connect.c,v 1.12 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: connect.c,v 1.13 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,8 +9,8 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKAllocEnv(&Environment, "S");
+-	CHKAllocConnect(&Connection, "S");
++	CHKAllocEnv(&odbc_env, "S");
++	CHKAllocConnect(&odbc_conn, "S");
+ }
+ 
+ int
+@@ -22,7 +22,7 @@ main(int argc, char *argv[])
+ 	int is_freetds = 1;
+ 	SQLRETURN rc;
+ 
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+ 	/*
+@@ -30,11 +30,11 @@ main(int argc, char *argv[])
+ 	 * is better to do it before connect cause uniODBC cache INIs
+ 	 * the name must be odbcinst.ini cause unixODBC accept only this name
+ 	 */
+-	if (DRIVER[0]) {
++	if (odbc_driver[0]) {
+ 		FILE *f = fopen("odbcinst.ini", "w");
+ 
+ 		if (f) {
+-			fprintf(f, "[FreeTDS]\nDriver = %s\n", DRIVER);
++			fprintf(f, "[FreeTDS]\nDriver = %s\n", odbc_driver);
+ 			fclose(f);
+ 			/* force iODBC */
+ 			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
+@@ -45,10 +45,10 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	printf("SQLConnect connect..\n");
+-	Connect();
+-	if (!driver_is_freetds())
++	odbc_connect();
++	if (!odbc_driver_is_freetds())
+ 		is_freetds = 0;
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	if (!is_freetds) {
+ 		printf("Driver is not FreeTDS, exiting\n");
+@@ -58,9 +58,9 @@ main(int argc, char *argv[])
+ 	/* try connect string with using DSN */
+ 	printf("connect string DSN connect..\n");
+ 	init_connect();
+-	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
+ 	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	/* try connect string using old SERVERNAME specification */
+ 	printf("connect string SERVERNAME connect..\n");
+@@ -68,23 +68,23 @@ main(int argc, char *argv[])
+ 
+ 	/* this is expected to work with unixODBC */
+ 	init_connect();
+-	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
++	sprintf(tmp, "DRIVER=FreeTDS;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
+ 	rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+ 	if (rc == SQL_ERROR) {
+ 		printf("Unable to open data source (ret=%d)\n", rc);
+ 		++failures;
+ 	}
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	/* this is expected to work with iODBC */
+ 	init_connect();
+-	sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", DRIVER, SERVER, USER, PASSWORD, DATABASE);
++	sprintf(tmp, "DRIVER=%s;SERVERNAME=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_driver, odbc_server, odbc_user, odbc_password, odbc_database);
+ 	rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+ 	if (rc == SQL_ERROR) {
+ 		printf("Unable to open data source (ret=%d)\n", rc);
+ 		++failures;
+ 	}
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	/* at least one should success.. */
+ 	if (failures > 1) {
+diff --git a/src/odbc/unittests/connect2.c b/src/odbc/unittests/connect2.c
+index 9d60b28..5fc0e3e 100644
+--- a/src/odbc/unittests/connect2.c
++++ b/src/odbc/unittests/connect2.c
+@@ -5,7 +5,7 @@
+  * either SQLConnect and SQLDriverConnect
+  */
+ 
+-static char software_version[] = "$Id: connect2.c,v 1.7 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: connect2.c,v 1.8 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int failed = 0;
+@@ -15,14 +15,14 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKAllocEnv(&Environment, "S");
+-	CHKAllocConnect(&Connection, "S");
++	CHKAllocEnv(&odbc_env, "S");
++	CHKAllocConnect(&odbc_conn, "S");
+ }
+ 
+ static void
+ normal_connect(void)
+ {
+-	CHKR(SQLConnect, (Connection, (SQLCHAR *) SERVER, SQL_NTS, (SQLCHAR *) USER, SQL_NTS, (SQLCHAR *) PASSWORD, SQL_NTS), "SI");
++	CHKR(SQLConnect, (odbc_conn, (SQLCHAR *) odbc_server, SQL_NTS, (SQLCHAR *) odbc_user, SQL_NTS, (SQLCHAR *) odbc_password, SQL_NTS), "SI");
+ }
+ 
+ static void
+@@ -60,7 +60,7 @@ main(int argc, char *argv[])
+ {
+ 	char tmp[1024];
+ 
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+ 	/* try setting db name before connect */
+@@ -80,7 +80,7 @@ main(int argc, char *argv[])
+ 	CHKSetConnectAttr(SQL_ATTR_CURRENT_CATALOG, (SQLPOINTER) tmp, strlen(tmp), "E");
+ 	check_dbname("tempdb");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	/* try setting db name before connect */
+ 	printf("SQLConnect before 2..\n");
+@@ -88,25 +88,25 @@ main(int argc, char *argv[])
+ 	set_dbname("tempdb");
+ 	normal_connect();
+ 	check_dbname("tempdb");
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	/* try connect string with using DSN */
+ 	printf("SQLDriverConnect before 1..\n");
+-	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", SERVER, USER, PASSWORD, DATABASE);
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
+ 	init_connect();
+ 	set_dbname("master");
+ 	driver_connect(tmp);
+-	check_dbname(DATABASE);
+-	Disconnect();
++	check_dbname(odbc_database);
++	odbc_disconnect();
+ 
+ 	/* try connect string with using DSN */
+ 	printf("SQLDriverConnect before 2..\n");
+-	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;", SERVER, USER, PASSWORD);
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;", odbc_server, odbc_user, odbc_password);
+ 	init_connect();
+ 	set_dbname("tempdb");
+ 	driver_connect(tmp);
+ 	check_dbname("tempdb");
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	if (failed) {
+ 		printf("Some tests failed\n");
+diff --git a/src/odbc/unittests/const_params.c b/src/odbc/unittests/const_params.c
+index dd956c2..a1592ef 100644
+--- a/src/odbc/unittests/const_params.c
++++ b/src/odbc/unittests/const_params.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?,123,'foo')} syntax and run */
+ 
+-static char software_version[] = "$Id: const_params.c,v 1.17 2009/03/16 12:19:03 freddy77 Exp $";
++static char software_version[] = "$Id: const_params.c,v 1.18 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,12 +12,12 @@ main(int argc, char *argv[])
+ 	SQLINTEGER out1;
+ 	SQLLEN ind, ind2, ind3;
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	if (CommandWithResult(Statement, "drop proc const_param") != SQL_SUCCESS)
++	if (odbc_command_with_result(odbc_stmt, "drop proc const_param") != SQL_SUCCESS)
+ 		printf("Unable to execute statement\n");
+ 
+-	Command("create proc const_param @in1 int, @in2 int, @in3 datetime, @in4 varchar(10), @out int output as\n"
++	odbc_command("create proc const_param @in1 int, @in2 int, @in3 datetime, @in4 varchar(10), @out int output as\n"
+ 		"begin\n"
+ 		" set nocount on\n"
+ 		" select @out = 7654321\n"
+@@ -43,10 +43,10 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* just to reset some possible buffers */
+-	Command("DECLARE @i INT");
++	odbc_command("DECLARE @i INT");
+ 
+ 	/* MS ODBC don't support empty parameters altough documented so avoid this test */
+-	if (driver_is_freetds()) {
++	if (odbc_driver_is_freetds()) {
+ 
+ 		CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind,  "S");
+ 		CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0, 0, &input,  0, &ind2, "S");
+@@ -71,9 +71,9 @@ main(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	Command("IF OBJECT_ID('const_param') IS NOT NULL DROP PROC const_param");
++	odbc_command("IF OBJECT_ID('const_param') IS NOT NULL DROP PROC const_param");
+ 
+-	Command("create proc const_param @in1 float, @in2 varbinary(100) as\n"
++	odbc_command("create proc const_param @in1 float, @in2 varbinary(100) as\n"
+ 		"begin\n"
+ 		" if @in1 <> 12.5 or @in2 <> 0x0102030405060708\n"
+ 		"  return 12345\n"
+@@ -92,9 +92,9 @@ main(int argc, char *argv[])
+ 		return 1;
+ 	}
+ 
+-	Command("drop proc const_param");
++	odbc_command("drop proc const_param");
+ 
+-	Command("create proc const_param @in varchar(20) as\n"
++	odbc_command("create proc const_param @in varchar(20) as\n"
+ 		"begin\n"
+ 		" if @in = 'value' select 8421\n"
+ 		" select 1248\n"
+@@ -102,20 +102,20 @@ main(int argc, char *argv[])
+ 
+ 	/* catch problem reported by Peter Deacon */
+ 	output = 0xdeadbeef;
+-	Command("{CALL const_param('value')}");
++	odbc_command("{CALL const_param('value')}");
+ 	CHKBindCol(1, SQL_C_SLONG, &output, 0, &ind, "S");
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+ 	if (output != 8421) {
+ 		fprintf(stderr, "Invalid result %d (0x%x)\n", (int) output, (int) output);
+ 		return 1;
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+-	Command("drop proc const_param");
++	odbc_command("drop proc const_param");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/convert_error.c b/src/odbc/unittests/convert_error.c
+index 0310c84..79ebbd5 100644
+--- a/src/odbc/unittests/convert_error.c
++++ b/src/odbc/unittests/convert_error.c
+@@ -4,7 +4,7 @@
+  */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: convert_error.c,v 1.10 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: convert_error.c,v 1.11 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int test_num = 0;
+@@ -17,7 +17,7 @@ Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2)
+ 	SQLLEN ind = 4;
+ 	int id = 1;
+ 
+-	SQLFreeStmt(Statement, SQL_RESET_PARAMS);
++	SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS);
+ 
+ 	++test_num;
+ 	sprintf(sql, "insert into #test_output values (%s, %s)", bind1, bind2);
+@@ -34,10 +34,10 @@ Test(const char *bind1, SQLSMALLINT type1, const char *bind2, SQLSMALLINT type2)
+ int
+ main(int argc, char **argv)
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	Command("create table #test_output (id int, msg text)");
++	odbc_command("create table #test_output (id int, msg text)");
+ 
+ 	Test("?", SQL_INTEGER, "?", SQL_LONGVARCHAR);
+ 	Test("123", SQL_INTEGER, "?", SQL_LONGVARCHAR);
+@@ -50,12 +50,12 @@ main(int argc, char **argv)
+ 	 * be emulated loosing column informations from server and Sybase do
+ 	 * not convert implicitly VARCHAR to INT
+ 	 */
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		Test("?", SQL_VARCHAR, "?", SQL_LONGVARCHAR);
+ 	else
+ 		++test_num;
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/copydesc.c b/src/odbc/unittests/copydesc.c
+index 5771490..25d8451 100644
+--- a/src/odbc/unittests/copydesc.c
++++ b/src/odbc/unittests/copydesc.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLCopyDesc and SQLAllocHandle(SQL_HANDLE_DESC) */
+ 
+-static char software_version[] = "$Id: copydesc.c,v 1.6 2010/01/22 10:45:19 freddy77 Exp $";
++static char software_version[] = "$Id: copydesc.c,v 1.7 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -13,26 +13,26 @@ main(int argc, char *argv[])
+ 	SQLLEN ind1, ind2;
+ 	char name[64];
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	CHKGetStmtAttr(SQL_ATTR_APP_ROW_DESC, &ard, 0, NULL, "S");
+ 
+ 	CHKBindCol(1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1, "S");
+ 	CHKBindCol(2, SQL_C_CHAR, name, sizeof(name), &ind2, "S");
+ 
+-	CHKAllocHandle(SQL_HANDLE_DESC, Connection, &ard2, "S");
++	CHKAllocHandle(SQL_HANDLE_DESC, odbc_conn, &ard2, "S");
+ 
+ 	/*
+ 	 * this is an additional test to test additional allocation 
+ 	 * As of 0.64 for a bug in SQLAllocDesc we only allow to allocate one
+ 	 */
+-	CHKAllocHandle(SQL_HANDLE_DESC, Connection, &ard3, "S");
++	CHKAllocHandle(SQL_HANDLE_DESC, odbc_conn, &ard3, "S");
+ 
+ 	CHKR(SQLCopyDesc, (ard, ard2), "S");
+ 
+ 	CHKFreeHandle(SQL_HANDLE_DESC, ard3, "S");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/cursor1.c b/src/odbc/unittests/cursor1.c
+index 63eddc7..79d0ffe 100644
+--- a/src/odbc/unittests/cursor1.c
++++ b/src/odbc/unittests/cursor1.c
+@@ -2,10 +2,10 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: cursor1.c,v 1.19 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: cursor1.c,v 1.20 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
++#define SWAP_STMT(b) do { SQLHSTMT xyz = odbc_stmt; odbc_stmt = b; b = xyz; } while(0)
+ 
+ static int mssql2005 = 0;
+ 
+@@ -24,7 +24,7 @@ CheckNoRow(const char *query)
+ 		CHKNumResultCols(&cols, "S");
+ 		if (cols != 0) {
+ 			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(1);
+ 		}
+ 	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
+@@ -46,18 +46,18 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 	SQLHSTMT stmt2;
+ 
+ 	/* create test table */
+-	Command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+-	Command(create_sql);
++	odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
++	odbc_command(create_sql);
+ 	for (i = 1; i <= 6; ++i) {
+ 		char sql_buf[80], data[10];
+ 		memset(data, 'a' + (i - 1), sizeof(data));
+ 		data[i] = 0;
+ 		sprintf(sql_buf, insert_sql, data, i);
+-		Command(sql_buf);
++		odbc_command(sql_buf);
+ 	}
+ 
+ 	/* set cursor options */
+-	ResetStatement();
++	odbc_reset_statement();
+ 	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+ 	CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (SQLPOINTER) ROWS, 0, "S");
+@@ -110,7 +110,7 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 				n[i - 1] = 321;
+ 				CHKSetPos(i, use_sql ? SQL_POSITION : SQL_UPDATE, SQL_LOCK_NO_CHANGE, "E");
+ 
+-				CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "S");
++				CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "S");
+ 				if (strstr((char *) msg, "Invalid column name 'c'") == NULL) {
+ 					fprintf(stderr, "Expected message not found at line %d\n", __LINE__);
+ 					exit(1);
+@@ -122,7 +122,7 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 				CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_CHAR, C_LEN, 0, c[i - 1], 0, NULL, "S");
+ 				CHKExecute("S");
+ 				/* FIXME this is not necessary for mssql driver */
+-				SQLMoreResults(Statement);
++				SQLMoreResults(odbc_stmt);
+ 				SWAP_STMT(stmt2);
+ 			}
+ 		}
+@@ -132,7 +132,7 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ 	CHKFreeStmt(SQL_DROP, "S");
+ 	SWAP_STMT(stmt2);
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* test values */
+ 	CheckNoRow("IF (SELECT COUNT(*) FROM #test) <> 4 SELECT 1");
+@@ -147,13 +147,13 @@ Test0(int use_sql, const char *create_sql, const char *insert_sql, const char *s
+ static void
+ Test(int use_sql)
+ {
+-	CommandWithResult(Statement, "DROP TABLE #a");
+-	Command("CREATE TABLE #a(x int)");
+-	Command("INSERT INTO #a VALUES(123)");
++	odbc_command_with_result(odbc_stmt, "DROP TABLE #a");
++	odbc_command("CREATE TABLE #a(x int)");
++	odbc_command("INSERT INTO #a VALUES(123)");
+ 	Test0(use_sql, "CREATE TABLE #test(i int, c varchar(6))", "INSERT INTO #test(c, i) VALUES('%s', %d)", "SELECT x AS i, c FROM #test, #a");
+ 
+ 	Test0(use_sql, "CREATE TABLE #test(i int, c varchar(6))", "INSERT INTO #test(c, i) VALUES('%s', %d)", "SELECT i, c FROM #test");
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 		Test0(use_sql, "CREATE TABLE #test(i int identity(1,1), c varchar(6))", "INSERT INTO #test(c) VALUES('%s')", "SELECT i, c FROM #test");
+ 		Test0(use_sql, "CREATE TABLE #test(i int primary key, c varchar(6))", "INSERT INTO #test(c, i) VALUES('%s', %d)", "SELECT i, c FROM #test");
+ 	}
+@@ -163,16 +163,16 @@ Test(int use_sql)
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
+-	CheckCursor();
++	odbc_connect();
++	odbc_check_cursor();
+ 
+-	if (db_is_microsoft() && db_version_int() >= 0x09000000u)
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u)
+ 		mssql2005 = 1;
+ 
+ 	Test(1);
+ 
+ 	Test(0);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index 039b21f..141f352 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -5,7 +5,7 @@
+  * 2) Test cursor returns results on language RPCs
+  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.9 2010/06/26 08:03:57 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.10 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -14,36 +14,36 @@ main(int argc, char *argv[])
+ 	unsigned char sqlstate[6];
+ 	unsigned char msg[256];
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #cursor2_test (i INT)");
++	odbc_command("CREATE TABLE #cursor2_test (i INT)");
+ 
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER, "S");
+ 
+ 	/* this should not fail or return warnings */
+-	Command("DROP TABLE #cursor2_test");
++	odbc_command("DROP TABLE #cursor2_test");
+ 
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "No");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, msg, sizeof(msg), NULL, "No");
+ 
+ 
+-	ResetStatement();
+-	CommandWithResult(Statement, "drop proc sp_test");
+-	Command("create proc sp_test @name varchar(30) as select 0 as pippo select 1 as 'test', @name as 'nome'");
++	odbc_reset_statement();
++	odbc_command_with_result(odbc_stmt, "drop proc sp_test");
++	odbc_command("create proc sp_test @name varchar(30) as select 0 as pippo select 1 as 'test', @name as 'nome'");
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, SQL_IS_INTEGER, "S");
+ 
+-	Command(" exec sp_test 'ciao'");
++	odbc_command(" exec sp_test 'ciao'");
+ 
+ 	CHKFetch("S");
+ 
+-	ResetStatement();
+-	Command("drop proc sp_test");
++	odbc_reset_statement();
++	odbc_command("drop proc sp_test");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/cursor3.c b/src/odbc/unittests/cursor3.c
+index f55ae7d..afc0251 100644
+--- a/src/odbc/unittests/cursor3.c
++++ b/src/odbc/unittests/cursor3.c
+@@ -1,7 +1,7 @@
+ /* Tests 2 active statements */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor3.c,v 1.9 2008/11/04 15:24:49 freddy77 Exp $";
++static char software_version[] = "$Id: cursor3.c,v 1.10 2010/07/05 09:20:32 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -9,63 +9,63 @@ main(int argc, char **argv)
+ {
+ 	SQLHSTMT stmt1 = SQL_NULL_HSTMT;
+ 	SQLHSTMT stmt2 = SQL_NULL_HSTMT;
+-	SQLHSTMT old_Statement;
++	SQLHSTMT old_odbc_stmt;
+ 	char buff[64];
+ 	SQLLEN ind;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+-	Command("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+-	Command("INSERT INTO #t1 VALUES (1, 'aaa')");
+-	Command("INSERT INTO #t1 VALUES (2, 'bbbbb')");
+-	Command("INSERT INTO #t1 VALUES (3, 'ccccccccc')");
+-	Command("INSERT INTO #t1 VALUES (4, 'dd')");
++	odbc_command("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
++	odbc_command("INSERT INTO #t1 VALUES (1, 'aaa')");
++	odbc_command("INSERT INTO #t1 VALUES (2, 'bbbbb')");
++	odbc_command("INSERT INTO #t1 VALUES (3, 'ccccccccc')");
++	odbc_command("INSERT INTO #t1 VALUES (4, 'dd')");
+ 
+-	old_Statement = Statement;
++	old_odbc_stmt = odbc_stmt;
+ 
+-	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &stmt1, "S");
+-	CHKAllocHandle(SQL_HANDLE_STMT, Connection, &stmt2, "S");
++	CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &stmt1, "S");
++	CHKAllocHandle(SQL_HANDLE_STMT, odbc_conn, &stmt2, "S");
+ 
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ /*	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); */
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+ /*	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S"); */
+ 
+ 
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ /*	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S"); */
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+ /*	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S"); */
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKSetCursorName((SQLCHAR *) "c1", SQL_NTS, "S");
+ 
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKSetCursorName((SQLCHAR *) "c2", SQL_NTS, "S");
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1 ORDER BY k", SQL_NTS, "S");
+ 
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKPrepare((SQLCHAR *) "SELECT * FROM #t1 ORDER BY k DESC", SQL_NTS, "S");
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKExecute("S");
+ 
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKExecute("S");
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKFetch("S");
+ 
+ 	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+ 	printf(">> Fetch from 1: [%s]\n", buff);
+ 
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKFetch("S");
+ 
+ 	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+@@ -76,31 +76,31 @@ main(int argc, char **argv)
+ 	 * fetch a data on stmt2 than fetch on stmt1 and try to get data on first one
+ 	 */
+ 	CHKFetch("S");	/* "ccccccccc" */
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKFetch("S");  /* "bbbbb" */
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+ 	printf(">> Fetch from 2: [%s]\n", buff);
+ 	if (strcmp(buff, "ccccccccc") != 0)
+ 		ODBC_REPORT_ERROR("Invalid results from SQLGetData");
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKGetData(2, SQL_C_CHAR, (SQLPOINTER) buff, sizeof(buff), &ind, "S");
+ 	printf(">> Fetch from 1: [%s]\n", buff);
+ 	if (strcmp(buff, "bbbbb") != 0)
+ 		ODBC_REPORT_ERROR("Invalid results from SQLGetData");
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKCloseCursor("SI");
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKCloseCursor("SI");
+ 
+-	Statement = stmt1;
++	odbc_stmt = stmt1;
+ 	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) stmt1, "S");
+-	Statement = stmt2;
++	odbc_stmt = stmt2;
+ 	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) stmt2, "S");
+ 
+-	Statement = old_Statement;
+-	Disconnect();
++	odbc_stmt = old_odbc_stmt;
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/cursor4.c b/src/odbc/unittests/cursor4.c
+index 8a34220..839d9b5 100755
+--- a/src/odbc/unittests/cursor4.c
++++ b/src/odbc/unittests/cursor4.c
+@@ -5,17 +5,17 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor4.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor4.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ exec_direct(const char *stmt)
+ {
+-	SQLHSTMT Statement = SQL_NULL_HSTMT;
++	SQLHSTMT odbc_stmt = SQL_NULL_HSTMT;
+ 
+-	CHKAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) Connection, (SQLHANDLE *) & Statement, "S");
+-	Command(stmt);
+-	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
++	CHKAllocHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_conn, (SQLHANDLE *) & odbc_stmt, "S");
++	odbc_command(stmt);
++	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
+ }
+ 
+ int
+@@ -24,15 +24,15 @@ main(int argc, char **argv)
+ 	char buff[64];
+ 	SQLLEN ind;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+ 	exec_direct("CREATE TABLE #t1 ( k INT, c VARCHAR(20))");
+ 	exec_direct("INSERT INTO #t1 VALUES (1, 'aaa')");
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_LOCK, SQL_IS_UINTEGER, "S");
+ 
+@@ -60,10 +60,10 @@ main(int argc, char **argv)
+ 
+ 	printf(">> New value after update = [%s] (should be [xxx]) \n", buff);
+ 
+-	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) Statement, "S");
+-	Statement = SQL_NULL_HSTMT;
++	CHKFreeHandle(SQL_HANDLE_STMT, (SQLHANDLE) odbc_stmt, "S");
++	odbc_stmt = SQL_NULL_HSTMT;
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/cursor5.c b/src/odbc/unittests/cursor5.c
+index 2fc451e..4912264 100755
+--- a/src/odbc/unittests/cursor5.c
++++ b/src/odbc/unittests/cursor5.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: cursor5.c,v 1.9 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: cursor5.c,v 1.10 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLINTEGER v_int_3;
+@@ -25,18 +25,18 @@ doFetch(int dir, int pos)
+ int
+ main(int argc, char **argv)
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
+-	CheckCursor();
++	odbc_use_version3 = 1;
++	odbc_connect();
++	odbc_check_cursor();
+ 
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (SQLPOINTER) SQL_AUTOCOMMIT_ON, SQL_IS_UINTEGER, "S");
+ 
+-	Command("create table #mytab1 (k int, c char(30))");
+-	Command("insert into #mytab1 values (1,'aaa')");
+-	Command("insert into #mytab1 values (2,'bbb')");
+-	Command("insert into #mytab1 values (3,'ccc')");
++	odbc_command("create table #mytab1 (k int, c char(30))");
++	odbc_command("insert into #mytab1 values (1,'aaa')");
++	odbc_command("insert into #mytab1 values (2,'bbb')");
++	odbc_command("insert into #mytab1 values (3,'ccc')");
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ /*	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_STATIC, 0, "S");	*/
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, SQL_IS_UINTEGER, "S");
+ 
+@@ -65,6 +65,6 @@ main(int argc, char **argv)
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/cursor6.c b/src/odbc/unittests/cursor6.c
+index 6a05f29..fba0a4f 100755
+--- a/src/odbc/unittests/cursor6.c
++++ b/src/odbc/unittests/cursor6.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with no binded columns */
+ 
+-static char software_version[] = "$Id: cursor6.c,v 1.5 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: cursor6.c,v 1.6 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int bind_all = 0;
+@@ -21,7 +21,7 @@ static void Test(void)
+ 	SQLUSMALLINT statuses[ROWS];
+ 	SQLULEN num_row;
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* this should not fail or return warnings */
+ 	if (use_cursors) {
+@@ -52,9 +52,9 @@ static void Test(void)
+ 
+ 	/* now check row numbers */
+ 	printf("num_row %d statuses[0] %d statuses[1] %d odbc3 %d\n", (int) num_row,
+-		(int) statuses[0], (int) statuses[1], use_odbc_version3);
++		(int) statuses[0], (int) statuses[1], odbc_use_version3);
+ 
+-	if (use_odbc_version3 || !normal_fetch) {
++	if (odbc_use_version3 || !normal_fetch) {
+ 		if (num_row != ROWS || statuses[0] != SQL_ROW_SUCCESS || statuses[1] != SQL_ROW_SUCCESS) {
+ 			fprintf(stderr, "result error 1\n");
+ 			exit(1);
+@@ -79,10 +79,10 @@ static void Init(void)
+ 	int i;
+ 	char sql[128];
+ 
+-	Command("CREATE TABLE #cursor6_test (i INT, c VARCHAR(20))");
++	odbc_command("CREATE TABLE #cursor6_test (i INT, c VARCHAR(20))");
+ 	for (i = 1; i <= 10; ++i) {
+ 		sprintf(sql, "INSERT INTO #cursor6_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
+-		Command(sql);
++		odbc_command(sql);
+ 	}
+ 
+ }
+@@ -90,10 +90,10 @@ static void Init(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+ 	Init();
+ 
+@@ -103,11 +103,11 @@ main(int argc, char *argv[])
+ 			ALL(normal_fetch)
+ 				Test();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+-	use_odbc_version3 = 0;
++	odbc_use_version3 = 0;
+ 
+-	Connect();
++	odbc_connect();
+ 	Init();
+ 
+ 	ALL(use_cursors)
+@@ -115,7 +115,7 @@ main(int argc, char *argv[])
+ 			ALL(normal_fetch)
+ 				Test();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/cursor7.c b/src/odbc/unittests/cursor7.c
+index 2be1706..e6a3e23 100644
+--- a/src/odbc/unittests/cursor7.c
++++ b/src/odbc/unittests/cursor7.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test SQLFetchScroll with a non-unitary rowset, using bottom-up direction */
+ 
+-static char software_version[] = "$Id: cursor7.c,v 1.8 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: cursor7.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -21,7 +21,7 @@ Test(void)
+ 	int i;
+ 	SQLRETURN RetCode;
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, int2ptr(SQL_CONCUR_READ_ONLY), 0, "S");
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, int2ptr(SQL_CURSOR_STATIC), 0, "S");
+@@ -71,10 +71,10 @@ Init(void)
+ 
+ 	printf("\n\nCreating table #cursor7_test with 12 records.\n");
+ 
+-	Command("\tCREATE TABLE #cursor7_test (i INT, c VARCHAR(20))");
++	odbc_command("\tCREATE TABLE #cursor7_test (i INT, c VARCHAR(20))");
+ 	for (i = 1; i <= 12; ++i) {
+ 		sprintf(sql, "\tINSERT INTO #cursor7_test(i,c) VALUES(%d, 'a%db%dc%d')", i, i, i, i);
+-		Command(sql);
++		odbc_command(sql);
+ 	}
+ 
+ }
+@@ -82,16 +82,16 @@ Init(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+ 	Init();
+ 
+ 	Test();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/data.c b/src/odbc/unittests/data.c
+index 275e722..8938928 100644
+--- a/src/odbc/unittests/data.c
++++ b/src/odbc/unittests/data.c
+@@ -13,7 +13,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: data.c,v 1.32 2009/11/29 20:06:28 freddy77 Exp $";
++static char software_version[] = "$Id: data.c,v 1.33 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int result = 0;
+@@ -30,8 +30,8 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 	SQLWCHAR *wp;
+ 	int i;
+ 
+-	SQLFreeStmt(Statement, SQL_UNBIND);
+-	SQLFreeStmt(Statement, SQL_RESET_PARAMS);
++	SQLFreeStmt(odbc_stmt, SQL_UNBIND);
++	SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS);
+ 
+ 	/* execute a select to get data as wire */
+ 	sprintf(sbuf, "SELECT CONVERT(%s, '%s') AS data", type, value_to_convert);
+@@ -42,15 +42,15 @@ Test(const char *type, const char *value_to_convert, SQLSMALLINT out_c_type, con
+ 	else if (strncmp(value_to_convert, "u&'", 3) == 0)
+ 		sprintf(sbuf, "SELECT CONVERT(%s, %s) AS data", type, value_to_convert);
+ 	if (ignore_select_error) {
+-		if (Command2(sbuf, "SENo") == SQL_ERROR) {
+-			ResetStatement();
++		if (odbc_command2(sbuf, "SENo") == SQL_ERROR) {
++			odbc_reset_statement();
+ 			return;
+ 		}
+ 	} else {
+-		Command(sbuf);
++		odbc_command(sbuf);
+ 	}
+ 	ignore_select_error = 0;
+-	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
++	SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+ 	CHKMoreResults("No");
+@@ -106,7 +106,7 @@ main(int argc, char *argv[])
+ {
+ 	int big_endian = 1;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	if (((char *) &big_endian)[0] == 1)
+ 		big_endian = 0;
+@@ -123,7 +123,7 @@ main(int argc, char *argv[])
+ 	Test("IMAGE", "cricetone", SQL_C_BINARY, "6372696365746F6E65");
+ 	Test("VARBINARY(20)", "teo", SQL_C_BINARY, "74656F");
+ 	/* TODO only MS ?? */
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		Test("TIMESTAMP", "abcdefghi", SQL_C_BINARY, "6162636465666768");
+ 
+ 	Test("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
+@@ -134,8 +134,8 @@ main(int argc, char *argv[])
+ 	Test("TINYINT", "231", SQL_C_BINARY, "E7");
+ 	Test("SMALLINT", "4321", SQL_C_BINARY, big_endian ? "10E1" : "E110");
+ 	Test("INT", "1234567", SQL_C_BINARY, big_endian ? "0012D687" : "87D61200");
+-	if ((db_is_microsoft() && db_version_int() >= 0x08000000u)
+-	    || (!db_is_microsoft() && strncmp(db_version(), "15.00.", 6) >= 0)) {
++	if ((odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u)
++	    || (!odbc_db_is_microsoft() && strncmp(odbc_db_version(), "15.00.", 6) >= 0)) {
+ 		int old_result = result;
+ 
+ 		Test("BIGINT", "123456789012345", SQL_C_BINARY, big_endian ? "00007048860DDF79" : "79DF0D8648700000");
+@@ -149,12 +149,12 @@ main(int argc, char *argv[])
+ 	Test("INT", "-123", SQL_C_CHAR, "4 -123");
+ 	Test("INT", "78654", SQL_C_WCHAR, "5 78654");
+ 	Test("VARCHAR(10)", "  51245  ", SQL_C_LONG, "51245");
+-	if (db_is_microsoft() && (strncmp(db_version(), "08.00.", 6) == 0 || strncmp(db_version(), "09.00.", 6) == 0)) {
++	if (odbc_db_is_microsoft() && (strncmp(odbc_db_version(), "08.00.", 6) == 0 || strncmp(odbc_db_version(), "09.00.", 6) == 0)) {
+ 		/* nvarchar without extended characters */
+ 		Test("NVARCHAR(20)", "test", SQL_C_CHAR, "4 test");
+ 		/* nvarchar with extended characters */
+ 		/* don't test with MS which usually have a not compatible encoding */
+-		if (driver_is_freetds())
++		if (odbc_driver_is_freetds())
+ 			Test("NVARCHAR(20)", "0x830068006900f200", SQL_C_CHAR, "4 \x83hi\xf2");
+ 
+ 		Test("VARCHAR(20)", "test", SQL_C_WCHAR, "4 test");
+@@ -179,13 +179,13 @@ main(int argc, char *argv[])
+ 	Test("MONEY", "4321234.5678", SQL_C_BINARY, big_endian ? "0000000A0FA8114E" : "0A0000004E11A80F");
+ 
+ 	/* behavior is different from MS ODBC */
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 		Test("NCHAR(7)", "donald", SQL_C_BINARY, "64006F006E0061006C0064002000");
+ 		Test("NTEXT", "duck", SQL_C_BINARY, "6400750063006B00");
+ 		Test("NVARCHAR(20)", "daffy", SQL_C_BINARY, "64006100660066007900");
+ 	}
+ 
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		Test("UNIQUEIDENTIFIER", "0DDF3B64-E692-11D1-AB06-00AA00BDD685", SQL_C_BINARY,
+ 		     big_endian ? "0DDF3B64E69211D1AB0600AA00BDD685" : "643BDF0D92E6D111AB0600AA00BDD685");
+ 
+@@ -195,7 +195,7 @@ main(int argc, char *argv[])
+ 	Test("DATETIME", "2006-06-09 11:22:44", SQL_C_WCHAR, "23 2006-06-09 11:22:44.000");
+ 	Test("SMALLDATETIME", "2006-06-12 22:37:21", SQL_C_WCHAR, "19 2006-06-12 22:37:00");
+ 
+-	if (db_is_microsoft() && db_version_int() >= 0x08000000u) {
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
+ 		Test("SQL_VARIANT", "CAST('123' AS INT)", SQL_C_CHAR, "3 123");
+ 		Test("SQL_VARIANT", "CAST('hello' AS CHAR(6))", SQL_C_CHAR, "6 hello ");
+ 		Test("SQL_VARIANT", "CAST('ciao' AS VARCHAR(10))", SQL_C_CHAR, "4 ciao");
+@@ -207,14 +207,14 @@ main(int argc, char *argv[])
+ 		Test("SQL_VARIANT", "CAST('-123.4' AS NUMERIC(10,2))", SQL_C_CHAR, "7 -123.40");
+ 	}
+ 
+-	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u) {
+ 		Test("VARCHAR(MAX)", "goodbye!", SQL_C_CHAR, "8 goodbye!");
+ 		Test("NVARCHAR(MAX)", "Micio mao", SQL_C_CHAR, "9 Micio mao");
+ 		Test("VARBINARY(MAX)", "ciao", SQL_C_BINARY, "6369616F");
+ 		Test("XML", "<a b=\"aaa\"><b>ciao</b>hi</a>", SQL_C_CHAR, "28 <a b=\"aaa\"><b>ciao</b>hi</a>");
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	if (!result)
+ 		printf("Done successfully!\n");
+diff --git a/src/odbc/unittests/date.c b/src/odbc/unittests/date.c
+index 3941e9e..ff240dc 100644
+--- a/src/odbc/unittests/date.c
++++ b/src/odbc/unittests/date.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: date.c,v 1.12 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: date.c,v 1.13 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -16,7 +16,7 @@ DoTest(int n)
+ 
+ 	TIMESTAMP_STRUCT ts;
+ 
+-	Command("select convert(datetime, '2002-12-27 18:43:21')");
++	odbc_command("select convert(datetime, '2002-12-27 18:43:21')");
+ 
+ 	CHKFetch("SI");
+ 	CHKDescribeCol(1, output, sizeof(output), NULL, &colType, &colSize, &colScale, &colNullable, "S");
+@@ -42,12 +42,12 @@ DoTest(int n)
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+ 	DoTest(0);
+ 	DoTest(1);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/descrec.c b/src/odbc/unittests/descrec.c
+index ed7a1b7..31d2cfc 100644
+--- a/src/odbc/unittests/descrec.c
++++ b/src/odbc/unittests/descrec.c
+@@ -1,7 +1,7 @@
+ /* test SQLGetDescRec */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: descrec.c,v 1.1 2010/03/02 15:41:37 freddy77 Exp $";
++static char software_version[] = "$Id: descrec.c,v 1.2 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,10 +12,10 @@ main(void)
+ 	SQLCHAR name[128];
+ 	SQLSMALLINT si;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	Command("create table #tmp1 (i int)");
++	odbc_command("create table #tmp1 (i int)");
+ 
+ 	/* get IRD */
+ 	CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &Descriptor, sizeof(Descriptor), &ind, "S");
+@@ -26,12 +26,12 @@ main(void)
+ 	CHKGetDescRec(1, name, sizeof(name), &si, NULL /*Type*/, NULL /*SubType*/, NULL /*Length*/, NULL/*Precision*/,
+ 		      NULL /*Scale*/, NULL /*Nullable*/, "No");
+ 
+-	Command("SELECT name FROM sysobjects");
++	odbc_command("SELECT name FROM sysobjects");
+ 
+ 	CHKGetDescRec(1, name, sizeof(name), &si, NULL /*Type*/, NULL /*SubType*/, NULL /*Length*/, NULL/*Precision*/,
+ 		      NULL /*Scale*/, NULL /*Nullable*/, "S");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+ 
+diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c
+index 0fad864..502de42 100644
+--- a/src/odbc/unittests/describecol.c
++++ b/src/odbc/unittests/describecol.c
+@@ -6,7 +6,7 @@
+  * test what say SQLDescribeCol about precision using some type
+  */
+ 
+-static char software_version[] = "$Id: describecol.c,v 1.17 2010/02/12 09:04:58 freddy77 Exp $";
++static char software_version[] = "$Id: describecol.c,v 1.18 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -149,7 +149,7 @@ get_attr_ird(ATTR_PARAMS)
+ 	if (attr->type == type_CHARP)
+ 		fatal("Line %u: CHAR* check still not supported\n", line_num);
+ 	i = 0xdeadbeef;
+-	ret = SQLColAttribute(Statement, 1, attr->value, NULL, SQL_IS_INTEGER, NULL, &i);
++	ret = SQLColAttribute(odbc_stmt, 1, attr->value, NULL, SQL_IS_INTEGER, NULL, &i);
+ 	if (!SQL_SUCCEEDED(ret))
+ 		fatal("Line %u: failure not expected\n", line_num);
+ 	/* SQL_DESC_LENGTH is the same of SQLDescribeCol len */
+@@ -173,7 +173,7 @@ get_attr_ard(ATTR_PARAMS)
+ 	SQLHDESC desc = SQL_NULL_HDESC;
+ 
+ 	/* get ARD */
+-	SQLGetStmtAttr(Statement, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &ind);
++	SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &ind);
+ 
+ 	ret = SQL_ERROR;
+ 	switch (attr->type) {
+@@ -218,10 +218,10 @@ main(int argc, char *argv[])
+ 	SQLLEN len;
+ 	get_attr_t get_attr_p = get_attr_none;
+ 
+-	Connect();
+-	Command("SET TEXTSIZE 4096");
++	odbc_connect();
++	odbc_command("SET TEXTSIZE 4096");
+ 
+-	SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
++	SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 
+ 	f = fopen(in_file, "r");
+ 	if (!f)
+@@ -248,12 +248,12 @@ main(int argc, char *argv[])
+ 		if (strcmp(cmd, "odbc") == 0) {
+ 			int odbc3 = get_int(strtok(NULL, SEP)) == 3 ? 1 : 0;
+ 
+-			if (use_odbc_version3 != odbc3) {
+-				use_odbc_version3 = odbc3;
+-				Disconnect();
+-				Connect();
+-				Command("SET TEXTSIZE 4096");
+-				SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
++			if (odbc_use_version3 != odbc3) {
++				odbc_use_version3 = odbc3;
++				odbc_disconnect();
++				odbc_connect();
++				odbc_command("SET TEXTSIZE 4096");
++				SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 			}
+ 		}
+ 
+@@ -263,21 +263,21 @@ main(int argc, char *argv[])
+ 			const char *value = strtok(NULL, SEP);
+ 			char sql[sizeof(buf) + 40];
+ 
+-			SQLMoreResults(Statement);
+-			ResetStatement();
++			SQLMoreResults(odbc_stmt);
++			odbc_reset_statement();
+ 
+ 			sprintf(sql, "SELECT CONVERT(%s, %s) AS col", type, value);
+ 
+ 			/* ignore error, we only need precision of known types */
+ 			get_attr_p = get_attr_none;
+-			if (CommandWithResult(Statement, sql) != SQL_SUCCESS) {
+-				ResetStatement();
+-				SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
++			if (odbc_command_with_result(odbc_stmt, sql) != SQL_SUCCESS) {
++				odbc_reset_statement();
++				SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 				continue;
+ 			}
+ 
+ 			CHKFetch("SI");
+-			SQLBindCol(Statement, 1, SQL_C_SLONG, &i, sizeof(i), &len);
++			SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+ 			get_attr_p = get_attr_ird;
+ 		}
+ 
+@@ -293,7 +293,7 @@ main(int argc, char *argv[])
+ 				fatal("Line %u: value not defined\n", line_num);
+ 
+ 			/* get ARD */
+-			SQLGetStmtAttr(Statement, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &ind);
++			SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &ind);
+ 
+ 			ret = SQL_ERROR;
+ 			switch (attr->type) {
+@@ -336,7 +336,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	fclose(f);
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return g_result;
+diff --git a/src/odbc/unittests/earlybind.c b/src/odbc/unittests/earlybind.c
+index e931d29..2d76bf0 100644
+--- a/src/odbc/unittests/earlybind.c
++++ b/src/odbc/unittests/earlybind.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: earlybind.c,v 1.4 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: earlybind.c,v 1.5 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -10,22 +10,22 @@ main(int argc, char *argv[])
+ 	SQLLEN ind1, ind2;
+ 	char name[64];
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #test(id INT, name VARCHAR(100))");
+-	Command("INSERT INTO #test(id, name) VALUES(8, 'sysobjects')");
++	odbc_command("CREATE TABLE #test(id INT, name VARCHAR(100))");
++	odbc_command("INSERT INTO #test(id, name) VALUES(8, 'sysobjects')");
+ 
+ 	/* bind before select */
+-	SQLBindCol(Statement, 1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1);
+-	SQLBindCol(Statement, 2, SQL_C_CHAR, name, sizeof(name), &ind2);
++	SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &id, sizeof(SQLINTEGER), &ind1);
++	SQLBindCol(odbc_stmt, 2, SQL_C_CHAR, name, sizeof(name), &ind2);
+ 
+ 	/* do select */
+-	Command("SELECT id, name FROM #test WHERE name = 'sysobjects' SELECT 123, 'foo'");
++	odbc_command("SELECT id, name FROM #test WHERE name = 'sysobjects' SELECT 123, 'foo'");
+ 
+ 	/* get results */
+ 	id = -1;
+ 	memset(name, 0, sizeof(name));
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+ 	if (id == -1 || strcmp(name, "sysobjects") != 0) {
+ 		fprintf(stderr, "wrong results\n");
+@@ -33,13 +33,13 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* discard others data */
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 
+ 	id = -1;
+ 	memset(name, 0, sizeof(name));
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+ 	if (id != 123 || strcmp(name, "foo") != 0) {
+ 		fprintf(stderr, "wrong results\n");
+@@ -47,17 +47,17 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* discard others data */
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 
+ 	/* other select */
+-	Command("SELECT 321, 'minni'");
++	odbc_command("SELECT 321, 'minni'");
+ 
+ 	/* get results */
+ 	id = -1;
+ 	memset(name, 0, sizeof(name));
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+ 	if (id != 321 || strcmp(name, "minni") != 0) {
+ 		fprintf(stderr, "wrong results\n");
+@@ -65,11 +65,11 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* discard others data */
+-	SQLFetch(Statement);
++	SQLFetch(odbc_stmt);
+ 
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/error.c b/src/odbc/unittests/error.c
+index 5a8785d..8e81599 100644
+--- a/src/odbc/unittests/error.c
++++ b/src/odbc/unittests/error.c
+@@ -2,7 +2,7 @@
+ 
+ /* some tests on error reporting */
+ 
+-static char software_version[] = "$Id: error.c,v 1.10 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: error.c,v 1.11 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -11,18 +11,18 @@ main(int argc, char *argv[])
+ 	SQLRETURN RetCode;
+ 	HSTMT stmt, tmp_stmt;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* create a test table */
+-	Command("create table #tmp (i int)");
+-	Command("insert into #tmp values(3)");
+-	Command("insert into #tmp values(4)");
+-	Command("insert into #tmp values(5)");
+-	Command("insert into #tmp values(6)");
+-	Command("insert into #tmp values(7)");
++	odbc_command("create table #tmp (i int)");
++	odbc_command("insert into #tmp values(3)");
++	odbc_command("insert into #tmp values(4)");
++	odbc_command("insert into #tmp values(5)");
++	odbc_command("insert into #tmp values(6)");
++	odbc_command("insert into #tmp values(7)");
+ 
+ 	/* issue our command */
+-	RetCode = Command2("select 100 / (i - 5) from #tmp order by i", "SE");
++	RetCode = odbc_command2("select 100 / (i - 5) from #tmp order by i", "SE");
+ 
+ 	/* special case, early Sybase detect error early */
+ 	if (RetCode != SQL_ERROR) {
+@@ -33,30 +33,30 @@ main(int argc, char *argv[])
+ 		CHKFetch("E");
+ 	}
+ 
+-	ReadError();
++	odbc_read_error();
+ 	if (!strstr(odbc_err, "zero")) {
+ 		fprintf(stderr, "Message invalid\n");
+ 		return 1;
+ 	}
+ 
+-	SQLFetch(Statement);
+-	SQLFetch(Statement);
+-	SQLFetch(Statement);
+-	SQLMoreResults(Statement);
++	SQLFetch(odbc_stmt);
++	SQLFetch(odbc_stmt);
++	SQLFetch(odbc_stmt);
++	SQLMoreResults(odbc_stmt);
+ 
+ 	CHKAllocStmt(&stmt, "S");
+ 
+-	Command("SELECT * FROM sysobjects");
++	odbc_command("SELECT * FROM sysobjects");
+ 
+-	tmp_stmt = Statement;
+-	Statement = stmt;
++	tmp_stmt = odbc_stmt;
++	odbc_stmt = stmt;
+ 
+ 	/* a statement is already active so you get error */
+-	Command2("SELECT * FROM sysobjects", "E");
++	odbc_command2("SELECT * FROM sysobjects", "E");
+ 
+-	ReadError();
++	odbc_read_error();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/freeclose.c b/src/odbc/unittests/freeclose.c
+index 3367912..f092f08 100644
+--- a/src/odbc/unittests/freeclose.c
++++ b/src/odbc/unittests/freeclose.c
+@@ -52,7 +52,7 @@
+ 
+ #include "tds.h"
+ 
+-static char software_version[] = "$Id: freeclose.c,v 1.12 2010/03/01 14:52:52 freddy77 Exp $";
++static char software_version[] = "$Id: freeclose.c,v 1.13 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* this crazy test test that we do not send too much prepare ... */
+@@ -322,7 +322,7 @@ main(int argc, char **argv)
+ 	WSAStartup(MAKEWORD(1, 1), &wsaData);
+ #endif
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	last_socket = find_last_socket();
+ 	if (TDS_IS_SOCKET_INVALID(last_socket)) {
+@@ -336,8 +336,8 @@ main(int argc, char **argv)
+ 		return 1;
+ 	}
+ 
+-	is_freetds = driver_is_freetds();
+-	Disconnect();
++	is_freetds = odbc_driver_is_freetds();
++	odbc_disconnect();
+ 
+ 	/* init fake server, behave like a proxy */
+ 	for (port = 12340; port < 12350; ++port)
+@@ -355,23 +355,23 @@ main(int argc, char **argv)
+ 		sprintf(string, "%d", port);
+ 		setenv("TDSPORT", string, 1);
+ 
+-		Connect();
++		odbc_connect();
+ 	} else {
+ 		char tmp[2048];
+ 		SQLSMALLINT len;
+ 
+-		CHKAllocEnv(&Environment, "S");
+-		CHKAllocConnect(&Connection, "S");
+-		sprintf(tmp, "DRIVER={SQL Server};SERVER=127.0.0.1,%d;UID=%s;PWD=%s;DATABASE=%s;Network=DBMSSOCN;", port, USER, PASSWORD, DATABASE);
++		CHKAllocEnv(&odbc_env, "S");
++		CHKAllocConnect(&odbc_conn, "S");
++		sprintf(tmp, "DRIVER={SQL Server};SERVER=127.0.0.1,%d;UID=%s;PWD=%s;DATABASE=%s;Network=DBMSSOCN;", port, odbc_user, odbc_password, odbc_database);
+ 		printf("connection string: %s\n", tmp);
+ 		CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+-		CHKAllocStmt(&Statement, "S");
++		CHKAllocStmt(&odbc_stmt, "S");
+ 	}
+ 
+ 	/* real test */
+-	Command("CREATE TABLE #test(i int, c varchar(40))");
++	odbc_command("CREATE TABLE #test(i int, c varchar(40))");
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* do not take into account connection statistics */
+ 	round_trips = 0;
+@@ -392,7 +392,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	printf("%u round trips %u inserts\n", round_trips, inserts);
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	if (inserts > 1 || round_trips > num_inserts * 2 + 6) {
+ 		fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts);
+@@ -421,7 +421,7 @@ main(int argc, char **argv)
+ 	}
+ 
+ 	printf("%u round trips %u inserts\n", round_trips, inserts);
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	if (inserts > 1 || round_trips > num_inserts * 2 + 6) {
+ 		fprintf(stderr, "Too much round trips (%u) or insert (%u) !!!\n", round_trips, inserts);
+@@ -430,7 +430,7 @@ main(int argc, char **argv)
+ 	printf("%u round trips %u inserts\n", round_trips, inserts);
+ #endif
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	alarm(10);
+ 	pthread_join(fake_thread, NULL);
+diff --git a/src/odbc/unittests/funccall.c b/src/odbc/unittests/funccall.c
+index 43b62bd..5e5d199 100644
+--- a/src/odbc/unittests/funccall.c
++++ b/src/odbc/unittests/funccall.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for {?=call store(?)} syntax and run */
+ 
+-static char software_version[] = "$Id: funccall.c,v 1.17 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: funccall.c,v 1.18 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -13,11 +13,11 @@ main(int argc, char *argv[])
+ 	SQLINTEGER out1;
+ 	char out2[30];
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");
++	odbc_command("IF OBJECT_ID('simpleresult') IS NOT NULL DROP PROC simpleresult");
+ 
+-	Command("create proc simpleresult @i int as begin return @i end");
++	odbc_command("create proc simpleresult @i int as begin return @i end");
+ 
+ 	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &input, 0, &ind2, "S");
+ 	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+@@ -35,13 +35,13 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* should return "Invalid cursor state" */
+-	if (SQLFetch(Statement) != SQL_ERROR) {
++	if (SQLFetch(odbc_stmt) != SQL_ERROR) {
+ 		printf("Data not expected\n");
+ 		exit(1);
+ 	}
+ 
+ 	/* just to reset some possible buffers */
+-	Command("DECLARE @i INT");
++	odbc_command("DECLARE @i INT");
+ 
+ 	/* same test but with SQLExecDirect and same bindings */
+ 	input = 567;
+@@ -57,15 +57,15 @@ main(int argc, char *argv[])
+ 	/* should return "Invalid cursor state" */
+ 	CHKFetch("E");
+ 
+-	Command("drop proc simpleresult");
++	odbc_command("drop proc simpleresult");
+ 
+-	Command("IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");
++	odbc_command("IF OBJECT_ID('simpleresult2') IS NOT NULL DROP PROC simpleresult2");
+ 
+ 	/* force cursor close */
+-	SQLCloseCursor(Statement);
++	SQLCloseCursor(odbc_stmt);
+ 
+ 	/* test output parameter */
+-	Command("create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
++	odbc_command("create proc simpleresult2 @i int, @x int output, @y varchar(20) output as begin select @x = 6789 select @y = 'test foo' return @i end");
+ 
+ 	CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0,  0, &output, 0,            &ind,  "S");
+ 	CHKBindParameter(2, SQL_PARAM_INPUT,  SQL_C_SLONG, SQL_INTEGER, 0,  0, &input,  0,            &ind2, "S");
+@@ -92,19 +92,19 @@ main(int argc, char *argv[])
+ 	/* should return "Invalid cursor state" */
+ 	CHKFetch("E");
+ 
+-	Command("drop proc simpleresult2");
++	odbc_command("drop proc simpleresult2");
+ 
+ 	/*
+ 	 * test from shiv kumar
+ 	 * Cfr ML 2006-11-21 "specifying a 0 for the StrLen_or_IndPtr in the
+ 	 * SQLBindParameter call is not working on AIX"
+ 	 */
+-	Command("IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");
++	odbc_command("IF OBJECT_ID('rpc_read') IS NOT NULL DROP PROC rpc_read");
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+-	Command("create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
+-	SQLCloseCursor(Statement);
++	odbc_command("create proc rpc_read @i int, @x timestamp as begin select 1 return 1234 end");
++	SQLCloseCursor(odbc_stmt);
+ 
+ 	CHKPrepare((SQLCHAR *) "{ ? = CALL rpc_read ( ?, ? ) }" , SQL_NTS, "S");
+ 
+@@ -123,8 +123,8 @@ main(int argc, char *argv[])
+ 
+ 	CHKFetch("No");
+ 
+-	ResetStatement();
+-	Command("drop proc rpc_read");
++	odbc_reset_statement();
++	odbc_command("drop proc rpc_read");
+ 
+ 	/*
+ 	 * Test from Joao Amaral
+@@ -133,14 +133,14 @@ main(int argc, char *argv[])
+ 	 * (with is supported only by mssql and do not return all stuff as 
+ 	 * select does)
+ 	 */
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 
+-		ResetStatement();
++		odbc_reset_statement();
+ 
+-		Command("IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
+-		Command("create proc sp_test @res int output as set @res = 456");
++		odbc_command("IF OBJECT_ID('sp_test') IS NOT NULL DROP PROC sp_test");
++		odbc_command("create proc sp_test @res int output as set @res = 456");
+ 
+-		ResetStatement();
++		odbc_reset_statement();
+ 
+ 		CHKPrepare((SQLCHAR *) "{ call sp_test(?)}", SQL_NTS, "S");
+ 		CHKBindParameter(1, SQL_PARAM_OUTPUT, SQL_C_SLONG, SQL_INTEGER, 0, 0, &output, 0, &ind, "S");
+@@ -152,10 +152,10 @@ main(int argc, char *argv[])
+ 			fprintf(stderr, "Invalid result %d(%x)\n", (int) output, (int) output);
+ 			return 1;
+ 		}
+-		Command("drop proc sp_test");
++		odbc_command("drop proc sp_test");
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/genparams.c b/src/odbc/unittests/genparams.c
+index c3eaa8d..f40cb36 100644
+--- a/src/odbc/unittests/genparams.c
++++ b/src/odbc/unittests/genparams.c
+@@ -18,7 +18,7 @@
+  * Also we have to check normal char and wide char
+  */
+ 
+-static char software_version[] = "$Id: genparams.c,v 1.45 2009/08/27 12:32:14 freddy77 Exp $";
++static char software_version[] = "$Id: genparams.c,v 1.46 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef TDS_NO_DM
+@@ -42,19 +42,19 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 	int i;
+ 	const char *sep;
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* build store procedure to test */
+-	Command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
++	odbc_command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
+ 	sep = "'";
+ 	if (strncmp(value_to_convert, "0x", 2) == 0)
+ 		sep = "";
+ 	sprintf(sbuf, "CREATE PROC spTestProc @i %s OUTPUT AS SELECT @i = CONVERT(%s, %s%s%s)", type, type, sep, value_to_convert, sep);
+-	Command(sbuf);
++	odbc_command(sbuf);
+ 	memset(out_buf, 0, sizeof(out_buf));
+ 
+ 	if (use_cursors) {
+-		ResetStatement();
++		odbc_reset_statement();
+ 		CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
+ 		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+ 	}
+@@ -83,8 +83,8 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 	 * MS OBDC requires it cause first recordset is a recordset with a
+ 	 * warning caused by the way it execute RPC (via EXEC statement)
+ 	 */
+-	if (use_cursors && !driver_is_freetds())
+-		SQLMoreResults(Statement);
++	if (use_cursors && !odbc_driver_is_freetds())
++		SQLMoreResults(odbc_stmt);
+ 
+ 	/* test results */
+ 	sbuf[0] = 0;
+@@ -115,7 +115,7 @@ TestOutput(const char *type, const char *value_to_convert, SQLSMALLINT out_c_typ
+ 		fprintf(stderr, "Wrong result\n  Got: %s\n  Expected: %s\n", sbuf, expected);
+ 		exit(1);
+ 	}
+-	Command("drop proc spTestProc");
++	odbc_command("drop proc spTestProc");
+ }
+ 
+ static char check_truncation = 0;
+@@ -132,7 +132,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	const char *p;
+ 	const char *sep = "'";
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* execute a select to get data as wire */
+ 	if ((p = strstr(value_to_convert, " -> ")) != NULL) {
+@@ -142,8 +142,8 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	if (value_len >= 2 && strncmp(value_to_convert, "0x", 2) == 0)
+ 		sep = "";
+ 	sprintf(sbuf, "SELECT CONVERT(%s, %s%.*s%s)", type, sep, (int) value_len, value_to_convert, sep);
+-	Command(sbuf);
+-	SQLBindCol(Statement, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
++	odbc_command(sbuf);
++	SQLBindCol(odbc_stmt, 1, out_c_type, out_buf, sizeof(out_buf), &out_len);
+ 	CHKFetch("SI");
+ 	CHKFetch("No");
+ 	CHKMoreResults("No");
+@@ -153,12 +153,12 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 	}
+ 
+ 	/* create a table with a column of that type */
+-	ResetStatement();
++	odbc_reset_statement();
+ 	sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s)", param_type);
+-	Command(sbuf);
++	odbc_command(sbuf);
+ 
+ 	if (use_cursors) {
+-		ResetStatement();
++		odbc_reset_statement();
+ 		CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
+ 		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+ 	}
+@@ -189,7 +189,7 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 
+ 	/* check if row is present */
+ 	if (!check_truncation) {
+-		ResetStatement();
++		odbc_reset_statement();
+ 		sep = "'";
+ 		if (strncmp(expected, "0x", 2) == 0)
+ 			sep = "";
+@@ -201,14 +201,14 @@ TestInput(SQLSMALLINT out_c_type, const char *type, SQLSMALLINT out_sql_type, co
+ 			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE CONVERT(VARBINARY(255), col) = CONVERT(VARBINARY(255), %s%s%s)", sep, expected, sep);
+ 		else
+ 			sprintf(sbuf, "SELECT * FROM #tmp_insert WHERE col = CONVERT(%s, %s%s%s)", param_type, sep, expected, sep);
+-		Command(sbuf);
++		odbc_command(sbuf);
+ 
+ 		CHKFetch("S");
+ 		CHKFetch("No");
+ 		CHKMoreResults("No");
+ 	}
+ 	check_truncation = 0;
+-	Command("DROP TABLE #tmp_insert");
++	odbc_command("DROP TABLE #tmp_insert");
+ }
+ 
+ /* stripped down version of TestInput for NULLs */
+@@ -218,15 +218,15 @@ NullInput(SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *param_ty
+ 	char sbuf[1024];
+ 	SQLLEN out_len = SQL_NULL_DATA;
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* create a table with a column of that type */
+-	ResetStatement();
++	odbc_reset_statement();
+ 	sprintf(sbuf, "CREATE TABLE #tmp_insert (col %s NULL)", param_type);
+-	Command(sbuf);
++	odbc_command(sbuf);
+ 
+ 	if (use_cursors) {
+-		ResetStatement();
++		odbc_reset_statement();
+ 		CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
+ 		CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+ 	}
+@@ -250,16 +250,16 @@ NullInput(SQLSMALLINT out_c_type, SQLSMALLINT out_sql_type, const char *param_ty
+ 	}
+ 
+ 	/* check if row is present */
+-	ResetStatement();
+-	if (!db_is_microsoft() && strcmp(param_type, "TEXT") == 0)
+-		Command("SELECT * FROM #tmp_insert WHERE col LIKE ''");
++	odbc_reset_statement();
++	if (!odbc_db_is_microsoft() && strcmp(param_type, "TEXT") == 0)
++		odbc_command("SELECT * FROM #tmp_insert WHERE col LIKE ''");
+ 	else
+-		Command("SELECT * FROM #tmp_insert WHERE col IS NULL");
++		odbc_command("SELECT * FROM #tmp_insert WHERE col IS NULL");
+ 
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+ 	CHKMoreResults("No");
+-	Command("DROP TABLE #tmp_insert");
++	odbc_command("DROP TABLE #tmp_insert");
+ }
+ 
+ 
+@@ -285,7 +285,7 @@ AllTests(void)
+ 	NullInput(SQL_C_TYPE_TIMESTAMP, SQL_TYPE_TIMESTAMP, "DATETIME");
+ 	NullInput(SQL_C_FLOAT,  SQL_REAL, "FLOAT");
+ 	NullInput(SQL_C_NUMERIC, SQL_LONGVARCHAR, "TEXT");
+-	if (db_is_microsoft() && db_version_int() >= 0x08000000u)
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u)
+ 		NullInput(SQL_C_BIT, SQL_BIT, "BIT");
+ 	NullInput(SQL_C_DOUBLE, SQL_DOUBLE, "MONEY");
+ 
+@@ -301,12 +301,12 @@ AllTests(void)
+ 	 * MS driver behavior for output parameters is different
+ 	 * former returns "313233" while newer "333133323333"
+ 	 */
+-	if (driver_is_freetds())
++	if (odbc_driver_is_freetds())
+ 		TestOutput("VARCHAR(20)", "313233", SQL_C_BINARY, SQL_VARCHAR, "333133323333");
+ 	/* FIXME our driver ignore precision for date */
+ 	precision = 3;
+ 	/* Some MS driver incorrectly prepare with smalldatetime*/
+-	if (!use_cursors || driver_is_freetds())
++	if (!use_cursors || odbc_driver_is_freetds())
+ 		TestOutput("DATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP, big_endian ? "0000949700FBAA2C" : "979400002CAAFB00");
+ 	TestOutput("SMALLDATETIME", "2004-02-24 15:16:17", SQL_C_BINARY, SQL_TIMESTAMP,
+ 	     big_endian ? "0000949700FB9640" : "979400004096FB00");
+@@ -330,9 +330,9 @@ AllTests(void)
+ 	m = ltime->tm_mon + 1;
+ 	d = ltime->tm_mday;
+ 	/* server concept of data can be different so try ask to server */
+-	Command("SELECT GETDATE()");
+-	SQLBindCol(Statement, 1, SQL_C_CHAR, date, sizeof(date), NULL);
+-	if (SQLFetch(Statement) == SQL_SUCCESS) {
++	odbc_command("SELECT GETDATE()");
++	SQLBindCol(odbc_stmt, 1, SQL_C_CHAR, date, sizeof(date), NULL);
++	if (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
+ 		int a, b, c;
+ 		if (sscanf(date, "%d-%d-%d", &a, &b, &c) == 3) {
+ 			y = a;
+@@ -340,9 +340,9 @@ AllTests(void)
+ 			d = c;
+ 		}
+ 	}
+-	SQLFetch(Statement);
+-	SQLMoreResults(Statement);
+-	SQLFreeStmt(Statement, SQL_UNBIND);
++	SQLFetch(odbc_stmt);
++	SQLMoreResults(odbc_stmt);
++	SQLFreeStmt(odbc_stmt, SQL_UNBIND);
+ 	sprintf(buf, "2003-07-22 13:02:03 -> %04d-%02d-%02d 13:02:03", (int) y, (int) m, (int) d);
+ 	TestInput(SQL_C_TYPE_TIME, "DATETIME", SQL_TYPE_TIMESTAMP, "DATETIME", buf);
+ 
+@@ -387,7 +387,7 @@ AllTests(void)
+ 	TestOutput("VARCHAR(20)", "0xf8f9", SQL_C_CHAR, SQL_VARCHAR, "2 \xf8\xf9");
+ 
+ 	/* TODO some Sybase versions */
+-	if (db_is_microsoft() && db_version_int() >= 0x08000000u) {
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
+ 		TestOutput("BIGINT", "-987654321065432", SQL_C_BINARY, SQL_BIGINT, big_endian ? "FFFC7DBBCF083228" : "283208CFBB7DFCFF");
+ 		TestInput(SQL_C_SBIGINT, "BIGINT", SQL_BIGINT, "BIGINT", "-12345678901234");
+ 		TestInput(SQL_C_CHAR, "NVARCHAR(100)", SQL_WCHAR, "NVARCHAR(100)", "test");
+@@ -433,7 +433,7 @@ AllTests(void)
+ 		TestInput(SQL_C_BINARY, "VARBINARY(100)", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
+ 		TestInput(SQL_C_BINARY, "IMAGE", SQL_WVARCHAR, "NVARCHAR(20)", "0x4100450054004F00 -> AETO");
+ 	}
+-	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u) {
+ 		TestInput(SQL_C_CHAR, "VARCHAR(20)", SQL_LONGVARCHAR, "VARCHAR(MAX)", "1EasyTest");
+ 		TestInput(SQL_C_BINARY, "VARBINARY(20)", SQL_LONGVARBINARY, "VARBINARY(MAX)", "Anything will suite!");
+ 	}
+@@ -442,17 +442,17 @@ AllTests(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	if (((char *) &big_endian)[0] == 1)
+ 		big_endian = 0;
+ 
+ 	for (use_cursors = 0; use_cursors <= 1; ++use_cursors) {
+ 		if (use_cursors) {
+-			if (!tds_no_dm || !driver_is_freetds())
+-				ResetStatement();
+-			CheckCursor();
++			if (!tds_no_dm || !odbc_driver_is_freetds())
++				odbc_reset_statement();
++			odbc_check_cursor();
+ 		}
+ 
+ 		exec_direct = 1;
+@@ -466,7 +466,7 @@ main(int argc, char *argv[])
+ 		AllTests();
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done successfully!\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/getdata.c b/src/odbc/unittests/getdata.c
+index b9b2daa..591019c 100644
+--- a/src/odbc/unittests/getdata.c
++++ b/src/odbc/unittests/getdata.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: getdata.c,v 1.17 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: getdata.c,v 1.18 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -13,17 +13,17 @@ test_err(const char *data, int c_type, const char *state)
+ 	char *buf = (char *) malloc(buf_size);
+ 
+ 	sprintf(sql, "SELECT '%s'", data);
+-	Command(sql);
+-	SQLFetch(Statement);
++	odbc_command(sql);
++	SQLFetch(odbc_stmt);
+ 	CHKGetData(1, c_type, buf, buf_size, &ind, "E");
+ 	free(buf);
+-	ReadError();
++	odbc_read_error();
+ 	if (strcmp(odbc_sqlstate, state) != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+-	ResetStatement();
++	odbc_reset_statement();
+ }
+ 
+ static int lc;
+@@ -56,14 +56,14 @@ main(int argc, char *argv[])
+ 	SQLLEN len;
+ 	SQLRETURN rc;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	lc = 1;
+ 	type = SQL_C_CHAR;
+ 
+ 	for (;;) {
+ 		/* TODO test with VARCHAR too */
+-		Command("SELECT CONVERT(TEXT,'Prova')");
++		odbc_command("SELECT CONVERT(TEXT,'Prova')");
+ 
+ 		CHKFetch("S");
+ 
+@@ -82,10 +82,10 @@ main(int argc, char *argv[])
+ 			exit(1);
+ 		}
+ 
+-		ResetStatement();
++		odbc_reset_statement();
+ 
+ 		/* test with varchar, not blob but variable */
+-		Command("SELECT CONVERT(VARCHAR(100), 'Other test')");
++		odbc_command("SELECT CONVERT(VARCHAR(100), 'Other test')");
+ 
+ 		CHKFetch("S");
+ 
+@@ -101,7 +101,7 @@ main(int argc, char *argv[])
+ 			exit(1);
+ 		}
+ 
+-		ResetStatement();
++		odbc_reset_statement();
+ 
+ 		if (type != SQL_C_CHAR)
+ 			break;
+@@ -111,7 +111,7 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* test with fixed length */
+-	Command("SELECT CONVERT(INT, 12345)");
++	odbc_command("SELECT CONVERT(INT, 12345)");
+ 
+ 	CHKFetch("S");
+ 
+@@ -128,10 +128,10 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* test with numeric */
+-	Command("SELECT CONVERT(NUMERIC(18,5), 1850000000000)");
++	odbc_command("SELECT CONVERT(NUMERIC(18,5), 1850000000000)");
+ 
+ 	CHKFetch("S");
+ 
+@@ -151,11 +151,11 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 
+ 	/* test int to truncated string */
+-	Command("SELECT CONVERT(INTEGER, 12345)");
++	odbc_command("SELECT CONVERT(INTEGER, 12345)");
+ 	CHKFetch("S");
+ 
+ 	/* error 22003 */
+@@ -168,37 +168,37 @@ main(int argc, char *argv[])
+ 		exit(1);
+ 	}
+ #endif
+-	ReadError();
++	odbc_read_error();
+ 	if (strcmp(odbc_sqlstate, "22003") != 0) {
+ 		fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ 	CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* test unique identifier to truncated string */
+-	rc = Command2("SELECT CONVERT(UNIQUEIDENTIFIER, 'AA7DF450-F119-11CD-8465-00AA00425D90')", "SENo");
++	rc = odbc_command2("SELECT CONVERT(UNIQUEIDENTIFIER, 'AA7DF450-F119-11CD-8465-00AA00425D90')", "SENo");
+ 	if (rc != SQL_ERROR) {
+ 		CHKFetch("S");
+ 
+ 		/* error 22003 */
+ 		CHKGetData(1, SQL_C_CHAR, buf, 17, NULL, "E");
+-		ReadError();
++		odbc_read_error();
+ 		if (strcmp(odbc_sqlstate, "22003") != 0) {
+ 			fprintf(stderr, "Unexpected sql state %s returned\n", odbc_sqlstate);
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(1);
+ 		}
+ 		CHKGetData(1, SQL_C_CHAR, buf, 2, NULL, "No");
+ 	}
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	/* test error from SQLGetData */
+ 	/* wrong constant, SQL_VARCHAR is invalid as C type */
+@@ -213,12 +213,12 @@ main(int argc, char *argv[])
+ 	test_err("1234567890123456789", SQL_C_LONG,      "22003");
+ 
+ 	/* test for empty string from mssql */
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 		lc = 1;
+ 		type = SQL_C_CHAR;
+ 
+ 		for (;;) {
+-			Command("SELECT CONVERT(TEXT,'')");
++			odbc_command("SELECT CONVERT(TEXT,'')");
+ 
+ 			CHKFetch("S");
+ 
+@@ -231,7 +231,7 @@ main(int argc, char *argv[])
+ 			}
+ 
+ 			CHKGetData(1, type, buf, lc, NULL, "No");
+-			ResetStatement();
++			odbc_reset_statement();
+ 
+ 			if (type != SQL_C_CHAR)
+ 				break;
+@@ -239,7 +239,7 @@ main(int argc, char *argv[])
+ 			type = SQL_C_WCHAR;
+ 		}	
+ 
+-		Command("SELECT CONVERT(TEXT,'')");
++		odbc_command("SELECT CONVERT(TEXT,'')");
+ 
+ 		CHKFetch("S");
+ 
+@@ -254,7 +254,7 @@ main(int argc, char *argv[])
+ 		CHKGetData(1, SQL_C_BINARY, buf, 1, NULL, "No");
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/hidden.c b/src/odbc/unittests/hidden.c
+index 61a11c9..8670abc 100755
+--- a/src/odbc/unittests/hidden.c
++++ b/src/odbc/unittests/hidden.c
+@@ -3,7 +3,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: hidden.c,v 1.7 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: hidden.c,v 1.8 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,16 +12,16 @@ main(int argc, char **argv)
+ 	SQLSMALLINT cnt = 0;
+ 	int failed = 0;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #t1 ( k INT, c CHAR(10), vc VARCHAR(10) )");
+-	Command("CREATE TABLE #tmp1 (i NUMERIC(10,0) IDENTITY PRIMARY KEY, b VARCHAR(20) NULL, c INT NOT NULL)");
++	odbc_command("CREATE TABLE #t1 ( k INT, c CHAR(10), vc VARCHAR(10) )");
++	odbc_command("CREATE TABLE #tmp1 (i NUMERIC(10,0) IDENTITY PRIMARY KEY, b VARCHAR(20) NULL, c INT NOT NULL)");
+ 
+ 	/* test hidden column with FOR BROWSE */
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+-	Command("SELECT c, b FROM #tmp1");
++	odbc_command("SELECT c, b FROM #tmp1");
+ 
+ 	CHKNumResultCols(&cnt, "S");
+ 
+@@ -29,10 +29,10 @@ main(int argc, char **argv)
+ 		fprintf(stderr, "Wrong number of columns in result set: %d\n", (int) cnt);
+ 		failed = 1;
+ 	}
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* test hidden column with cursors*/
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_NONSCROLLABLE, SQL_IS_UINTEGER, "S");
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_SENSITIVITY, (SQLPOINTER) SQL_SENSITIVE, SQL_IS_UINTEGER, "S");
+@@ -48,7 +48,7 @@ main(int argc, char **argv)
+ 		failed = 1;
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return failed ? 1: 0;
+ }
+diff --git a/src/odbc/unittests/insert_speed.c b/src/odbc/unittests/insert_speed.c
+index 31bc2eb..f4c0acb 100644
+--- a/src/odbc/unittests/insert_speed.c
++++ b/src/odbc/unittests/insert_speed.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: insert_speed.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: insert_speed.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SQL_QUERY_LENGTH 80
+@@ -17,7 +17,7 @@ insert_test_auto(void)
+ 	SQLINTEGER id = 0;
+ 	char string[64];
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
+ 	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+@@ -28,7 +28,7 @@ insert_test_auto(void)
+ 		CHKExecute("SI");
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ }
+ 
+ 
+@@ -44,7 +44,7 @@ insert_test_man(void)
+ 
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, int2ptr(commit_off), SQL_IS_INTEGER, "SI");
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SLONG, SQL_INTEGER, sizeof(id), 0, &id, 0, &sql_nts, "SI");
+ 	CHKBindParameter(2, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, sizeof(string), 0, string, 0, &sql_nts, "SI");
+@@ -55,28 +55,28 @@ insert_test_man(void)
+ 		CHKExecute("SI");
+ 	}
+ 
+-	SQLEndTran(SQL_HANDLE_DBC, Connection, SQL_COMMIT);
+-	SQLSetConnectAttr(Connection, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_on), SQL_IS_INTEGER);
+-	ResetStatement();
++	SQLEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT);
++	SQLSetConnectAttr(odbc_conn, SQL_ATTR_AUTOCOMMIT, int2ptr(commit_on), SQL_IS_INTEGER);
++	odbc_reset_statement();
+ }
+ 
+ int
+ main(int argc, char **argv)
+ {
+-	Connect();
++	odbc_connect();
+ 
+-	CommandWithResult(Statement, "DROP TABLE test");
+-	Command("CREATE TABLE test(i int, c varchar(40))");
++	odbc_command_with_result(odbc_stmt, "DROP TABLE test");
++	odbc_command("CREATE TABLE test(i int, c varchar(40))");
+ 
+ 	insert_test_man();
+ 
+-	Command("DELETE FROM test");
++	odbc_command("DELETE FROM test");
+ 
+ 	insert_test_auto();
+ 
+-	Command("DROP TABLE test");
++	odbc_command("DROP TABLE test");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/lang_error.c b/src/odbc/unittests/lang_error.c
+index 9e1f7d0..759729d 100644
+--- a/src/odbc/unittests/lang_error.c
++++ b/src/odbc/unittests/lang_error.c
+@@ -2,18 +2,18 @@
+ 
+ /* Test if SQLExecDirect return error if a error in row is returned */
+ 
+-static char software_version[] = "$Id: lang_error.c,v 1.5 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: lang_error.c,v 1.6 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+ 	/* issue print statement and test message returned */
+-	Command2("SELECT DATEADD(dd,-100000,getdate())", "E");
++	odbc_command2("SELECT DATEADD(dd,-100000,getdate())", "E");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/moreandcount.c b/src/odbc/unittests/moreandcount.c
+index 3828288..db0cd28 100644
+--- a/src/odbc/unittests/moreandcount.c
++++ b/src/odbc/unittests/moreandcount.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults and SQLRowCount on batch */
+ 
+-static char software_version[] = "$Id: moreandcount.c,v 1.18 2009/03/17 09:05:47 freddy77 Exp $";
++static char software_version[] = "$Id: moreandcount.c,v 1.19 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -30,68 +30,68 @@ DoTest(int prepare)
+ 	}
+ 	if (!prepare) {
+ 		printf("Result %d\n", ++n);
+-		CHECK_COLS(0);
+-		CHECK_ROWS(1);
++		ODBC_CHECK_COLS(0);
++		ODBC_CHECK_ROWS(1);
+ 		CHKMoreResults("S");
+ 	}
+ 	printf("Result %d\n", ++n);
+-	CHECK_COLS(1);
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(-1);
+ 	CHKFetch("S");
+ 	CHKFetch("S");
+-	CHECK_COLS(1);
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(-1);
+ 	CHKFetch("No");
+-	CHECK_COLS(1);
+-	CHECK_ROWS(2);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(2);
+ 	CHKMoreResults("S");
+ 	if (!prepare) {
+ 		printf("Result %d\n", ++n);
+-		CHECK_COLS(0);
+-		CHECK_ROWS(1);
++		ODBC_CHECK_COLS(0);
++		ODBC_CHECK_ROWS(1);
+ 		CHKMoreResults("S");
+ 		printf("Result %d\n", ++n);
+-		CHECK_COLS(0);
+-		CHECK_ROWS(2);
++		ODBC_CHECK_COLS(0);
++		ODBC_CHECK_ROWS(2);
+ 		CHKMoreResults("S");
+ 	}
+ 	printf("Result %d\n", ++n);
+-	CHECK_COLS(1);
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(-1);
+ 	CHKFetch("S");
+-	CHECK_COLS(1);
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(-1);
+ 	CHKFetch("No");
+-	CHECK_COLS(1);
++	ODBC_CHECK_COLS(1);
+ 	if (prepare) {
+ 		/* collapse 2 recordset... after a lot of testing this is the behavior! */
+-		if (driver_is_freetds())
+-			CHECK_ROWS(2);
++		if (odbc_driver_is_freetds())
++			ODBC_CHECK_ROWS(2);
+ 	} else {
+-		CHECK_ROWS(1);
++		ODBC_CHECK_ROWS(1);
+ 		CHKMoreResults("S");
+-		CHECK_COLS(0);
+-		CHECK_ROWS(2);
++		ODBC_CHECK_COLS(0);
++		ODBC_CHECK_ROWS(2);
+ 	}
+ 
+ 	CHKMoreResults("No");
+ #ifndef TDS_NO_DM
+ 	if (!prepare)
+-		CHECK_COLS(-1);
+-	CHECK_ROWS(-2);
++		ODBC_CHECK_COLS(-1);
++	ODBC_CHECK_ROWS(-2);
+ #endif
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+-	Command("create table #tmp1 (i int)");
+-	Command("create table #tmp2 (i int)");
+-	Command("insert into #tmp1 values(1)");
+-	Command("insert into #tmp1 values(2)");
+-	Command("insert into #tmp1 values(5)");
++	odbc_command("create table #tmp1 (i int)");
++	odbc_command("create table #tmp2 (i int)");
++	odbc_command("insert into #tmp1 values(1)");
++	odbc_command("insert into #tmp1 values(2)");
++	odbc_command("insert into #tmp1 values(5)");
+ 
+ 	printf("Use direct statement\n");
+ 	DoTest(0);
+@@ -99,7 +99,7 @@ main(int argc, char *argv[])
+ 	printf("Use prepared statement\n");
+ 	DoTest(1);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/norowset.c b/src/odbc/unittests/norowset.c
+index cbe7d9e..6241f2c 100644
+--- a/src/odbc/unittests/norowset.c
++++ b/src/odbc/unittests/norowset.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: norowset.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: norowset.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Test that a select following a store procedure execution return results */
+@@ -11,16 +11,16 @@ main(int argc, char *argv[])
+ 	char output[256];
+ 	SQLLEN dataSize;
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	CommandWithResult(Statement, "drop proc sp_norowset_test");
++	odbc_command_with_result(odbc_stmt, "drop proc sp_norowset_test");
+ 
+-	Command("create proc sp_norowset_test as begin declare @i int end");
++	odbc_command("create proc sp_norowset_test as begin declare @i int end");
+ 
+-	Command("exec sp_norowset_test");
++	odbc_command("exec sp_norowset_test");
+ 
+ 	/* note, mssql 2005 seems to not return row for tempdb, use always master */
+-	Command("select name from master..sysobjects where name = 'sysobjects'");
++	odbc_command("select name from master..sysobjects where name = 'sysobjects'");
+ 	CHKFetch("S");
+ 
+ 	CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &dataSize, "S");
+@@ -34,9 +34,9 @@ main(int argc, char *argv[])
+ 
+ 	CHKMoreResults("No");
+ 
+-	Command("drop proc sp_norowset_test");
++	odbc_command("drop proc sp_norowset_test");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/paramcore.c b/src/odbc/unittests/paramcore.c
+index e23db83..5636b77 100644
+--- a/src/odbc/unittests/paramcore.c
++++ b/src/odbc/unittests/paramcore.c
+@@ -4,7 +4,7 @@
+  * Try to make core dump using SQLBindParameter
+  */
+ 
+-static char software_version[] = "$Id: paramcore.c,v 1.7 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: paramcore.c,v 1.8 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{call sp_paramcore_test(?)}"
+@@ -15,46 +15,46 @@ main(int argc, char *argv[])
+ {
+ 	SQLLEN cb = SQL_NTS;
+ 
+-	use_odbc_version3 = 1;
++	odbc_use_version3 = 1;
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	CommandWithResult(Statement, "drop proc sp_paramcore_test");
+-	Command("create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");
++	odbc_command_with_result(odbc_stmt, "drop proc sp_paramcore_test");
++	odbc_command("create proc sp_paramcore_test @s varchar(100) output as select @s = '12345'");
+ 
+ 	/* here we pass a NULL buffer for input SQL_NTS */
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, NULL, OUTSTRING_LEN, &cb, "S");
+ 
+ 	cb = SQL_NTS;
+ 	CHKExecDirect((SQLCHAR*) SP_TEXT, SQL_NTS, "E");
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* here we pass a NULL buffer for input */
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_LONG, SQL_VARCHAR, 18, 0, NULL, OUTSTRING_LEN, &cb, "S");
+ 
+ 	cb = 1;
+ 	CHKExecDirect((SQLCHAR*) SP_TEXT, SQL_NTS, "E");
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+-	Command("drop proc sp_paramcore_test");
+-	Command("create proc sp_paramcore_test @s numeric(10,2) output as select @s = 12345.6");
+-	ResetStatement();
++	odbc_command("drop proc sp_paramcore_test");
++	odbc_command("create proc sp_paramcore_test @s numeric(10,2) output as select @s = 12345.6");
++	odbc_reset_statement();
+ 
+ #if 0	/* this fails even on native platforms */
+ 	/* here we pass a NULL buffer for output */
+ 	cb = sizeof(SQL_NUMERIC_STRUCT);
+-	SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_NUMERIC, SQL_NUMERIC, 18, 0, NULL, OUTSTRING_LEN, &cb);
+-	ReadError();
++	SQLBindParameter(odbc_stmt, 1, SQL_PARAM_OUTPUT, SQL_C_NUMERIC, SQL_NUMERIC, 18, 0, NULL, OUTSTRING_LEN, &cb);
++	odbc_read_error();
+ 
+ 	cb = 1;
+-	CommandWithResult(Statement, SP_TEXT);
+-	ReadError();
+-	ResetStatement();
++	odbc_command_with_result(odbc_stmt, SP_TEXT);
++	odbc_read_error();
++	odbc_reset_statement();
+ #endif
+ 
+-	Command("drop proc sp_paramcore_test");
++	odbc_command("drop proc sp_paramcore_test");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done successfully!\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/params.c b/src/odbc/unittests/params.c
+index 9acd9b0..8623e8c 100644
+--- a/src/odbc/unittests/params.c
++++ b/src/odbc/unittests/params.c
+@@ -3,7 +3,7 @@
+ /* Test for store procedure and params */
+ /* Test from Tom Rogers */
+ 
+-static char software_version[] = "$Id: params.c,v 1.11 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: params.c,v 1.12 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* SP definition */
+@@ -30,13 +30,13 @@ Test(int bind_before)
+ 	SQLLEN cbReturnCode = 0, cbInParam = 0, cbOutParam = 0;
+ 	SQLLEN cbOutString = SQL_NTS;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* drop proc */
+-	Command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
++	odbc_command("IF OBJECT_ID('spTestProc') IS NOT NULL DROP PROC spTestProc");
+ 
+ 	/* create proc */
+-	Command(sp_define);
++	odbc_command(sp_define);
+ 
+ 	if (!bind_before)
+ 		CHKPrepare((SQLCHAR *) SP_TEXT, strlen(SP_TEXT), "S");
+@@ -55,7 +55,7 @@ Test(int bind_before)
+ 
+ 	CHKExecute("S");
+ 
+-	Command("DROP PROC spTestProc");
++	odbc_command("DROP PROC spTestProc");
+ 
+ 	printf("Output:\n");
+ 	printf("   Return Code = %d\n", (int) ReturnCode);
+@@ -73,7 +73,7 @@ Test(int bind_before)
+ 		return 1;
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+ 
+diff --git a/src/odbc/unittests/prepare_results.c b/src/odbc/unittests/prepare_results.c
+index bcf3993..cd18246 100644
+--- a/src/odbc/unittests/prepare_results.c
++++ b/src/odbc/unittests/prepare_results.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for data format returned from SQLPrepare */
+ 
+-static char software_version[] = "$Id: prepare_results.c,v 1.11 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: prepare_results.c,v 1.12 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,14 +12,14 @@ main(int argc, char *argv[])
+ 	SQLULEN size;
+ 	char name[128];
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("create table #odbctestdata (i int, c char(20), n numeric(34,12) )");
++	odbc_command("create table #odbctestdata (i int, c char(20), n numeric(34,12) )");
+ 
+ 	/* reset state */
+-	Command("select * from #odbctestdata");
+-	SQLFetch(Statement);
+-	SQLMoreResults(Statement);
++	odbc_command("select * from #odbctestdata");
++	SQLFetch(odbc_stmt);
++	SQLMoreResults(odbc_stmt);
+ 
+ 	/* test query returns column information for update */
+ 	CHKPrepare((SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS, "S");
+@@ -50,7 +50,7 @@ main(int argc, char *argv[])
+ 
+ 	CHKDescribeCol(2, (SQLCHAR *) name, sizeof(name), &namelen, &type, &size, &digits, &nullable, "S");
+ 
+-	if (type != SQL_CHAR || strcmp(name, "c") != 0 || (size != 20 && (db_is_microsoft() || size != 40))) {
++	if (type != SQL_CHAR || strcmp(name, "c") != 0 || (size != 20 && (odbc_db_is_microsoft() || size != 40))) {
+ 		fprintf(stderr, "wrong column 2 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+ 		exit(1);
+ 	}
+@@ -63,9 +63,9 @@ main(int argc, char *argv[])
+ 	}
+ 
+ 	/* TODO test SQLDescribeParam (when implemented) */
+-	Command("drop table #odbctestdata");
++	odbc_command("drop table #odbctestdata");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/prepclose.c b/src/odbc/unittests/prepclose.c
+index c68edb9..4b14e26 100644
+--- a/src/odbc/unittests/prepclose.c
++++ b/src/odbc/unittests/prepclose.c
+@@ -26,7 +26,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: prepclose.c,v 1.6 2010/03/01 14:50:55 freddy77 Exp $";
++static char software_version[] = "$Id: prepclose.c,v 1.7 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -67,7 +67,7 @@ Test(int direct)
+ 	char buf[256];
+ 	unsigned char sqlstate[6];
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	if (!close_last_socket()) {
+ 		fprintf(stderr, "Error closing connection\n");
+@@ -84,11 +84,11 @@ Test(int direct)
+ 			CHKNumResultCols(&cols, "E");
+ 	}
+ 
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	sqlstate[5] = 0;
+ 	printf("state=%s err=%s\n", (char*) sqlstate, buf);
+ 	
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/preperror.c b/src/odbc/unittests/preperror.c
+index a6b0a71..c759dd3 100644
+--- a/src/odbc/unittests/preperror.c
++++ b/src/odbc/unittests/preperror.c
+@@ -2,7 +2,7 @@
+ 
+ /* test error on prepared statement, from Nathaniel Talbott test */
+ 
+-static char software_version[] = "$Id: preperror.c,v 1.8 2008/11/04 14:46:17 freddy77 Exp $";
++static char software_version[] = "$Id: preperror.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,9 +12,9 @@ main(int argc, char *argv[])
+ 	char buf[256];
+ 	unsigned char sqlstate[6];
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #urls ( recdate DATETIME ) ");
++	odbc_command("CREATE TABLE #urls ( recdate DATETIME ) ");
+ 
+ 	/* test implicit conversion error */
+ 	CHKExecDirect((SQLCHAR *) "INSERT INTO #urls ( recdate ) VALUES ( '2003-10-1 10:11:1 0' )", SQL_NTS, "E");
+@@ -27,21 +27,21 @@ main(int argc, char *argv[])
+ 
+ 	CHKExecute("E");
+ 
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	printf("err=%s\n", buf);
+ 
+ 	/* assure initial state */
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* try to prepare and execute a statement with error (from DBD::ODBC test) */
+ 	if (CHKPrepare((SQLCHAR *) "SELECT XXNOTCOLUMN FROM sysobjects", SQL_NTS, "SE") == SQL_SUCCESS)
+ 		CHKExecute("E");
+ 
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	printf("err=%s\n", buf);
+ 
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/print.c b/src/odbc/unittests/print.c
+index 4702db7..eaa232b 100644
+--- a/src/odbc/unittests/print.c
++++ b/src/odbc/unittests/print.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: print.c,v 1.23 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: print.c,v 1.24 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLCHAR output[256];
+@@ -17,15 +17,15 @@ test(int odbc3)
+ 	SQLLEN cnamesize;
+ 	const char *query;
+ 
+-	use_odbc_version3 = odbc3;
++	odbc_use_version3 = odbc3;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* issue print statement and test message returned */
+ 	output[0] = 0;
+ 	query = "print 'START' select count(*) from sysobjects where name='sysobjects' print 'END'";
+-	Command2(query, "I");
+-	ReadError();
++	odbc_command2(query, "I");
++	odbc_read_error();
+ 	if (!strstr(odbc_err, "START")) {
+ 		printf("Message invalid\n");
+ 		return 1;
+@@ -33,22 +33,22 @@ test(int odbc3)
+ 	odbc_err[0] = 0;
+ 
+ 	if (odbc3) {
+-		CHECK_COLS(0);
+-		CHECK_ROWS(-1);
++		ODBC_CHECK_COLS(0);
++		ODBC_CHECK_ROWS(-1);
+ 		CHKFetch("E");
+ 		CHKMoreResults("S");
+ 	}
+     
+-	CHECK_COLS(1);
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(-1);
+ 
+ 	CHKFetch("S");
+-	CHECK_COLS(1);
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(-1);
+ 	/* check no data */
+ 	CHKFetch("No");
+-	CHECK_COLS(1);
+-	CHECK_ROWS(1);
++	ODBC_CHECK_COLS(1);
++	ODBC_CHECK_ROWS(1);
+ 
+ 	/* SQLMoreResults return NO DATA or SUCCESS WITH INFO ... */
+ 	if (tds_no_dm && !odbc3)
+@@ -63,7 +63,7 @@ test(int odbc3)
+ 	 * (unixODBC till 2.2.11 do not read errors on NO DATA, skip test)
+ 	 */
+ 	if (tds_no_dm || odbc3) {
+-		ReadError();
++		odbc_read_error();
+ 		if (!strstr(odbc_err, "END")) {
+ 			printf("Message invalid\n");
+ 			return 1;
+@@ -74,29 +74,29 @@ test(int odbc3)
+ 	if (!odbc3) {
+ 		if (tds_no_dm) {
+ #if 0
+-			CHECK_COLS(-1);
++			ODBC_CHECK_COLS(-1);
+ #endif
+-			CHECK_ROWS(-2);
++			ODBC_CHECK_ROWS(-2);
+ 		}
+ 	} else {
+-		CHECK_COLS(0);
+-		CHECK_ROWS(-1);
++		ODBC_CHECK_COLS(0);
++		ODBC_CHECK_ROWS(-1);
+ 
+ 		CHKMoreResults("No");
+ 	}
+ 
+ 	/* issue invalid command and test error */
+-	Command2("SELECT donotexistsfield FROM donotexiststable", "E");
+-	ReadError();
++	odbc_command2("SELECT donotexistsfield FROM donotexiststable", "E");
++	odbc_read_error();
+ 
+ 	/* test no data returned */
+ 	CHKFetch("E");
+-	ReadError();
++	odbc_read_error();
+ 
+ 	CHKGetData(1, SQL_C_CHAR, output, sizeof(output), &cnamesize, "E");
+-	ReadError();
++	odbc_read_error();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/putdata.c b/src/odbc/unittests/putdata.c
+index c406487..7439a7b 100644
+--- a/src/odbc/unittests/putdata.c
++++ b/src/odbc/unittests/putdata.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLPutData */
+ 
+-static char software_version[] = "$Id: putdata.c,v 1.17 2009/03/06 09:14:09 freddy77 Exp $";
++static char software_version[] = "$Id: putdata.c,v 1.18 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char test_text[] =
+@@ -25,7 +25,7 @@ CheckNoRow(const char *query)
+ 		CHKNumResultCols(&cols, "S");
+ 		if (cols != 0) {
+ 			fprintf(stderr, "Data not expected here, query:\n\t%s\n", query);
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(1);
+ 		}
+ 	} while (CHKMoreResults("SNo") == SQL_SUCCESS);
+@@ -54,10 +54,10 @@ main(int argc, char *argv[])
+ 	SQLRETURN RetCode;
+ 	int type, lc, sql_type;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* create table to hold data */
+-	Command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
++	odbc_command("CREATE TABLE #putdata (c TEXT NULL, b IMAGE NULL)");
+ 
+ 	sql_type = SQL_LONGVARCHAR;
+ 	type = SQL_C_CHAR;
+@@ -99,10 +99,10 @@ main(int argc, char *argv[])
+ 		CHKParamData(&ptr, "E");
+ 
+ 		/* check state  and reset some possible buffers */
+-		Command("DECLARE @i INT");
++		odbc_command("DECLARE @i INT");
+ 
+ 		/* use server ntext if available */
+-		if (sql_type == SQL_LONGVARCHAR && db_is_microsoft() && db_version_int() >= 0x08000000u) {
++		if (sql_type == SQL_LONGVARCHAR && odbc_db_is_microsoft() && odbc_db_version_int() >= 0x08000000u) {
+ 			sql_type = SQL_WLONGVARCHAR;
+ 			continue;
+ 		}
+@@ -148,7 +148,7 @@ main(int argc, char *argv[])
+ 	CHKParamData(&ptr, "E");
+ 
+ 	/* check state  and reset some possible buffers */
+-	Command("DECLARE @i2 INT");
++	odbc_command("DECLARE @i2 INT");
+ 
+ 
+ 	CHKFreeStmt(SQL_RESET_PARAMS, "S");
+@@ -170,7 +170,7 @@ main(int argc, char *argv[])
+ 	strcat(sql, "') SELECT 1");
+ 	CheckNoRow(sql);
+ 
+-	Command("DELETE FROM #putdata");
++	odbc_command("DELETE FROM #putdata");
+ 
+ 	/* test len == 0 case from ML */
+ 	type = SQL_C_CHAR;
+@@ -183,20 +183,20 @@ main(int argc, char *argv[])
+ 
+ 		RetCode = CHKExecute("Ne");
+ 		while (RetCode == SQL_NEED_DATA) {
+-			RetCode = SQLParamData(Statement, &ptr);
++			RetCode = SQLParamData(odbc_stmt, &ptr);
+ 			if (RetCode == SQL_NEED_DATA) {
+ 				if (type == SQL_C_CHAR) {
+-					SQLPutData(Statement, "abc", 3);
++					SQLPutData(odbc_stmt, "abc", 3);
+ 				} else {
+ 					SQLWCHAR buf[10];
+-					SQLPutData(Statement, buf, to_sqlwchar(buf, "abc", 3));
++					SQLPutData(odbc_stmt, buf, to_sqlwchar(buf, "abc", 3));
+ 				}
+ 			}
+ 		}
+ 		if (type != SQL_C_CHAR)
+ 			break;
+ 		type = SQL_C_WCHAR;
+-		ResetStatement();
++		odbc_reset_statement();
+ 	}
+ 
+ 	/* check inserts ... */
+@@ -204,7 +204,7 @@ main(int argc, char *argv[])
+ 
+ 	/* TODO test cancel inside SQLExecute */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/raiserror.c b/src/odbc/unittests/raiserror.c
+index 684df8c..1c83d4c 100644
+--- a/src/odbc/unittests/raiserror.c
++++ b/src/odbc/unittests/raiserror.c
+@@ -4,7 +4,7 @@
+ 
+ /* TODO add support for Sybase */
+ 
+-static char software_version[] = "$Id: raiserror.c,v 1.24 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: raiserror.c,v 1.25 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define SP_TEXT "{?=call #tmp1(?,?,?)}"
+@@ -61,7 +61,7 @@ TestResult(SQLRETURN result0, int level, const char *func)
+ 	SqlState[0] = 0;
+ 	MessageText[0] = 0;
+ 	NativeError = 0;
+-	rc = CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText, sizeof(MessageText), &TextLength, "SI");
++	rc = CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, SqlState, &NativeError, (SQLCHAR *) MessageText, sizeof(MessageText), &TextLength, "SI");
+ 	printf("Func=%s Result=%d DIAG REC 1: State=%s Error=%d: %s\n", func, (int) rc, SqlState, (int) NativeError, MessageText);
+ 
+ 	if (strstr(MessageText, "An error occurred") == NULL) {
+@@ -71,7 +71,7 @@ TestResult(SQLRETURN result0, int level, const char *func)
+ 	}
+ }
+ 
+-#define MY_ERROR(msg) ReportError(msg, line, __FILE__)
++#define MY_ERROR(msg) odbc_report_error(msg, line, __FILE__)
+ 
+ static void
+ CheckData(const char *s, int line)
+@@ -120,7 +120,7 @@ Test(int level)
+ 
+ 	char sql[80];
+ 
+-	printf("ODBC %d nocount %s select %s level %d\n", use_odbc_version3 ? 3 : 2,
++	printf("ODBC %d nocount %s select %s level %d\n", odbc_use_version3 ? 3 : 2,
+ 	       g_nocount ? "yes" : "no", g_second_select ? "yes" : "no", level);
+ 
+ 	ReturnCode = INVALID_RETURN;
+@@ -128,21 +128,21 @@ Test(int level)
+ 
+ 	/* test with SQLExecDirect */
+ 	sprintf(sql, "RAISERROR('An error occurred.', %d, 1)", level);
+-	result = CommandWithResult(Statement, sql);
++	result = odbc_command_with_result(odbc_stmt, sql);
+ 
+ 	TestResult(result, level, "SQLExecDirect");
+ 
+ 	/* test with SQLPrepare/SQLExecute */
+-	if (!SQL_SUCCEEDED(SQLPrepare(Statement, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)))) {
++	if (!SQL_SUCCEEDED(SQLPrepare(odbc_stmt, (SQLCHAR *) SP_TEXT, strlen(SP_TEXT)))) {
+ 		fprintf(stderr, "SQLPrepare failure!\n");
+ 		exit(1);
+ 	}
+ 
+-	SQLBindParameter(Statement, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode);
+-	SQLBindParameter(Statement, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam, 0, &cbInParam);
+-	SQLBindParameter(Statement, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam, 0, &cbOutParam);
++	SQLBindParameter(odbc_stmt, 1, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &ReturnCode, 0, &cbReturnCode);
++	SQLBindParameter(odbc_stmt, 2, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &InParam, 0, &cbInParam);
++	SQLBindParameter(odbc_stmt, 3, SQL_PARAM_OUTPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &OutParam, 0, &cbOutParam);
+ 	strcpy(OutString, "Test");
+-	SQLBindParameter(Statement, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
++	SQLBindParameter(odbc_stmt, 4, SQL_PARAM_OUTPUT, SQL_C_CHAR, SQL_VARCHAR, OUTSTRING_LEN, 0, OutString, OUTSTRING_LEN,
+ 			 &cbOutString);
+ 
+ 	CHKExecute("S");
+@@ -151,8 +151,8 @@ Test(int level)
+ 	CHKFetch("S");
+ 	CheckData("Here is the first row");
+ 
+-	result = SQLFetch(Statement);
+-	if (use_odbc_version3) {
++	result = SQLFetch(odbc_stmt);
++	if (odbc_use_version3) {
+ 		SQLCHAR SqlState[6];
+ 		SQLINTEGER NativeError;
+ 		char MessageText[1000];
+@@ -161,13 +161,13 @@ Test(int level)
+ 
+ 		if (result != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("SQLFetch should return NO DATA");
+-		CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, SqlState, &NativeError, (SQLCHAR *) MessageText,
++		CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, SqlState, &NativeError, (SQLCHAR *) MessageText,
+ 				       sizeof(MessageText), &TextLength, "No");
+-		result = SQLMoreResults(Statement);
++		result = SQLMoreResults(odbc_stmt);
+ 		expected = level > 10 ? SQL_ERROR : SQL_SUCCESS_WITH_INFO;
+ 		if (result != expected)
+ 			ODBC_REPORT_ERROR("SQLMoreResults returned unexpected result");
+-		if (use_odbc_version3 && !g_second_select && g_nocount) {
++		if (odbc_use_version3 && !g_second_select && g_nocount) {
+ 			CheckReturnCode(result, 0);
+ 			ReturnCode = INVALID_RETURN;
+ 			TestResult(result, level, "SQLMoreResults");
+@@ -175,30 +175,30 @@ Test(int level)
+ 		} else {
+ 			TestResult(result, level, "SQLMoreResults");
+ 		}
+-		CHECK_ROWS(-1);
++		ODBC_CHECK_ROWS(-1);
+ 	} else {
+ 		TestResult(result, level, "SQLFetch");
+ 	}
+ 
+-	if (driver_is_freetds())
++	if (odbc_driver_is_freetds())
+ 		CheckData("");
+ 
+ 	if (!g_second_select) {
+-		CHECK_ROWS(-1);
++		ODBC_CHECK_ROWS(-1);
+ 		CheckReturnCode(result, g_nocount ? 0 : INVALID_RETURN);
+ 
+-		result = SQLMoreResults(Statement);
++		result = SQLMoreResults(odbc_stmt);
+ #ifdef ENABLE_DEVELOPING
+ 		if (result != SQL_NO_DATA)
+ 			ODBC_REPORT_ERROR("SQLMoreResults should return NO DATA");
+ 
+-		CHECK_ROWS(-2);
++		ODBC_CHECK_ROWS(-2);
+ #endif
+ 		CheckReturnCode(result, 0);
+ 		return;
+ 	}
+ 
+-	if (!use_odbc_version3 || !g_nocount) {
++	if (!odbc_use_version3 || !g_nocount) {
+ 		CHKMoreResults("S");
+ 		result = SQL_SUCCESS;
+ 	}
+@@ -212,7 +212,7 @@ Test(int level)
+ 	CHKFetch("No");
+ 	CheckData("");
+ 
+-	if (!use_odbc_version3 || g_nocount)
++	if (!odbc_use_version3 || g_nocount)
+ 		CheckReturnCode(result, 0);
+ #ifdef ENABLE_DEVELOPING
+ 	else
+@@ -220,7 +220,7 @@ Test(int level)
+ #endif
+ 
+ 	/* FIXME how to handle return in store procedure ??  */
+-	result = SQLMoreResults(Statement);
++	result = SQLMoreResults(odbc_stmt);
+ #ifdef ENABLE_DEVELOPING
+ 	if (result != SQL_NO_DATA)
+ 		ODBC_REPORT_ERROR("SQLMoreResults return other data");
+@@ -240,34 +240,34 @@ Test2(int nocount, int second_select)
+ 	g_second_select = second_select;
+ 
+ 	/* this test do not work with Sybase */
+-	if (!db_is_microsoft())
++	if (!odbc_db_is_microsoft())
+ 		return;
+ 
+ 	sprintf(sql, create_proc, nocount ? "     SET NOCOUNT ON\n" : "",
+ 		second_select ? "     SELECT 'Here is the last row' AS LastResult\n" : "");
+-	Command(sql);
++	odbc_command(sql);
+ 
+ 	Test(5);
+ 
+ 	Test(11);
+ 
+-	Command("DROP PROC #tmp1");
++	odbc_command("DROP PROC #tmp1");
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+ 	Test2(0, 1);
+ 
+ 	Test2(1, 1);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+-	use_odbc_version3 = 1;
++	odbc_use_version3 = 1;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	Test2(0, 1);
+ 	Test2(1, 1);
+@@ -275,7 +275,7 @@ main(int argc, char *argv[])
+ 	Test2(0, 0);
+ 	Test2(1, 0);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/rebindpar.c b/src/odbc/unittests/rebindpar.c
+index bb184a7..ab31b3b 100644
+--- a/src/odbc/unittests/rebindpar.c
++++ b/src/odbc/unittests/rebindpar.c
+@@ -2,10 +2,10 @@
+ 
+ /* Test for executing SQLExecute and rebinding parameters */
+ 
+-static char software_version[] = "$Id: rebindpar.c,v 1.9 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: rebindpar.c,v 1.10 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
++#define SWAP_STMT(b) do { SQLHSTMT xyz = odbc_stmt; odbc_stmt = b; b = xyz; } while(0)
+ 
+ static HSTMT stmt;
+ 
+@@ -24,7 +24,7 @@ TestInsert(char *buf)
+ 
+ 	SWAP_STMT(stmt);
+ 	sprintf(sql, "SELECT 1 FROM #tmp1 WHERE c = '%s'", buf);
+-	Command(sql);
++	odbc_command(sql);
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+ 	CHKMoreResults("No");
+@@ -43,7 +43,7 @@ Test(int prebind)
+ 	for (i = 0; i < 21; ++i)
+ 		strcat(buf, "miao");
+ 
+-	Command("DELETE FROM #tmp1");
++	odbc_command("DELETE FROM #tmp1");
+ 
+ 	CHKAllocStmt(&stmt, "S");
+ 
+@@ -55,28 +55,28 @@ Test(int prebind)
+ 
+ 	/* try to insert an empty string, should not fail */
+ 	/* NOTE this is currently the only test for insert a empty string using rpc */
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		TestInsert("");
+ 	TestInsert("a");
+ 	TestInsert("bb");
+ 	TestInsert(buf);
+ 
+ 	CHKFreeStmt(SQL_DROP, "S");
+-	Statement = SQL_NULL_HSTMT;
++	odbc_stmt = SQL_NULL_HSTMT;
+ 	SWAP_STMT(stmt);
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #tmp1 (c VARCHAR(200))");
++	odbc_command("CREATE TABLE #tmp1 (c VARCHAR(200))");
+ 
+ 	Test(1);
+ 	Test(0);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/rownumber.c b/src/odbc/unittests/rownumber.c
+index 0ccae96..72d61ed 100644
+--- a/src/odbc/unittests/rownumber.c
++++ b/src/odbc/unittests/rownumber.c
+@@ -7,7 +7,7 @@
+  * TODO make it work and add to Makefile.am
+  */
+ 
+-static char software_version[] = "$Id: rownumber.c,v 1.5 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: rownumber.c,v 1.6 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -27,8 +27,8 @@ CheckRowNum(int n, int line)
+ 	}
+ }
+ 
+-#undef CHECK_ROWS
+-#define CHECK_ROWS(n) CheckRowNum(n,__LINE__)
++#undef ODBC_CHECK_ROWS
++#define ODBC_CHECK_ROWS(n) CheckRowNum(n,__LINE__)
+ 
+ static void
+ DoTest()
+@@ -39,46 +39,46 @@ DoTest()
+ 	/* execute a batch command and check row number */
+ 	CHKExecDirect((SQLCHAR *) query, SQL_NTS, "S");
+ 
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_ROWS(-1);
+ 	printf("Result %d\n", ++n);
+ 	CHKFetch("S");
+-	CHECK_ROWS(0);
++	ODBC_CHECK_ROWS(0);
+ 	CHKFetch("S");
+-	CHECK_ROWS(0);
++	ODBC_CHECK_ROWS(0);
+ 	CHKFetch("S");
+-	CHECK_ROWS(0);
++	ODBC_CHECK_ROWS(0);
+ 	CHKFetch("No");
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_ROWS(-1);
+ 	CHKMoreResults("S");
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_ROWS(-1);
+ 
+ 	printf("Result %d\n", ++n);
+ 	CHKFetch("S");
+-	CHECK_ROWS(0);
++	ODBC_CHECK_ROWS(0);
+ 	CHKFetch("S");
+-	CHECK_ROWS(0);
++	ODBC_CHECK_ROWS(0);
+ 	CHKFetch("No");
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_ROWS(-1);
+ 	CHKMoreResults("No");
+-	CHECK_ROWS(-1);
++	ODBC_CHECK_ROWS(-1);
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
++	odbc_use_version3 = 1;
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("create table #tmp1 (i int)");
+-	Command("create table #tmp2 (i int)");
+-	Command("insert into #tmp1 values(1)");
+-	Command("insert into #tmp1 values(2)");
+-	Command("insert into #tmp1 values(5)");
++	odbc_command("create table #tmp1 (i int)");
++	odbc_command("create table #tmp2 (i int)");
++	odbc_command("insert into #tmp1 values(1)");
++	odbc_command("insert into #tmp1 values(2)");
++	odbc_command("insert into #tmp1 values(5)");
+ 
+ 	DoTest();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/rowset.c b/src/odbc/unittests/rowset.c
+index aec052e..454e353 100644
+--- a/src/odbc/unittests/rowset.c
++++ b/src/odbc/unittests/rowset.c
+@@ -1,16 +1,16 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: rowset.c,v 1.6 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: rowset.c,v 1.7 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ test_err(int n)
+ {
+ 	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(n), 0, "E");
+-	ReadError();
++	odbc_read_error();
+ 	if (strcmp(odbc_sqlstate, "HY024") != 0) {
+ 		fprintf(stderr, "Unexpected sql state returned\n");
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ }
+@@ -28,14 +28,14 @@ main(int argc, char *argv[])
+ 	SQLUSMALLINT statuses[10];
+ 	char buf[32];
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	/* initial value should be 1 */
+ 	CHKGetStmtAttr(SQL_ROWSET_SIZE, &len, sizeof(len), NULL, "S");
+ 	if (len != 1) {
+ 		fprintf(stderr, "len should be 1\n");
+-		Disconnect();
++		odbc_disconnect();
+ 		return 1;
+ 	}
+ 
+@@ -44,14 +44,14 @@ main(int argc, char *argv[])
+ 	test_err(-1);
+ 	test_err(0);
+ 
+-	CheckCursor();
++	odbc_check_cursor();
+ 
+ 	/* set some correct values */
+ 	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(2), 0, "S");
+ 	CHKSetStmtAttr(SQL_ROWSET_SIZE, (SQLPOINTER) int2ptr(1), 0, "S");
+ 
+ 	/* now check that SQLExtendedFetch works as expected */
+-	Command("CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
++	odbc_command("CREATE TABLE #rowset(n INTEGER, c VARCHAR(20))");
+ 	for (i = 0; i < 10; ++i) {
+ 		char s[10];
+ 		char sql[128];
+@@ -59,10 +59,10 @@ main(int argc, char *argv[])
+ 		memset(s, 'a' + i, 9);
+ 		s[9] = 0;
+ 		sprintf(sql, "INSERT INTO #rowset(n,c) VALUES(%d,'%s')", i+1, s);
+-		Command(sql);
++		odbc_command(sql);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 	CHKSetStmtOption(SQL_ATTR_CURSOR_TYPE, SQL_CURSOR_DYNAMIC, "S");
+ 	CHKExecDirect((SQLCHAR *) "SELECT * FROM #rowset ORDER BY n", SQL_NTS, "SI");
+ 
+@@ -74,11 +74,11 @@ main(int argc, char *argv[])
+ 
+ 	if (row_count != 1 || statuses[0] != SQL_ROW_SUCCESS || strcmp(buf, "aaaaaaaaa") != 0) {
+ 		fprintf(stderr, "Invalid result\n");
+-		Disconnect();
++		odbc_disconnect();
+ 		return 1;
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/rpc.c b/src/odbc/unittests/rpc.c
+index 405a0ca..78350ca 100644
+--- a/src/odbc/unittests/rpc.c
++++ b/src/odbc/unittests/rpc.c
+@@ -6,7 +6,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: rpc.c,v 1.12 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: rpc.c,v 1.13 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char procedure_sql[] = 
+@@ -56,7 +56,7 @@ Test(const char *name)
+ {
+ 	int iresults=0, data_errors=0;
+ 	int ipar=0;
+-	HSTMT Statement = SQL_NULL_HSTMT;
++	HSTMT odbc_stmt = SQL_NULL_HSTMT;
+ 	char call_cmd[128];
+ 	struct Argument { 
+                 SQLSMALLINT       InputOutputType;  /* fParamType */
+@@ -85,7 +85,7 @@ Test(const char *name)
+ 
+ 
+ 	printf("executing SQLAllocStmt\n");
+-	CHKAllocStmt(&Statement, "S");
++	CHKAllocStmt(&odbc_stmt, "S");
+ 
+ 	for( ipar=0; ipar < sizeof(args)/sizeof(args[0]); ipar++ ) {
+ 		printf("executing SQLBindParameter for parameter %d\n", 1+ipar);
+@@ -195,7 +195,7 @@ Test(const char *name)
+ 
+ 	printf("executing SQLFreeStmt\n");
+ 	CHKFreeStmt(SQL_DROP, "S");
+-	Statement = SQL_NULL_HSTMT;
++	odbc_stmt = SQL_NULL_HSTMT;
+ 
+ 	for (ipar = 0; ipar < sizeof(args)/sizeof(args[0]); ++ipar)
+ 		if (args[ipar].BufferLength > 0)
+@@ -216,7 +216,7 @@ main(int argc, char *argv[])
+ 	strcat(drop_proc, proc_name);
+ 	
+ 	printf("connecting\n");
+-	Connect();
++	odbc_connect();
+ 	
+ 	init_proc(proc_name);
+ 
+@@ -224,9 +224,9 @@ main(int argc, char *argv[])
+ 	Test(proc_name);
+ 	
+ 	printf("dropping procedure\n");
+-	Command(drop_proc);
++	odbc_command(drop_proc);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/scroll.c b/src/odbc/unittests/scroll.c
+index d87e29d..253dcce 100644
+--- a/src/odbc/unittests/scroll.c
++++ b/src/odbc/unittests/scroll.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test cursors */
+ 
+-static char software_version[] = "$Id: scroll.c,v 1.9 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: scroll.c,v 1.10 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -41,22 +41,22 @@ main(int argc, char *argv[])
+ 	};
+ 	const int num_tests = sizeof(tests) / sizeof(TEST);
+ 
+-	use_odbc_version3 = 1;
++	odbc_use_version3 = 1;
+ 
+-	Connect();
+-	CheckCursor();
++	odbc_connect();
++	odbc_check_cursor();
+ 
+ 	/* create test table */
+-	Command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
+-	Command("CREATE TABLE #test(i int, c varchar(6))");
+-	Command("INSERT INTO #test(i, c) VALUES(1, 'a')");
+-	Command("INSERT INTO #test(i, c) VALUES(2, 'bb')");
+-	Command("INSERT INTO #test(i, c) VALUES(3, 'ccc')");
+-	Command("INSERT INTO #test(i, c) VALUES(4, 'dddd')");
+-	Command("INSERT INTO #test(i, c) VALUES(5, 'eeeee')");
++	odbc_command("IF OBJECT_ID('tempdb..#test') IS NOT NULL DROP TABLE #test");
++	odbc_command("CREATE TABLE #test(i int, c varchar(6))");
++	odbc_command("INSERT INTO #test(i, c) VALUES(1, 'a')");
++	odbc_command("INSERT INTO #test(i, c) VALUES(2, 'bb')");
++	odbc_command("INSERT INTO #test(i, c) VALUES(3, 'ccc')");
++	odbc_command("INSERT INTO #test(i, c) VALUES(4, 'dddd')");
++	odbc_command("INSERT INTO #test(i, c) VALUES(5, 'eeeee')");
+ 
+ 	/* set cursor options */
+-	ResetStatement();
++	odbc_reset_statement();
+ 	CHKSetStmtAttr(SQL_ATTR_CONCURRENCY, (SQLPOINTER) SQL_CONCUR_ROWVER, 0, "S");
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_SCROLLABLE, (SQLPOINTER) SQL_SCROLLABLE, 0, "S");
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, 0, "S");
+@@ -112,8 +112,8 @@ main(int argc, char *argv[])
+ 		}
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/stats.c b/src/odbc/unittests/stats.c
+index 34ac2e8..f0feff8 100644
+--- a/src/odbc/unittests/stats.c
++++ b/src/odbc/unittests/stats.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: stats.c,v 1.2 2010/07/02 09:01:22 freddy77 Exp $";
++static char software_version[] = "$Id: stats.c,v 1.3 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static SQLLEN cnamesize;
+@@ -27,10 +27,10 @@ TestProc(const char *type, const char *expected)
+ {
+ 	char sql[256];
+ 
+-	Command("IF OBJECT_ID('stat_proc') IS NOT NULL DROP PROC stat_proc");
++	odbc_command("IF OBJECT_ID('stat_proc') IS NOT NULL DROP PROC stat_proc");
+ 
+ 	sprintf(sql, "CREATE PROC stat_proc(@t %s) AS RETURN 0", type);
+-	Command(sql);
++	odbc_command(sql);
+ 
+ 	column = "@t";
+ 	CHKProcedureColumns((SQLCHAR *) catalog, LEN(catalog), (SQLCHAR *) schema, LEN(schema), (SQLCHAR *) proc, LEN(proc), (SQLCHAR *) column, LEN(column), "SI");
+@@ -40,7 +40,7 @@ TestProc(const char *type, const char *expected)
+ 	ReadCol(6);
+ 	if (strcmp(output, expected) != 0) {
+ 		fprintf(stderr, "Got \"%s\" expected \"%s\"\n", output, expected);
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ 
+@@ -52,10 +52,10 @@ TestTable(const char *type, const char *expected)
+ {
+ 	char sql[256];
+ 
+-	Command("IF OBJECT_ID('stat_t') IS NOT NULL DROP TABLE stat_t");
++	odbc_command("IF OBJECT_ID('stat_t') IS NOT NULL DROP TABLE stat_t");
+ 
+ 	sprintf(sql, "CREATE TABLE stat_t(t %s)", type);
+-	Command(sql);
++	odbc_command(sql);
+ 
+ 	column = "t";
+ 	table = "stat_t";
+@@ -66,7 +66,7 @@ TestTable(const char *type, const char *expected)
+ 	ReadCol(5);
+ 	if (strcmp(output, expected) != 0) {
+ 		fprintf(stderr, "Got \"%s\" expected \"%s\"\n", output, expected);
+-		Disconnect();
++		odbc_disconnect();
+ 		exit(1);
+ 	}
+ 
+@@ -88,22 +88,22 @@ main(int argc, char *argv[])
+ {
+ 	char int_buf[32];
+ 
+-	use_odbc_version3 = 0;
+-	Connect();
++	odbc_use_version3 = 0;
++	odbc_connect();
+ 
+ 	TestProc("DATETIME", STR(SQL_TIMESTAMP));
+ 	TestTable("DATETIME", STR(SQL_TIMESTAMP));
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	TestProc("DATETIME", STR(SQL_TYPE_TIMESTAMP));
+ 	TestTable("DATETIME", STR(SQL_TYPE_TIMESTAMP));
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/t0001.c b/src/odbc/unittests/t0001.c
+index 4872809..d94880c 100644
+--- a/src/odbc/unittests/t0001.c
++++ b/src/odbc/unittests/t0001.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0001.c,v 1.18 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: t0001.c,v 1.19 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -14,22 +14,22 @@ main(int argc, char *argv[])
+ 	const char *command;
+ 	SQLCHAR output[256];
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
++	odbc_command("if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
+ 
+ 	command = "create table #odbctestdata ("
+ 		"col1 varchar(30) not null,"
+ 		"col2 int not null,"
+ 		"col3 float not null," "col4 numeric(18,6) not null," "col5 datetime not null," "col6 text not null)";
+-	Command(command);
++	odbc_command(command);
+ 
+ 	command = "insert #odbctestdata values ("
+ 		"'ABCDEFGHIJKLMNOP',"
+ 		"123456," "1234.56," "123456.78," "'Sep 11 2001 10:00AM'," "'just to check returned length...')";
+-	Command(command);
++	odbc_command(command);
+ 
+-	Command("select * from #odbctestdata");
++	odbc_command("select * from #odbctestdata");
+ 
+ 	CHKFetch("SI");
+ 
+@@ -45,9 +45,9 @@ main(int argc, char *argv[])
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	Command("drop table #odbctestdata");
++	odbc_command("drop table #odbctestdata");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/t0002.c b/src/odbc/unittests/t0002.c
+index c89628c..1b6cfd2 100644
+--- a/src/odbc/unittests/t0002.c
++++ b/src/odbc/unittests/t0002.c
+@@ -1,44 +1,44 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: t0002.c,v 1.16 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: t0002.c,v 1.17 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-#define SWAP_STMT(b) do { SQLHSTMT xyz = Statement; Statement = b; b = xyz; } while(0)
++#define SWAP_STMT(b) do { SQLHSTMT xyz = odbc_stmt; odbc_stmt = b; b = xyz; } while(0)
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	HSTMT old_Statement;
++	HSTMT old_odbc_stmt;
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
++	odbc_command("if object_id('tempdb..#odbctestdata') is not null drop table #odbctestdata");
+ 
+-	Command("create table #odbctestdata (i int)");
+-	Command("insert #odbctestdata values (123)");
++	odbc_command("create table #odbctestdata (i int)");
++	odbc_command("insert #odbctestdata values (123)");
+ 
+ 	/*
+ 	 * now we allocate another statement, select, get all results
+ 	 * then make another query with first select and drop this statement
+ 	 * result should not disappear (required for DBD::ODBC)
+ 	 */
+-	old_Statement = Statement;
+-	Statement = SQL_NULL_HSTMT;
+-	CHKAllocStmt(&Statement, "S");
++	old_odbc_stmt = odbc_stmt;
++	odbc_stmt = SQL_NULL_HSTMT;
++	CHKAllocStmt(&odbc_stmt, "S");
+ 
+-	Command("select * from #odbctestdata where 0=1");
++	odbc_command("select * from #odbctestdata where 0=1");
+ 
+ 	CHKFetch("No");
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	SWAP_STMT(old_Statement);
+-	Command("select * from #odbctestdata");
+-	SWAP_STMT(old_Statement);
++	SWAP_STMT(old_odbc_stmt);
++	odbc_command("select * from #odbctestdata");
++	SWAP_STMT(old_odbc_stmt);
+ 
+ 	/* drop first statement .. data should not disappear */
+ 	CHKFreeStmt(SQL_DROP, "S");
+-	Statement = old_Statement;
++	odbc_stmt = old_odbc_stmt;
+ 
+ 	CHKFetch("SI");
+ 
+@@ -46,9 +46,9 @@ main(int argc, char *argv[])
+ 
+ 	CHKCloseCursor("SI");
+ 
+-	Command("drop table #odbctestdata");
++	odbc_command("drop table #odbctestdata");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/t0003.c b/src/odbc/unittests/t0003.c
+index 2a0e9f5..4aef303 100644
+--- a/src/odbc/unittests/t0003.c
++++ b/src/odbc/unittests/t0003.c
+@@ -2,17 +2,17 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0003.c,v 1.19 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: t0003.c,v 1.20 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+ DoTest(int prepared)
+ {
+-	Command("create table #odbctestdata (i int)");
++	odbc_command("create table #odbctestdata (i int)");
+ 
+ 	/* test that 2 empty result set are returned correctly */
+ 	if (!prepared) {
+-		Command("select * from #odbctestdata select * from #odbctestdata");
++		odbc_command("select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+ 		CHKPrepare((SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
+ 		CHKExecute("S");
+@@ -28,9 +28,9 @@ DoTest(int prepared)
+ 	CHKMoreResults("No");
+ 
+ 	/* test that skipping a no empty result go to other result set */
+-	Command("insert into #odbctestdata values(123)");
++	odbc_command("insert into #odbctestdata values(123)");
+ 	if (!prepared) {
+-		Command("select * from #odbctestdata select * from #odbctestdata");
++		odbc_command("select * from #odbctestdata select * from #odbctestdata");
+ 	} else {
+ 		CHKPrepare((SQLCHAR *)"select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
+ 		CHKExecute("S");
+@@ -45,18 +45,18 @@ DoTest(int prepared)
+ 
+ 	CHKMoreResults("No");
+ 
+-	Command("drop table #odbctestdata");
++	odbc_command("drop table #odbctestdata");
+ }
+ 
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+ 	DoTest(0);
+ 	DoTest(1);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/t0004.c b/src/odbc/unittests/t0004.c
+index 2a4093d..6f6cc7b 100644
+--- a/src/odbc/unittests/t0004.c
++++ b/src/odbc/unittests/t0004.c
+@@ -2,7 +2,7 @@
+ 
+ /* Test for SQLMoreResults */
+ 
+-static char software_version[] = "$Id: t0004.c,v 1.17 2008/11/04 10:59:02 freddy77 Exp $";
++static char software_version[] = "$Id: t0004.c,v 1.18 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -41,12 +41,12 @@ Test(int use_indicator)
+ int
+ main(int argc, char *argv[])
+ {
+-	Connect();
++	odbc_connect();
+ 
+ 	Test(1);
+ 	Test(0);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/tables.c b/src/odbc/unittests/tables.c
+index 47c7251..3d6c293 100644
+--- a/src/odbc/unittests/tables.c
++++ b/src/odbc/unittests/tables.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: tables.c,v 1.18 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: tables.c,v 1.19 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -40,7 +40,7 @@ TestName(int index, const char *expected_name)
+ 
+ 	/* retrieve with SQLColAttribute */
+ 	CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		NAME_TEST;
+ 	CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
+ 	NAME_TEST;
+@@ -72,8 +72,8 @@ DoTest(const char *type, int row_returned)
+ 	CHKTables((SQLCHAR *) catalog, LEN(catalog), (SQLCHAR *) schema, LEN(schema), (SQLCHAR *) table_buf, table_len, (SQLCHAR *) type, LEN(type), "SI");
+ 
+ 	/* test column name (for DBD::ODBC) */
+-	TestName(1, use_odbc_version3 || !driver_is_freetds() ? "TABLE_CAT" : "TABLE_QUALIFIER");
+-	TestName(2, use_odbc_version3 || !driver_is_freetds() ? "TABLE_SCHEM" : "TABLE_OWNER");
++	TestName(1, odbc_use_version3 || !odbc_driver_is_freetds() ? "TABLE_CAT" : "TABLE_QUALIFIER");
++	TestName(2, odbc_use_version3 || !odbc_driver_is_freetds() ? "TABLE_SCHEM" : "TABLE_OWNER");
+ 	TestName(3, "TABLE_NAME");
+ 	TestName(4, "TABLE_TYPE");
+ 	TestName(5, "REMARKS");
+@@ -131,13 +131,13 @@ main(int argc, char *argv[])
+ 	char type[32];
+ 	int mssql2005 = 0;
+ 
+-	use_odbc_version3 = 0;
+-	Connect();
++	odbc_use_version3 = 0;
++	odbc_connect();
+ 
+-	if (db_is_microsoft() && db_version_int() >= 0x09000000u) {
++	if (odbc_db_is_microsoft() && odbc_db_version_int() >= 0x09000000u) {
+ 		mssql2005 = 1;
+ 		strcpy(expected_type, "VIEW");
+-		CommandWithResult(Statement, "USE master");
++		odbc_command_with_result(odbc_stmt, "USE master");
+ 	}
+ 
+ 	DoTest(NULL, 1);
+@@ -151,19 +151,19 @@ main(int argc, char *argv[])
+ 	sprintf(type, "TABLE,'%s'", expected_type);
+ 	DoTest(type, 1);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	if (mssql2005)
+-		CommandWithResult(Statement, "USE master");
++		odbc_command_with_result(odbc_stmt, "USE master");
+ 
+ 	sprintf(type, "'%s'", expected_type);
+ 	DoTest(type, 1);
+ 	/* TODO this should work even for Sybase and mssql 2005 */
+-	if (db_is_microsoft()) {
++	if (odbc_db_is_microsoft()) {
+ 		/* here table is a name of table */
+ 		catalog = "%";
+ 		schema = NULL;
+@@ -197,7 +197,7 @@ main(int argc, char *argv[])
+ 	expect_col = 2;
+ 	DoTest(NULL, 2);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/test64.c b/src/odbc/unittests/test64.c
+index 89b4623..4df9ad4 100644
+--- a/src/odbc/unittests/test64.c
++++ b/src/odbc/unittests/test64.c
+@@ -1,7 +1,7 @@
+ /* test win64 consistency */
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: test64.c,v 1.9 2010/01/09 19:05:07 freddy77 Exp $";
++static char software_version[] = "$Id: test64.c,v 1.10 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /*
+@@ -91,7 +91,7 @@ test_params(void)
+ 
+ 	/* now see results */
+ 	for (p = param_set; *p != NULL; ++p) {
+-		ResetStatement();
++		odbc_reset_statement();
+ 		len = 0xdeadbeef;
+ 		len <<= 16;
+ 		len <<= 16;
+@@ -103,10 +103,10 @@ test_params(void)
+ 		CHKSetStmtAttr(SQL_ATTR_PARAMSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 		CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_ULONG, SQL_INTEGER, 5, 0, ids, 0, id_lens, "S");
+ 
+-		Command("INSERT INTO #tmp1(i) VALUES(?)");
+-		SQLMoreResults(Statement);
++		odbc_command("INSERT INTO #tmp1(i) VALUES(?)");
++		SQLMoreResults(odbc_stmt);
+ 		for (n = 0; n < ARRAY_SIZE; ++n)
+-			SQLMoreResults(Statement);
++			SQLMoreResults(odbc_stmt);
+ 		l = len;
+ 		len >>= 16;
+ 		h = len >> 16;
+@@ -198,7 +198,7 @@ test_rows(void)
+ 	for (p = row_set; ; ++p) {
+ 		const char *test_name = NULL;
+ 
+-		ResetStatement();
++		odbc_reset_statement();
+ 		len = 0xdeadbeef;
+ 		len <<= 16;
+ 		len <<= 16;
+@@ -214,16 +214,16 @@ test_rows(void)
+ 		if (*p) {
+ 			CHKSetStmtAttr(SQL_ATTR_ROW_ARRAY_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+ 
+-			Command("SELECT DISTINCT i FROM #tmp1");
+-			SQLFetch(Statement);
++			odbc_command("SELECT DISTINCT i FROM #tmp1");
++			SQLFetch(odbc_stmt);
+ 			test_name = "SQLSetStmtAttr";
+ 		} else {
+ 			CHKSetStmtAttr(SQL_ROWSET_SIZE, (void *) int2ptr(ARRAY_SIZE), 0, "S");
+-			Command("SELECT DISTINCT i FROM #tmp1");
++			odbc_command("SELECT DISTINCT i FROM #tmp1");
+ 			CHKExtendedFetch(SQL_FETCH_NEXT, 0, &len, NULL, "S");
+ 			test_name = "SQLExtendedFetch";
+ 		}
+-		SQLMoreResults(Statement);
++		SQLMoreResults(odbc_stmt);
+ 
+ 		l = len;
+ 		len >>= 16;
+@@ -250,15 +250,15 @@ main(void)
+ 		return 0;
+ 	}
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+-	Command("create table #tmp1 (i int)");
++	odbc_command("create table #tmp1 (i int)");
+ 
+ 	test_params();
+ 	test_rows();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+ 
+diff --git a/src/odbc/unittests/testodbc.c b/src/odbc/unittests/testodbc.c
+index 6b80e8e..d5873e3 100644
+--- a/src/odbc/unittests/testodbc.c
++++ b/src/odbc/unittests/testodbc.c
+@@ -10,7 +10,7 @@
+ 
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: testodbc.c,v 1.14 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: testodbc.c,v 1.15 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef DEBUG
+@@ -51,11 +51,11 @@ TestRawODBCPreparedQuery(void)
+ 
+ 	/* INIT */
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* MAKE QUERY */
+ 
+-	Command("CREATE TABLE #Products ("
++	odbc_command("CREATE TABLE #Products ("
+ 		"ProductID int NOT NULL ,"
+ 		"ProductName varchar (40) ,"
+ 		"SupplierID int NULL ,"
+@@ -72,7 +72,7 @@ TestRawODBCPreparedQuery(void)
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(74,'Longlife Tofu',4,7,'5 kg pkg.',10.00,4,20,5,0) "
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(11,'Queso Cabrales',5,4,'1 kg pkg.',21.00,22,30,30,0) "
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(12,'Queso Manchego La Pastora',5,4,'10 - 500 g pkgs.',38.00,86,0,0,0)");
+-	while (SQLMoreResults(Statement) == SQL_SUCCESS);
++	while (SQLMoreResults(odbc_stmt) == SQL_SUCCESS);
+ 
+ 	queryString = (SQLCHAR *) "SELECT * FROM #Products WHERE SupplierID = ?";
+ 
+@@ -84,7 +84,7 @@ TestRawODBCPreparedQuery(void)
+ 
+ 	count = 0;
+ 
+-	while (SQLFetch(Statement) == SQL_SUCCESS) {
++	while (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
+ 		count++;
+ 	}
+ 	AB_PRINT(("Got %d rows", count));
+@@ -101,7 +101,7 @@ TestRawODBCPreparedQuery(void)
+ 
+ 	/* CLOSEDOWN */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	AB_FUNCT(("TestRawODBCPreparedQuery (out): ok"));
+ 	return TRUE;
+@@ -121,11 +121,11 @@ TestRawODBCDirectQuery(void)
+ 
+ 	/* INIT */
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* MAKE QUERY */
+ 
+-	Command("CREATE TABLE #Products ("
++	odbc_command("CREATE TABLE #Products ("
+ 		"ProductID int NOT NULL ,"
+ 		"ProductName varchar (40) ,"
+ 		"SupplierID int NULL ,"
+@@ -142,7 +142,7 @@ TestRawODBCDirectQuery(void)
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(3,'Aniseed Syrup',1,2,'12 - 550 ml bottles',10.00,13,70,25,0) "
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(4,'Chef Anton''s Cajun Seasoning',2,2,'48 - 6 oz jars',22.00,53,0,0,0) "
+ 		"INSERT INTO #Products(ProductID,ProductName,SupplierID,CategoryID,QuantityPerUnit,UnitPrice,UnitsInStock,UnitsOnOrder,ReorderLevel,Discontinued) VALUES(5,'Chef Anton''s Gumbo Mix',2,2,'36 boxes',21.35,0,0,0,1) ");
+-	while (SQLMoreResults(Statement) == SQL_SUCCESS);
++	while (SQLMoreResults(odbc_stmt) == SQL_SUCCESS);
+ 
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_SSHORT, SQL_INTEGER, 0, 0, &supplierId, 0, &lenOrInd, "S");
+ 
+@@ -150,7 +150,7 @@ TestRawODBCDirectQuery(void)
+ 
+ 	count = 0;
+ 
+-	while (SQLFetch(Statement) == SQL_SUCCESS) {
++	while (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
+ 		count++;
+ 	}
+ 	AB_PRINT(("Got %d rows", count));
+@@ -167,7 +167,7 @@ TestRawODBCDirectQuery(void)
+ 
+ 	/* CLOSEDOWN */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	AB_FUNCT(("TestRawODBCDirectQuery (out): ok"));
+ 	return TRUE;
+@@ -193,10 +193,10 @@ TestRawODBCGuid(void)
+ 
+ 	AB_FUNCT(("TestRawODBCGuid (in)"));
+ 
+-	Connect();
++	odbc_connect();
+ 	
+-	if (!db_is_microsoft()) {
+-		Disconnect();
++	if (!odbc_db_is_microsoft()) {
++		odbc_disconnect();
+ 		return TRUE;
+ 	}
+ 
+@@ -206,7 +206,7 @@ TestRawODBCGuid(void)
+ 	       "species VARCHAR(20), sex CHAR(1), age INTEGER, " "guid UNIQUEIDENTIFIER DEFAULT NEWID() ); ";
+ 	CHKExecDirect(queryString, SQL_NTS, "SNo");
+ 
+-	CommandWithResult(Statement, "DROP PROC GetGUIDRows");
++	odbc_command_with_result(odbc_stmt, "DROP PROC GetGUIDRows");
+ 
+ 	AB_PRINT(("Creating stored proc GetGUIDRows"));
+ 
+@@ -285,7 +285,7 @@ TestRawODBCGuid(void)
+ 	strcpy((char *) (guid), "1234abcd-abcd-abcd-abcd-123456789abc");
+ 
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_GUID, SQL_GUID, 16, 0, &sqlguid, 16, &lenOrInd, "S");
+-	status = SQLExecDirect(Statement, queryString, SQL_NTS);
++	status = SQLExecDirect(odbc_stmt, queryString, SQL_NTS);
+ 	if (status != SQL_SUCCESS) {
+ 		AB_ERROR(("Insert row 5 failed"));
+ 		AB_ERROR(("Sadly this was expected in *nix ODBC. Carry on."));
+@@ -297,7 +297,7 @@ TestRawODBCGuid(void)
+ 	AB_PRINT(("retrieving name and guid"));
+ 	queryString = (SQLCHAR *) "SELECT name, guid FROM #pet";
+ 	CHKExecDirect(queryString, SQL_NTS, "S");
+-	while (SQLFetch(Statement) == SQL_SUCCESS) {
++	while (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
+ 		count++;
+ 		CHKGetData(1, SQL_CHAR, name, 20, 0, "S");
+ 		CHKGetData(2, SQL_CHAR, guid, 37, 0, "S");
+@@ -309,7 +309,7 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state if we try SELECT again).
+ 	 */
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 
+ 	/*
+@@ -336,7 +336,7 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state if we try SELECT again).
+ 	 */
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/*
+ 	 * Now retrieve rows via stored procedure passing GUID as param.
+@@ -349,7 +349,7 @@ TestRawODBCGuid(void)
+ 
+ 	CHKBindParameter(1, SQL_PARAM_INPUT, SQL_C_CHAR, SQL_GUID, 0, 0, guid, 0, &lenOrInd, "S");
+ 	CHKExecDirect(queryString, SQL_NTS, "S");
+-	while (SQLFetch(Statement) == SQL_SUCCESS) {
++	while (SQLFetch(odbc_stmt) == SQL_SUCCESS) {
+ 		count++;
+ 		CHKGetData(1, SQL_CHAR, name, 20, 0, "S");
+ 		CHKGetData(2, SQL_CHAR, guid, 37, 0, "S");
+@@ -361,14 +361,14 @@ TestRawODBCGuid(void)
+ 	 * Realloc cursor handle - (Windows ODBC considers it an invalid cursor
+ 	 * state after a previous SELECT has occurred).
+ 	 */
+-	ResetStatement();
++	odbc_reset_statement();
+ 
+ 	/* cleanup */
+-	CommandWithResult(Statement, "DROP PROC GetGUIDRows");
++	odbc_command_with_result(odbc_stmt, "DROP PROC GetGUIDRows");
+ 
+ 	/* CLOSEDOWN */
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	AB_FUNCT(("TestRawODBCGuid (out): ok"));
+ 	return TRUE;
+@@ -426,7 +426,7 @@ RunTests(void)
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
++	odbc_use_version3 = 1;
+ 
+ 	if (RunTests())
+ 		return 0;	/* Success */
+diff --git a/src/odbc/unittests/timeout.c b/src/odbc/unittests/timeout.c
+index 230c89a..349d166 100644
+--- a/src/odbc/unittests/timeout.c
++++ b/src/odbc/unittests/timeout.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test timeout of query */
+ 
+-static char software_version[] = "$Id: timeout.c,v 1.12 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: timeout.c,v 1.13 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -15,7 +15,7 @@ AutoCommit(int onoff)
+ static void
+ EndTransaction(SQLSMALLINT type)
+ {
+-	CHKEndTran(SQL_HANDLE_DBC, Connection, type, "S");
++	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, type, "S");
+ }
+ 
+ int
+@@ -26,27 +26,27 @@ main(int argc, char *argv[])
+ 	HSTMT stmt;
+ 	SQLINTEGER i;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* here we can't use temporary table cause we use two connection */
+-	CommandWithResult(Statement, "drop table test_timeout");
+-	Command("create table test_timeout(n numeric(18,0) primary key, t varchar(30))");
++	odbc_command_with_result(odbc_stmt, "drop table test_timeout");
++	odbc_command("create table test_timeout(n numeric(18,0) primary key, t varchar(30))");
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 
+-	Command("insert into test_timeout(n, t) values(1, 'initial')");
++	odbc_command("insert into test_timeout(n, t) values(1, 'initial')");
+ 	EndTransaction(SQL_COMMIT);
+ 
+-	Command("update test_timeout set t = 'second' where n = 1");
++	odbc_command("update test_timeout set t = 'second' where n = 1");
+ 
+ 	/* save this connection and do another */
+-	env = Environment;
+-	dbc = Connection;
+-	stmt = Statement;
+-	Environment = SQL_NULL_HENV;
+-	Connection = SQL_NULL_HDBC;
+-	Statement = SQL_NULL_HSTMT;
++	env = odbc_env;
++	dbc = odbc_conn;
++	stmt = odbc_stmt;
++	odbc_env = SQL_NULL_HENV;
++	odbc_conn = SQL_NULL_HDBC;
++	odbc_stmt = SQL_NULL_HSTMT;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+ 	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+@@ -59,23 +59,23 @@ main(int argc, char *argv[])
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+ 	/* TODO should return error S1T00 Timeout expired, test error message */
+-	Command2("update test_timeout set t = 'bad' where n = 1", "E");
++	odbc_command2("update test_timeout set t = 'bad' where n = 1", "E");
+ 
+ 	EndTransaction(SQL_ROLLBACK);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+-	Environment = env;
+-	Connection = dbc;
+-	Statement = stmt;
++	odbc_env = env;
++	odbc_conn = dbc;
++	odbc_stmt = stmt;
+ 
+ 	EndTransaction(SQL_COMMIT);
+ 
+ 	/* Sybase do not accept DROP TABLE during a transaction */
+ 	AutoCommit(SQL_AUTOCOMMIT_ON);
+-	Command("drop table test_timeout");
++	odbc_command("drop table test_timeout");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/timeout2.c b/src/odbc/unittests/timeout2.c
+index 13d751d..619ae31 100644
+--- a/src/odbc/unittests/timeout2.c
++++ b/src/odbc/unittests/timeout2.c
+@@ -14,7 +14,7 @@
+  * Test from Ou Liu, cf "Query Time Out", 2006-08-08
+  */
+ 
+-static char software_version[] = "$Id: timeout2.c,v 1.8 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: timeout2.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if defined(__MINGW32__) || defined(_WIN32)
+@@ -26,10 +26,10 @@ main(int argc, char *argv[])
+ {
+ 	int i;
+ 
+-	Connect();
++	odbc_connect();
+ 
+-	Command("create table #timeout(i int)");
+-	Command("insert into #timeout values(1)");
++	odbc_command("create table #timeout(i int)");
++	odbc_command("insert into #timeout values(1)");
+ 
+ 	for (i = 0; i < 2; ++i) {
+ 
+@@ -50,13 +50,13 @@ main(int argc, char *argv[])
+ 			sleep(15);
+ 		}
+ 
+-		SQLFreeStmt(Statement, SQL_CLOSE);
+-		SQLFreeStmt(Statement, SQL_UNBIND);
+-		SQLFreeStmt(Statement, SQL_RESET_PARAMS);
+-		SQLCloseCursor(Statement);
++		SQLFreeStmt(odbc_stmt, SQL_CLOSE);
++		SQLFreeStmt(odbc_stmt, SQL_UNBIND);
++		SQLFreeStmt(odbc_stmt, SQL_RESET_PARAMS);
++		SQLCloseCursor(odbc_stmt);
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/timeout3.c b/src/odbc/unittests/timeout3.c
+index 5f87079..25a3743 100644
+--- a/src/odbc/unittests/timeout3.c
++++ b/src/odbc/unittests/timeout3.c
+@@ -40,7 +40,7 @@
+ 	test connection timeout
+ */
+ 
+-static char software_version[] = "$Id: timeout3.c,v 1.11 2010/03/01 14:50:55 freddy77 Exp $";
++static char software_version[] = "$Id: timeout3.c,v 1.12 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -48,9 +48,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKAllocEnv(&Environment, "S");
+-	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	CHKAllocConnect(&Connection, "S");
++	CHKAllocEnv(&odbc_env, "S");
++	SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++	CHKAllocConnect(&odbc_conn, "S");
+ }
+ 
+ static pthread_t      fake_thread;
+@@ -125,7 +125,7 @@ main(int argc, char *argv[])
+ 	int port;
+ 	time_t start_time, end_time;
+ 
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+ 	/*
+@@ -133,11 +133,11 @@ main(int argc, char *argv[])
+ 	 * is better to do it before connect cause uniODBC cache INIs
+ 	 * the name must be odbcinst.ini cause unixODBC accept only this name
+ 	 */
+-	if (DRIVER[0]) {
++	if (odbc_driver[0]) {
+ 		FILE *f = fopen("odbcinst.ini", "w");
+ 
+ 		if (f) {
+-			fprintf(f, "[FreeTDS]\nDriver = %s\n", DRIVER);
++			fprintf(f, "[FreeTDS]\nDriver = %s\n", odbc_driver);
+ 			fclose(f);
+ 			/* force iODBC */
+ 			setenv("ODBCINSTINI", "./odbcinst.ini", 1);
+@@ -169,8 +169,8 @@ main(int argc, char *argv[])
+ 
+ 	strcpy(sqlstate, "XXXXX");
+ 	tmp[0] = 0;
+-	CHKGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) tmp, sizeof(tmp), NULL, "SI");
+-	Disconnect();
++	CHKGetDiagRec(SQL_HANDLE_DBC, odbc_conn, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) tmp, sizeof(tmp), NULL, "SI");
++	odbc_disconnect();
+ 	CLOSESOCKET(fake_sock);
+ 	pthread_join(fake_thread, NULL);
+ 
+diff --git a/src/odbc/unittests/timeout4.c b/src/odbc/unittests/timeout4.c
+index 2bafe7d..91cc272 100644
+--- a/src/odbc/unittests/timeout4.c
++++ b/src/odbc/unittests/timeout4.c
+@@ -39,7 +39,7 @@
+  * prepare or execute a query. This should fail and return an error message.
+  */
+ 
+-static char software_version[] = "$Id: timeout4.c,v 1.5 2010/03/01 14:50:55 freddy77 Exp $";
++static char software_version[] = "$Id: timeout4.c,v 1.6 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #if HAVE_FSTAT && defined(S_IFSOCK)
+@@ -83,7 +83,7 @@ Test(int direct)
+ 	char sqlstate[6];
+ 	time_t start_time, end_time;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	if (!shutdown_last_socket()) {
+ 		fprintf(stderr, "Error shutting down connection\n");
+@@ -106,7 +106,7 @@ Test(int direct)
+ 	alarm(0);
+ 
+ 	strcpy(sqlstate, "XXXXX");
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, (SQLCHAR *) sqlstate, NULL, (SQLCHAR *) buf, sizeof(buf), NULL, "SI");
+ 	sqlstate[5] = 0;
+ 	printf("Message: %s - %s\n", sqlstate, buf);
+ 	if (strcmp(sqlstate, "HYT00") || !strstr(buf, "Timeout")) {
+@@ -118,7 +118,7 @@ Test(int direct)
+ 		return 1;
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	if (end_socket >= 0)
+ 		close(end_socket);
+@@ -130,7 +130,7 @@ Test(int direct)
+ int
+ main(void)
+ {
+-	use_odbc_version3 = 1;
++	odbc_use_version3 = 1;
+ 
+ 	if (Test(0) || Test(1))
+ 		return 1;
+diff --git a/src/odbc/unittests/transaction.c b/src/odbc/unittests/transaction.c
+index 54c4558..f15e57f 100644
+--- a/src/odbc/unittests/transaction.c
++++ b/src/odbc/unittests/transaction.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: transaction.c,v 1.16 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: transaction.c,v 1.17 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int
+@@ -24,44 +24,44 @@ Test(int discard_test)
+ 		"INSERT INTO TestTransaction VALUES ( @value )\n%s", discard_test ? "SELECT * FROM TestTransaction\n" : "");
+ 
+ 	/* create stored proc */
+-	CommandWithResult(Statement, "DROP PROCEDURE testinsert");
++	odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testinsert");
+ 
+-	Command(createProcedure);
++	odbc_command(createProcedure);
+ 
+ 	/* create stored proc that generates an error */
+-	CommandWithResult(Statement, "DROP PROCEDURE testerror");
++	odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testerror");
+ 
+-	Command(createErrorProcedure);
++	odbc_command(createErrorProcedure);
+ 
+ 	/* Start transaction */
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
+ 
+ 	/* Insert a value */
+-	Command("EXEC testinsert 1");
++	odbc_command("EXEC testinsert 1");
+ 
+ 	/* we should be able to read row count */
+ 	CHKRowCount(&rows, "S");
+ 
+ 	/* Commit transaction */
+-	CHKEndTran(SQL_HANDLE_DBC, Connection, SQL_COMMIT, "S");
++	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_COMMIT, "S");
+ 
+-	SQLCloseCursor(Statement);
++	SQLCloseCursor(odbc_stmt);
+ 
+ 	/* Start transaction */
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_OFF, 0, "S");
+ 
+ 	/* Insert another value */
+-	Command("EXEC testinsert 2");
++	odbc_command("EXEC testinsert 2");
+ 
+ 	/* Roll back transaction */
+-	CHKEndTran(SQL_HANDLE_DBC, Connection, SQL_ROLLBACK, "S");
++	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, SQL_ROLLBACK, "S");
+ 
+ 	/* TODO test row inserted */
+ 
+ 	CHKSetConnectAttr(SQL_ATTR_AUTOCOMMIT, (void *) SQL_AUTOCOMMIT_ON, 0, "S");
+ 
+ 	/* generate an error */
+-	Command("EXEC testerror");
++	odbc_command("EXEC testerror");
+ 	CHKBindCol(1, SQL_C_SLONG, &out_buf, sizeof(out_buf), &out_len, "S");
+ 
+ 	while (CHKFetch("SNo") == SQL_SUCCESS) {
+@@ -75,15 +75,15 @@ Test(int discard_test)
+ 
+ 	CHKMoreResults("E");
+ 
+-	CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, sqlstate, NULL, (SQLCHAR *)buf, sizeof(buf), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, sqlstate, NULL, (SQLCHAR *)buf, sizeof(buf), NULL, "SI");
+ 	printf("err=%s\n", buf);
+ 
+ 	CHKMoreResults("No");
+ 
+       cleanup:
+ 	/* drop table */
+-	CommandWithResult(Statement, "DROP PROCEDURE testinsert");
+-	CommandWithResult(Statement, "DROP PROCEDURE testerror");
++	odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testinsert");
++	odbc_command_with_result(odbc_stmt, "DROP PROCEDURE testerror");
+ 
+ 	return retcode;
+ }
+@@ -93,11 +93,11 @@ main(int argc, char *argv[])
+ {
+ 	int retcode = 0;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/* create table */
+-	CommandWithResult(Statement, "DROP TABLE TestTransaction");
+-	Command("CREATE TABLE TestTransaction ( value INT )");
++	odbc_command_with_result(odbc_stmt, "DROP TABLE TestTransaction");
++	odbc_command("CREATE TABLE TestTransaction ( value INT )");
+ 
+ 	if (!retcode)
+ 		retcode = Test(1);
+@@ -105,9 +105,9 @@ main(int argc, char *argv[])
+ 		retcode = Test(0);
+ 
+ 	/* drop table */
+-	CommandWithResult(Statement, "DROP TABLE TestTransaction");
++	odbc_command_with_result(odbc_stmt, "DROP TABLE TestTransaction");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return retcode;
+diff --git a/src/odbc/unittests/transaction2.c b/src/odbc/unittests/transaction2.c
+index a59b7d7..db37d45 100644
+--- a/src/odbc/unittests/transaction2.c
++++ b/src/odbc/unittests/transaction2.c
+@@ -3,7 +3,7 @@
+ 
+ /* Test transaction types */
+ 
+-static char software_version[] = "$Id: transaction2.c,v 1.9 2010/03/02 15:07:00 freddy77 Exp $";
++static char software_version[] = "$Id: transaction2.c,v 1.10 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -11,7 +11,7 @@ ReadErrorConn(void)
+ {
+ 	memset(odbc_err, 0, sizeof(odbc_err));
+ 	memset(odbc_sqlstate, 0, sizeof(odbc_sqlstate));
+-	CHKGetDiagRec(SQL_HANDLE_DBC, Connection, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
++	CHKGetDiagRec(SQL_HANDLE_DBC, odbc_conn, 1, (SQLCHAR *) odbc_sqlstate, NULL, (SQLCHAR *) odbc_err, sizeof(odbc_err), NULL, "SI");
+ 	printf("Message: '%s' %s\n", odbc_sqlstate, odbc_err);
+ }
+ 
+@@ -24,11 +24,11 @@ AutoCommit(int onoff)
+ static void
+ EndTransaction(SQLSMALLINT type)
+ {
+-	CHKEndTran(SQL_HANDLE_DBC, Connection, type, "S");
++	CHKEndTran(SQL_HANDLE_DBC, odbc_conn, type, "S");
+ }
+ 
+ #define SWAP(t,a,b) do { t xyz = a; a = b; b = xyz; } while(0)
+-#define SWAP_CONN() do { SWAP(HENV,env,Environment); SWAP(HDBC,dbc,Connection); SWAP(HSTMT,stmt,Statement);} while(0)
++#define SWAP_CONN() do { SWAP(HENV,env,odbc_env); SWAP(HDBC,dbc,odbc_conn); SWAP(HSTMT,stmt,odbc_stmt);} while(0)
+ 
+ static HENV env = SQL_NULL_HENV;
+ static HDBC dbc = SQL_NULL_HDBC;
+@@ -40,12 +40,12 @@ CheckDirtyRead(void)
+ 	SQLRETURN RetCode;
+ 
+ 	/* transaction 1 try to change a row but not commit */
+-	Command("UPDATE test_transaction SET t = 'second' WHERE n = 1");
++	odbc_command("UPDATE test_transaction SET t = 'second' WHERE n = 1");
+ 
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch uncommited row */
+-	RetCode = Command2("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1", "SE");
++	RetCode = odbc_command2("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1", "SE");
+ 	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+@@ -55,7 +55,7 @@ CheckDirtyRead(void)
+ 
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+ 	EndTransaction(SQL_ROLLBACK);
+@@ -69,12 +69,12 @@ CheckNonrepeatableRead(void)
+ 
+ 	/* transaction 2 read a row */
+ 	SWAP_CONN();
+-	Command("SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
+-	SQLMoreResults(Statement);
++	odbc_command("SELECT * FROM test_transaction WHERE t = 'initial' AND n = 1");
++	SQLMoreResults(odbc_stmt);
+ 
+ 	/* transaction 1 change a row and commit */
+ 	SWAP_CONN();
+-	RetCode = Command2("UPDATE test_transaction SET t = 'second' WHERE n = 1", "SE");
++	RetCode = odbc_command2("UPDATE test_transaction SET t = 'second' WHERE n = 1", "SE");
+ 	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+@@ -87,14 +87,14 @@ CheckNonrepeatableRead(void)
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch commited row */
+-	Command("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
++	odbc_command("SELECT * FROM test_transaction WHERE t = 'second' AND n = 1");
+ 
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+-	Command("UPDATE test_transaction SET t = 'initial' WHERE n = 1");
++	odbc_command("UPDATE test_transaction SET t = 'initial' WHERE n = 1");
+ 	EndTransaction(SQL_COMMIT);
+ 	return 1;
+ }
+@@ -106,12 +106,12 @@ CheckPhantom(void)
+ 
+ 	/* transaction 2 read a row */
+ 	SWAP_CONN();
+-	Command("SELECT * FROM test_transaction WHERE t = 'initial'");
+-	SQLMoreResults(Statement);
++	odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'");
++	SQLMoreResults(odbc_stmt);
+ 
+ 	/* transaction 1 insert a row that match critera */
+ 	SWAP_CONN();
+-	RetCode = Command2("INSERT INTO test_transaction(n, t) VALUES(2, 'initial')", "SE");
++	RetCode = odbc_command2("INSERT INTO test_transaction(n, t) VALUES(2, 'initial')", "SE");
+ 	if (RetCode == SQL_ERROR) {
+ 		EndTransaction(SQL_ROLLBACK);
+ 		SWAP_CONN();
+@@ -124,15 +124,15 @@ CheckPhantom(void)
+ 	SWAP_CONN();
+ 
+ 	/* second transaction try to fetch commited row */
+-	Command("SELECT * FROM test_transaction WHERE t = 'initial'");
++	odbc_command("SELECT * FROM test_transaction WHERE t = 'initial'");
+ 
+ 	CHKFetch("S");
+ 	CHKFetch("S");
+ 	CHKFetch("No");
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 	EndTransaction(SQL_ROLLBACK);
+ 	SWAP_CONN();
+-	Command("DELETE test_transaction WHERE n = 2");
++	odbc_command("DELETE test_transaction WHERE n = 2");
+ 	EndTransaction(SQL_COMMIT);
+ 	return 1;
+ }
+@@ -155,7 +155,7 @@ ConnectWithTxn(int txn)
+ {
+ 	global_txn = txn;
+ 	odbc_set_conn_attr = my_attrs;
+-	Connect();
++	odbc_connect();
+ 	odbc_set_conn_attr = NULL;
+ }
+ 
+@@ -167,7 +167,7 @@ Test(int txn, const char *expected)
+ 
+ 	SWAP_CONN();
+ 	if (test_with_connect) {
+-		Disconnect();
++		odbc_disconnect();
+ 		ConnectWithTxn(txn);
+ 		CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 	} else {
+@@ -195,33 +195,33 @@ Test(int txn, const char *expected)
+ int
+ main(int argc, char *argv[])
+ {
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	/* Invalid argument value */
+ 	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ | SQL_TXN_READ_COMMITTED), 0, "E");
+ 	ReadErrorConn();
+ 	if (strcmp(odbc_sqlstate, "HY024") != 0) {
+-		Disconnect();
++		odbc_disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+ 	}
+ 
+ 	/* here we can't use temporary table cause we use two connection */
+-	Command("IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
+-	Command("CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
++	odbc_command("IF OBJECT_ID('test_transaction') IS NOT NULL DROP TABLE test_transaction");
++	odbc_command("CREATE TABLE test_transaction(n NUMERIC(18,0) PRIMARY KEY, t VARCHAR(30))");
+ 
+ 	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+-	Command("INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
++	odbc_command("INSERT INTO test_transaction(n, t) VALUES(1, 'initial')");
+ 
+ #ifdef ENABLE_DEVELOPING
+ 	/* test setting with active transaction "Operation invalid at this time" */
+ 	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E");
+ 	ReadErrorConn();
+ 	if (strcmp(odbc_sqlstate, "HY011") != 0) {
+-		Disconnect();
++		odbc_disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+ 	}
+@@ -229,18 +229,18 @@ main(int argc, char *argv[])
+ 
+ 	EndTransaction(SQL_COMMIT);
+ 
+-	Command("SELECT * FROM test_transaction");
++	odbc_command("SELECT * FROM test_transaction");
+ 
+ 	/* test setting with pending data */
+ 	CHKSetConnectAttr(SQL_ATTR_TXN_ISOLATION, int2ptr(SQL_TXN_REPEATABLE_READ), 0, "E");
+ 	ReadErrorConn();
+ 	if (strcmp(odbc_sqlstate, "HY011") != 0) {
+-		Disconnect();
++		odbc_disconnect();
+ 		fprintf(stderr, "Unexpected success\n");
+ 		return 1;
+ 	}
+ 
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
+ 
+ 	EndTransaction(SQL_COMMIT);
+ 
+@@ -248,7 +248,7 @@ main(int argc, char *argv[])
+ 	/* save this connection and do another */
+ 	SWAP_CONN();
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	CHKSetStmtAttr(SQL_ATTR_QUERY_TIMEOUT, (SQLPOINTER) 2, 0, "S");
+ 	AutoCommit(SQL_AUTOCOMMIT_OFF);
+@@ -258,7 +258,7 @@ main(int argc, char *argv[])
+ 	for (test_with_connect = 0; test_with_connect <= 1; ++test_with_connect) {
+ 		Test(SQL_TXN_READ_UNCOMMITTED, "dirty 1 non repeatable 1 phantom 1");
+ 		Test(SQL_TXN_READ_COMMITTED, "dirty 0 non repeatable 1 phantom 1");
+-		if (db_is_microsoft()) {
++		if (odbc_db_is_microsoft()) {
+ 			Test(SQL_TXN_REPEATABLE_READ, "dirty 0 non repeatable 0 phantom 1");
+ 		} else {
+ 			hide_error = 1;
+@@ -268,7 +268,7 @@ main(int argc, char *argv[])
+ 		Test(SQL_TXN_SERIALIZABLE, "dirty 0 non repeatable 0 phantom 0");
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	SWAP_CONN();
+ 
+@@ -276,8 +276,8 @@ main(int argc, char *argv[])
+ 
+ 	/* Sybase do not accept DROP TABLE during a transaction */
+ 	AutoCommit(SQL_AUTOCOMMIT_ON);
+-	Command("DROP TABLE test_transaction");
++	odbc_command("DROP TABLE test_transaction");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/type.c b/src/odbc/unittests/type.c
+index e401d09..0c2abc2 100644
+--- a/src/odbc/unittests/type.c
++++ b/src/odbc/unittests/type.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: type.c,v 1.8 2007/11/26 18:12:31 freddy77 Exp $";
++static char software_version[] = "$Id: type.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ struct type
+@@ -104,7 +104,7 @@ main(int argc, char **argv)
+ 	SQLLEN lind;
+ 	SQLHDESC desc;
+ 
+-	Connect();
++	odbc_connect();
+ 
+ 	/*
+ 	 * test setting two time a descriptor
+@@ -115,14 +115,14 @@ main(int argc, char **argv)
+ 	/* test C types */
+ 	for (p = types; p->name; ++p) {
+ 		if (SQL_SUCCEEDED
+-		    (SQLBindParameter(Statement, 1, SQL_PARAM_INPUT, p->type, SQL_VARCHAR, (SQLUINTEGER) (-1), 0, buf, 16, &lind))) {
++		    (SQLBindParameter(odbc_stmt, 1, SQL_PARAM_INPUT, p->type, SQL_VARCHAR, (SQLUINTEGER) (-1), 0, buf, 16, &lind))) {
+ 			SQLSMALLINT concise_type, type, code;
+ 			SQLHDESC desc;
+ 
+ 			concise_type = type = code = 0;
+ 
+ 			/* get APD */
+-			SQLGetStmtAttr(Statement, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
++			SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
+ 
+ 			SQLGetDescField(desc, 1, SQL_DESC_TYPE, &type, sizeof(SQLSMALLINT), &ind);
+ 			SQLGetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, &concise_type, sizeof(SQLSMALLINT), &ind);
+@@ -139,7 +139,7 @@ main(int argc, char **argv)
+ 			fprintf(stderr, "Error setting type %d (%s)\n", (int) p->type, p->name);
+ 
+ 			concise_type = p->type;
+-			SQLGetStmtAttr(Statement, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
++			SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_PARAM_DESC, &desc, sizeof(desc), &ind);
+ 			if (SQL_SUCCEEDED
+ 			    (SQLSetDescField(desc, 1, SQL_DESC_CONCISE_TYPE, int2ptr(concise_type), sizeof(SQLSMALLINT))))
+ 			{
+@@ -159,7 +159,7 @@ main(int argc, char **argv)
+ 	printf("\n\n");
+ 
+ 	/* test SQL types */
+-	SQLGetStmtAttr(Statement, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind);
++	SQLGetStmtAttr(odbc_stmt, SQL_ATTR_IMP_PARAM_DESC, &desc, sizeof(desc), &ind);
+ 	for (p = types; p->name; ++p) {
+ 		SQLSMALLINT concise_type = p->type;
+ 
+@@ -181,7 +181,7 @@ main(int argc, char **argv)
+ 		}
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	return result;
+ }
+diff --git a/src/odbc/unittests/typeinfo.c b/src/odbc/unittests/typeinfo.c
+index 7a28c61..223cb7e 100644
+--- a/src/odbc/unittests/typeinfo.c
++++ b/src/odbc/unittests/typeinfo.c
+@@ -1,6 +1,6 @@
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: typeinfo.c,v 1.13 2009/03/17 09:05:47 freddy77 Exp $";
++static char software_version[] = "$Id: typeinfo.c,v 1.14 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void
+@@ -25,14 +25,14 @@ TestName(int index, const char *expected_name)
+ 
+ 	/* retrieve with SQLColAttribute */
+ 	CHKColAttribute(index, SQL_DESC_NAME, name, sizeof(name), &len, NULL, "S");
+-	if (db_is_microsoft())
++	if (odbc_db_is_microsoft())
+ 		NAME_TEST;
+ 	CHKColAttribute(index, SQL_DESC_LABEL, name, sizeof(name), &len, NULL, "S");
+ 	NAME_TEST;
+ }
+ 
+ static void
+-FlushStatement(void)
++Flushodbc_stmt(void)
+ {
+ 	while (CHKFetch("SNo") == SQL_SUCCESS)
+ 		;
+@@ -57,27 +57,27 @@ CheckType(SQLSMALLINT type, SQLSMALLINT expected, const char *string_type, int l
+ 	case SQL_SUCCESS:
+ 		if (expected == SQL_UNKNOWN_TYPE) {
+ 			fprintf(stderr, "Data not expected (type %d - %s) line %d\n", type, string_type, line);
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(1);
+ 		}
+ 		if (expected != out_type) {
+ 			fprintf(stderr, "Got type %d expected %d. Input type %d - %s line %d\n", out_type, expected, type, string_type, line);
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(1);
+ 		}
+ 		break;
+ 	case SQL_NO_DATA:
+ 		if (expected != SQL_UNKNOWN_TYPE) {
+ 			fprintf(stderr, "Data expected. Inpute type %d - %s line %d\n", type, string_type, line);
+-			Disconnect();
++			odbc_disconnect();
+ 			exit(1);
+ 		}
+ 		break;
+ 	}
+ 
+-	SQLFreeStmt(Statement, SQL_UNBIND);
++	SQLFreeStmt(odbc_stmt, SQL_UNBIND);
+ 
+-	FlushStatement();
++	Flushodbc_stmt();
+ }
+ 
+ static void
+@@ -90,15 +90,15 @@ DoTest(int version3)
+ 	int date_time_supported = 0;
+ 	int name_version3;
+ 
+-	use_odbc_version3 = version3;
++	odbc_use_version3 = version3;
+ 	name_version3 = version3;
+-	Connect();
++	odbc_connect();
+ 
+ 	printf("Using ODBC version %d\n", version3 ? 3 : 2);
+ 
+ 	/* test column name */
+ 	/* MS ODBC use always ODBC 3 names even in ODBC 2 mode */
+-	if (!driver_is_freetds())
++	if (!odbc_driver_is_freetds())
+ 		name_version3 = 1;
+ 	CHKGetTypeInfo(SQL_ALL_TYPES, "SI");
+ 	TestName(1, "TYPE_NAME");
+@@ -120,16 +120,16 @@ DoTest(int version3)
+ 	/* TODO test these column for ODBC 3 */
+ 	/* ODBC 3.0 SQL_DATA_TYPE SQL_DATETIME_SUB NUM_PREC_RADIX INTERVAL_PRECISION */
+ 
+-	FlushStatement();
++	Flushodbc_stmt();
+ 
+ 	/* TODO test if SQL_ALL_TYPES returns right numeric type for timestamp */
+ 
+ 	/* numeric type for data */
+ 
+ 	/* test for date/time support */
+-	if (CommandWithResult(Statement, "select cast(getdate() as date)") == SQL_SUCCESS)
++	if (odbc_command_with_result(odbc_stmt, "select cast(getdate() as date)") == SQL_SUCCESS)
+ 		date_time_supported = 1;
+-	SQLCloseCursor(Statement);
++	SQLCloseCursor(odbc_stmt);
+ 
+ #define CHECK_TYPE(in,out) CheckType(in, out, #in, __LINE__)
+ 
+@@ -139,17 +139,17 @@ DoTest(int version3)
+ 	CHECK_TYPE(SQL_DATE, date_time_supported && !version3 ? SQL_DATE : SQL_UNKNOWN_TYPE);
+ 	CHECK_TYPE(SQL_TIME, date_time_supported && !version3 ? SQL_TIME : SQL_UNKNOWN_TYPE);
+ 	/* MS ODBC returns S1004 (HY004), TODO support it */
+-	if (driver_is_freetds() || version3) {
++	if (odbc_driver_is_freetds() || version3) {
+ 		CHECK_TYPE(SQL_TYPE_DATE, date_time_supported && version3 ? SQL_TYPE_DATE : SQL_UNKNOWN_TYPE);
+ 		CHECK_TYPE(SQL_TYPE_TIME, date_time_supported && version3 ? SQL_TYPE_TIME : SQL_UNKNOWN_TYPE);
+ 	}
+ 	/* TODO MS ODBC handle SQL_TIMESTAMP even for ODBC 3 */
+-	if (driver_is_freetds())
++	if (odbc_driver_is_freetds())
+ 		CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_UNKNOWN_TYPE : SQL_TIMESTAMP);
+ 	else
+ 		CHECK_TYPE(SQL_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_TIMESTAMP);
+ 	/* MS ODBC returns S1004 (HY004), TODO support it */
+-	if (driver_is_freetds() || version3) {
++	if (odbc_driver_is_freetds() || version3) {
+ 		CHECK_TYPE(SQL_TYPE_TIMESTAMP, version3 ? SQL_TYPE_TIMESTAMP : SQL_UNKNOWN_TYPE);
+ 	}
+ 
+@@ -166,10 +166,10 @@ DoTest(int version3)
+ 	CHKBindCol(14, SQL_C_SSHORT, &min_scale, 0, &ind6, "SI");
+ 	while (CHKFetch("SNo") == SQL_SUCCESS)
+ 		;
+-	SQLFreeStmt(Statement, SQL_UNBIND);
+-	FlushStatement();
++	SQLFreeStmt(odbc_stmt, SQL_UNBIND);
++	Flushodbc_stmt();
+ 
+-	Disconnect();
++	odbc_disconnect();
+ }
+ 
+ int
+diff --git a/src/odbc/unittests/utf8.c b/src/odbc/unittests/utf8.c
+index d53c986..ba360b0 100755
+--- a/src/odbc/unittests/utf8.c
++++ b/src/odbc/unittests/utf8.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test binding with UTF-8 encoding */
+-static char software_version[] = "$Id: utf8.c,v 1.11 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: utf8.c,v 1.12 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,9 +9,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKAllocEnv(&Environment, "S");
+-	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	CHKAllocConnect(&Connection, "S");
++	CHKAllocEnv(&odbc_env, "S");
++	SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++	CHKAllocConnect(&odbc_conn, "S");
+ }
+ 
+ static void
+@@ -68,7 +68,7 @@ TestBinding(int minimun)
+ 	SQLLEN n_len;
+ 
+ 	sprintf(tmp, "DELETE FROM %s", table_name);
+-	Command(tmp);
++	odbc_command(tmp);
+ 
+ 	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+ 	sprintf(tmp, "INSERT INTO %s VALUES(?,?,?)", table_name);
+@@ -100,7 +100,7 @@ TestBinding(int minimun)
+ 		CheckNoRow(tmp);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ }
+ 
+ int
+@@ -110,37 +110,37 @@ main(int argc, char *argv[])
+ 	const char * const*p;
+ 	SQLINTEGER n;
+ 
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+ 	/* connect string using DSN */
+ 	init_connect();
+-	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", odbc_server, odbc_user, odbc_password, odbc_database);
+ 	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+-	if (!driver_is_freetds()) {
+-		Disconnect();
++	if (!odbc_driver_is_freetds()) {
++		odbc_disconnect();
+ 		printf("Driver is not FreeTDS, exiting\n");
+ 		return 0;
+ 	}
+ 
+-	if (!db_is_microsoft() || db_version_int() < 0x08000000u) {
+-		Disconnect();
++	if (!odbc_db_is_microsoft() || odbc_db_version_int() < 0x08000000u) {
++		odbc_disconnect();
+ 		printf("Test for MSSQL only\n");
+ 		return 0;
+ 	}
+ 
+-	CHKAllocStmt(&Statement, "S");
++	CHKAllocStmt(&odbc_stmt, "S");
+ 
+ 	/* create test table */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+-	Command(tmp);
++	odbc_command(tmp);
+ 	sprintf(tmp, "CREATE TABLE %s (k int, c NCHAR(10), vc NVARCHAR(10))", table_name);
+-	Command(tmp);
++	odbc_command(tmp);
+ 
+ 	/* insert with INSERT statements */
+ 	for (n = 1, p = strings; p[0] && p[1]; p += 2, ++n) {
+ 		sprintf(tmp, "INSERT INTO %s VALUES (%d,N'%s',N'%s')", table_name, (int) n, p[0], p[1]);
+-		Command(tmp);
++		odbc_command(tmp);
+ 	}
+ 
+ 	/* check rows */
+@@ -155,9 +155,9 @@ main(int argc, char *argv[])
+ 
+ 	/* cleanup */
+ 	sprintf(tmp, "IF OBJECT_ID(N'%s') IS NOT NULL DROP TABLE %s", table_name, table_name);
+-	Command(tmp);
++	odbc_command(tmp);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	printf("Done.\n");
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/utf8_2.c b/src/odbc/unittests/utf8_2.c
+index 2eb9e33..d04c0dc 100755
+--- a/src/odbc/unittests/utf8_2.c
++++ b/src/odbc/unittests/utf8_2.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ /* test conversion of Hebrew characters (which have shift sequences) */
+-static char software_version[] = "$Id: utf8_2.c,v 1.8 2008/11/06 15:56:39 freddy77 Exp $";
++static char software_version[] = "$Id: utf8_2.c,v 1.9 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -9,9 +9,9 @@ static void init_connect(void);
+ static void
+ init_connect(void)
+ {
+-	CHKAllocEnv(&Environment, "S");
+-	SQLSetEnvAttr(Environment, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
+-	CHKAllocConnect(&Connection, "S");
++	CHKAllocEnv(&odbc_env, "S");
++	SQLSetEnvAttr(odbc_env, SQL_ATTR_ODBC_VERSION, (SQLPOINTER) (SQL_OV_ODBC3), SQL_IS_UINTEGER);
++	CHKAllocConnect(&odbc_conn, "S");
+ }
+ 
+ static const char * const strings[] = {
+@@ -41,38 +41,38 @@ main(int argc, char *argv[])
+ 	const char * const*p;
+ 	int n;
+ 
+-	if (read_login_info())
++	if (odbc_read_login_info())
+ 		exit(1);
+ 
+ 	/* connect string using DSN */
+ 	init_connect();
+-	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", SERVER, USER, PASSWORD, DATABASE);
++	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;ClientCharset=UTF-8;", odbc_server, odbc_user, odbc_password, odbc_database);
+ 	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+-	if (!driver_is_freetds()) {
+-		Disconnect();
++	if (!odbc_driver_is_freetds()) {
++		odbc_disconnect();
+ 		printf("Driver is not FreeTDS, exiting\n");
+ 		return 0;
+ 	}
+ 
+-	if (!db_is_microsoft() || db_version_int() < 0x08000000u) {
+-		Disconnect();
++	if (!odbc_db_is_microsoft() || odbc_db_version_int() < 0x08000000u) {
++		odbc_disconnect();
+ 		printf("Test for MSSQL only\n");
+ 		return 0;
+ 	}
+ 
+-	CHKAllocStmt(&Statement, "S");
++	CHKAllocStmt(&odbc_stmt, "S");
+ 
+ 	/* create test table */
+-	Command("CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
++	odbc_command("CREATE TABLE #tmpHebrew (i INT, v VARCHAR(10) COLLATE Hebrew_CI_AI)");
+ 
+ 	/* insert with INSERT statements */
+ 	for (n = 0, p = strings_hex; p[n]; ++n) {
+ 		sprintf(tmp, "INSERT INTO #tmpHebrew VALUES(%d, CAST(%s AS NVARCHAR(10)))", n+1, p[n]);
+-		Command(tmp);
++		odbc_command(tmp);
+ 	}
+ 
+ 	/* test conversions in libTDS */
+-	Command("SELECT v FROM #tmpHebrew");
++	odbc_command("SELECT v FROM #tmpHebrew");
+ 
+ 	/* insert with SQLPrepare/SQLBindParameter/SQLExecute */
+ 	CHKBindCol(1, SQL_C_CHAR, out, sizeof(out), &n_len, "S");
+@@ -80,12 +80,12 @@ main(int argc, char *argv[])
+ 		CHKFetch("S");
+ 		if (n_len != strlen(p[n]) || strcmp(p[n], out) != 0) {
+ 			fprintf(stderr, "Wrong row %d %s\n", n, out);
+-			Disconnect();
++			odbc_disconnect();
+ 			return 1;
+ 		}
+ 	}
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 	printf("Done.\n");
+ 	return 0;
+ }
+diff --git a/src/odbc/unittests/warning.c b/src/odbc/unittests/warning.c
+index a7ce5e6..99456b4 100644
+--- a/src/odbc/unittests/warning.c
++++ b/src/odbc/unittests/warning.c
+@@ -14,7 +14,7 @@
+  * inside recordset
+  * Sybase do not return warning but test works the same
+  */
+-static char software_version[] = "$Id: warning.c,v 1.9 2008/12/03 12:55:52 freddy77 Exp $";
++static char software_version[] = "$Id: warning.c,v 1.10 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static const char one_null_with_warning[] = "select max(a) as foo from (select convert(int, null) as a) as test";
+@@ -44,28 +44,28 @@ Test(const char *query)
+ 	 * We check for "NO DM" cause unixODBC till 2.2.11 do not read
+ 	 * errors on SQL_NO_DATA
+ 	 */
+-	if (db_is_microsoft() && tds_no_dm) {
++	if (odbc_db_is_microsoft() && tds_no_dm) {
+ 		SQLCHAR output[256];
+ 
+-		CHKGetDiagRec(SQL_HANDLE_STMT, Statement, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
++		CHKGetDiagRec(SQL_HANDLE_STMT, odbc_stmt, 1, NULL, NULL, output, sizeof(output), NULL, "SI");
+ 		printf("Message: %s\n", (char *) output);
+ 	}
+ 
+-	ResetStatement();
++	odbc_reset_statement();
+ }
+ 
+ int
+ main(void)
+ {
+-	Connect();
++	odbc_connect();
+ 
+-	Command("CREATE TABLE #warning(name varchar(20), value int null)");
+-	Command("INSERT INTO #warning VALUES('a', NULL)");
++	odbc_command("CREATE TABLE #warning(name varchar(20), value int null)");
++	odbc_command("INSERT INTO #warning VALUES('a', NULL)");
+ 
+ 	Test(one_null_with_warning);
+ 	Test("SELECT SUM(value) FROM #warning");
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	printf("Done.\n");
+ 	return 0;
+diff --git a/src/odbc/unittests/wchar.c b/src/odbc/unittests/wchar.c
+index a4f5eef..f31bfb4 100644
+--- a/src/odbc/unittests/wchar.c
++++ b/src/odbc/unittests/wchar.c
+@@ -2,7 +2,7 @@
+ 
+ /* test SQL_C_DEFAULT with NCHAR type */
+ 
+-static char software_version[] = "$Id: wchar.c,v 1.3 2008/11/04 14:46:18 freddy77 Exp $";
++static char software_version[] = "$Id: wchar.c,v 1.4 2010/07/05 09:20:33 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -12,20 +12,20 @@ main(int argc, char *argv[])
+ 	SQLLEN ind;
+ 	int failed = 0;
+ 
+-	use_odbc_version3 = 1;
+-	Connect();
++	odbc_use_version3 = 1;
++	odbc_connect();
+ 
+ 	CHKBindCol(1, SQL_C_DEFAULT, buf, 100, &ind, "S");
+-	Command("SELECT CONVERT(NCHAR(10), 'Pippo 123')");
++	odbc_command("SELECT CONVERT(NCHAR(10), 'Pippo 123')");
+ 
+ 	/* get data */
+ 	memset(buf, 0, sizeof(buf));
+ 	CHKFetch("S");
+ 
+-	SQLMoreResults(Statement);
+-	SQLMoreResults(Statement);
++	SQLMoreResults(odbc_stmt);
++	SQLMoreResults(odbc_stmt);
+ 
+-	Disconnect();
++	odbc_disconnect();
+ 
+ 	if (strcmp(buf, "Pippo 123 ") != 0) {
+ 		fprintf(stderr, "Wrong results '%s'\n", buf);
+
+commit 8a2fbbe387f06284d7427240be9a4b8c70b2212e
+Author: freddy77 <freddy77>
+Date:   Mon Jul 5 14:22:19 2010 +0000
+
+    support SQL_NO_TOTAL from SQLGetData
+
+diff --git a/ChangeLog b/ChangeLog
+index 0139514..fc63bf8 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul  5 16:22:06 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/blob1.c: support SQL_NO_TOTAL from SQLGetData
++
+ Mon Jul  5 11:19:56 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/array.c src/odbc/unittests/array_out.c:
+ 	* src/odbc/unittests/attributes.c src/odbc/unittests/base.c:
+@@ -2636,4 +2639,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3060 2010/07/05 09:20:32 freddy77 Exp $
++$Id: ChangeLog,v 1.3061 2010/07/05 14:22:19 freddy77 Exp $
+diff --git a/src/odbc/unittests/blob1.c b/src/odbc/unittests/blob1.c
+index e2c5de7..338167b 100755
+--- a/src/odbc/unittests/blob1.c
++++ b/src/odbc/unittests/blob1.c
+@@ -5,7 +5,7 @@
+ #include <ctype.h>
+ #include <assert.h>
+ 
+-static char software_version[] = "$Id: blob1.c,v 1.22 2010/07/05 09:20:32 freddy77 Exp $";
++static char software_version[] = "$Id: blob1.c,v 1.23 2010/07/05 14:22:19 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #define NBYTES 10000
+@@ -115,8 +115,10 @@ readBlob(test_info *t)
+ 		total += len;
+ 	}
+ 	printf(">>   total bytes read = %d \n", (int) total);
+-	if (total != 10000)
++	if (total != 10000) {
++		fprintf(stderr, "Wrong buffer length, expected 20000\n");
+ 		failed = 1;
++	}
+ }
+ 
+ static void
+@@ -143,11 +145,15 @@ readBlobAsChar(test_info *t, int step, int wide)
+ 	while (rc == SQL_SUCCESS_WITH_INFO) {
+ 		i++;
+ 		rc = CHKGetData(t->num, type, (SQLPOINTER) buf, (SQLINTEGER) bufsize, &len, "SINo");
++		if (rc == SQL_SUCCESS_WITH_INFO && len == SQL_NO_TOTAL) {
++			len = bufsize - char_len;
++			rc = SQL_SUCCESS;
++		}
+ 		if (rc == SQL_NO_DATA || len <= 0)
+ 			break;
+ 		rc = CHKGetData(t->num, type, (SQLPOINTER) buf, 0, &len2, "SINo");
+ //		printf("out_len %u bufsize %u len2 %u\n", (unsigned) len, (unsigned) bufsize, (unsigned) len2);
+-		if (rc == SQL_SUCCESS_WITH_INFO)
++		if (rc == SQL_SUCCESS_WITH_INFO && len2 != SQL_NO_TOTAL)
+ 			len = len - len2;
+ #if 0
+ 		if (len > (SQLLEN) (bufsize - char_len))
+@@ -170,8 +176,10 @@ readBlobAsChar(test_info *t, int step, int wide)
+ 		total += len;
+ 	}
+ 	printf(">>   total bytes read = %d \n", (int) total);
+-	if (total != 20000)
++	if (total != 20000) {
++		fprintf(stderr, "Wrong buffer length, expected 20000\n");
+ 		failed = 1;
++	}
+ }
+ 
+ static void
+
+commit 3bad8f1339c35e1c2ceb4842f690184be7cb34b1
+Author: freddy77 <freddy77>
+Date:   Mon Jul 5 14:22:40 2010 +0000
+
+    fix for SQLTables and sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index fc63bf8..4ff875b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul  5 16:22:33 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: fix for SQLTables and sybase
++
+ Mon Jul  5 16:22:06 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/blob1.c: support SQL_NO_TOTAL from SQLGetData
+ 
+@@ -2639,4 +2642,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3061 2010/07/05 14:22:19 freddy77 Exp $
++$Id: ChangeLog,v 1.3062 2010/07/05 14:22:40 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 6a4fa48..e13ae7d 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.542 2010/07/05 06:59:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.543 2010/07/05 14:22:40 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -6664,10 +6664,6 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	cbCatalogName = tds_dstr_len(&catalog_name);
+-	cbSchemaName = tds_dstr_len(&schema_name);
+-	cbTableType = tds_dstr_len(&table_type);
+-
+ 	/* support wildcards on catalog (only odbc 3) */
+ 	wildcards = 0;
+ 	if (stmt->dbc->env->attr.odbc_version == SQL_OV_ODBC3 && stmt->dbc->attr.metadata_id == SQL_FALSE &&
+@@ -6675,17 +6671,14 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 		wildcards = 1;
+ 
+ 	proc = "sp_tables ";
+-	if (cbCatalogName > 0) {
++	if (!tds_dstr_isempty(&catalog_name)) {
+ 		if (wildcards) {
+ 			/* if catalog specified and wildcards use sp_tableswc under mssql2k */
+ 			if (TDS_IS_MSSQL(tds) && tds->product_version >= TDS_MS_VER(8,0,0)) {
+ 				proc = "sp_tableswc ";
+-				if (cbSchemaName == SQL_NULL_DATA) {
++				if (tds_dstr_isempty(&schema_name))
+ 					tds_dstr_copy(&schema_name, "%");
+-					cbSchemaName = 1;
+-				}
+ 			}
+-
+ 			/*
+ 			 * TODO support wildcards on catalog even for Sybase
+ 			 * first execute a select name from master..sysdatabases where name like catalog quoted
+@@ -6699,7 +6692,7 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 	}
+ 
+ 	/* fix type if needed quoting it */
+-	if (cbTableType > 0) {
++	if (!tds_dstr_isempty(&table_type)) {
+ 		int to_fix = 0;
+ 		int elements = 0;
+ 		const char *p = tds_dstr_cstr(&table_type);
+@@ -6752,14 +6745,20 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 			}
+ 			*dst = 0;
+ 			tds_dstr_set(&table_type, type);
+-			cbTableType = tds_dstr_len(&table_type);
+ 		}
+ 	}
+ 
+-	retcode =
+-		odbc_stat_execute(stmt _wide, proc, 4, "P@table_name", szTableName, cbTableName, "!P@table_owner", tds_dstr_cstr(&schema_name),
+-				  cbSchemaName, "!P@table_qualifier", tds_dstr_cstr(&catalog_name), cbCatalogName,
+-				  "!@table_type", tds_dstr_cstr(&table_type), cbTableType);
++	/* special case for catalog list */
++	if (strcmp(tds_dstr_cstr(&catalog_name), "%") == 0 && cbTableName <= 0 && cbSchemaName <= 0) {
++		retcode =
++			odbc_stat_execute(stmt _wide, "sp_tables @table_name='', @table_owner='', @table_qualifier='%' ", 0);
++	} else {
++		retcode =
++			odbc_stat_execute(stmt _wide, proc, 4, "P@table_name", szTableName, cbTableName,
++				"!P@table_owner", tds_dstr_cstr(&schema_name), tds_dstr_len(&schema_name),
++				"!P@table_qualifier", tds_dstr_cstr(&catalog_name), tds_dstr_len(&catalog_name),
++				"!@table_type", tds_dstr_cstr(&table_type), tds_dstr_len(&table_type));
++	}
+ 	tds_dstr_free(&schema_name);
+ 	tds_dstr_free(&catalog_name);
+ 	tds_dstr_free(&table_type);
+
+commit 8f853c416da4eb78e5cd3b0942a52b5f2576bbcf
+Author: freddy77 <freddy77>
+Date:   Mon Jul 5 20:49:47 2010 +0000
+
+    improve conversion if wide enabled
+
+diff --git a/ChangeLog b/ChangeLog
+index 4ff875b..a334bb5 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Mon Jul  5 22:49:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c: improve conversion if wide enabled
++
+ Mon Jul  5 16:22:33 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: fix for SQLTables and sybase
+ 
+@@ -2642,4 +2645,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3062 2010/07/05 14:22:40 freddy77 Exp $
++$Id: ChangeLog,v 1.3063 2010/07/05 20:49:47 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 0992ed0..08a73da 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.115 2010/07/03 09:14:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.116 2010/07/05 20:49:50 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -58,8 +58,10 @@ TDS_RCSID(var, "$Id: odbc_util.c,v 1.115 2010/07/03 09:14:36 freddy77 Exp $");
+ static char *odbc_iso2utf(const char *s, int len);
+ static char *odbc_mb2utf(TDS_DBC *dbc, const char *s, int len);
+ static char *odbc_wide2utf(const SQLWCHAR *s, int len);
+-#else
+-static char *odbc_strndup(const char *s, int len)
++#endif
++
++static char *
++odbc_strndup(const char *s, int len)
+ {
+ 	char *out = (char*) malloc(len+1);
+ 	if (!out)
+@@ -68,7 +70,6 @@ static char *odbc_strndup(const char *s, int len)
+ 	out[len] = 0;
+ 	return out;
+ }
+-#endif
+ 
+ static int
+ odbc_set_stmt(TDS_STMT * stmt, char **dest, const ODBC_CHAR *sql, int sql_len _WIDE)
+@@ -257,6 +258,9 @@ odbc_mb2utf(TDS_DBC *dbc, const char *s, int len)
+ 	if (!char_conv)
+ 		return odbc_iso2utf(s, len);
+ 
++	if (char_conv->flags == TDS_ENCODING_MEMCPY)
++		return odbc_strndup(s, len);
++
+ 	il = len;
+ 
+ 	/* allocate needed buffer (+1 is to exclude 0 case) */
+@@ -364,7 +368,7 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 		if (dest && cbBuffer)
+ 			*dest = 0;
+ 		out_len *= SIZEOF_SQLWCHAR;
+-	} else if (1 || !dbc || !dbc->mb_conv) {
++	} else if (!dbc || !dbc->mb_conv) {
+ 		/* to ISO-8859-1 */
+ 		const unsigned char *p = (const unsigned char*) s;
+ 		unsigned char *dest = (unsigned char*) buffer;
+@@ -406,8 +410,8 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 		/* terminate buffer */
+ 		if (dest && cbBuffer)
+ 			*dest = 0;
+-	} else {
+-		/* TODO convert and set correctly length !!! */
++	} else if (dbc->mb_conv->flags == TDS_ENCODING_MEMCPY) {
++		/* to UTF-8 */
+ 		if (len >= cbBuffer) {
+ 			len = cbBuffer - 1;
+ 			result = SQL_SUCCESS_WITH_INFO;
+@@ -417,6 +421,42 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 			memmove((char *) buffer, s, len);
+ 			((char *) buffer)[len] = 0;
+ 		}
++	} else {
++		const char *ib;
++		char *ob;
++		size_t il, ol;
++		TDSICONV *char_conv = dbc->mb_conv;
++
++		il = len;
++		ib = s;
++		ol = cbBuffer;
++		ob = (char *) buffer;
++
++		/* char_conv is only mostly const */
++		memset((TDS_ERRNO_MESSAGE_FLAGS*) &char_conv->suppress, 0, sizeof(char_conv->suppress));
++		char_conv->suppress.e2big = 1;
++		if (tds_iconv(dbc->tds_socket, char_conv, to_client, &ib, &il, &ob, &ol) == (size_t)-1)
++			result = SQL_ERROR;
++		out_len = cbBuffer - ol;
++		while (result != SQL_ERROR && il) {
++			char discard[128];
++			ol = sizeof(discard);
++			ob = discard;
++			char_conv->suppress.e2big = 1;
++			if (tds_iconv(dbc->tds_socket, char_conv, to_client, &ib, &il, &ob, &ol) == (size_t)-1)
++				result = SQL_ERROR;
++			if (out_len < cbBuffer) {
++				int max_copy = out_len - cbBuffer;
++				if (max_copy > sizeof(discard) - ol)
++					max_copy = sizeof(discard) - ol;
++				memcpy(((char *) buffer) + out_len, discard, max_copy);
++			}
++			out_len += sizeof(discard) - ol;
++		}
++		if (out_len >= cbBuffer && result != SQL_ERROR)
++			result = SQL_SUCCESS_WITH_INFO;
++		if (buffer && cbBuffer >= 0)
++			((char *) buffer)[cbBuffer-1 < out_len ? cbBuffer-1:out_len] = 0;
+ 	}
+ #else
+ 	out_len = len;
+
+commit 28658d57e1dcb7b87330e62a55810517d1ca91b5
+Author: freddy77 <freddy77>
+Date:   Tue Jul 6 09:23:43 2010 +0000
+
+    update export symbols
+
+diff --git a/ChangeLog b/ChangeLog
+index a334bb5..046f1e0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Jul  6 11:23:28 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/checkexport.sh vms/odbc_driver_axp.opt:
++	* win32/FreeTDS.def:
++	- update export symbols
++
+ Mon Jul  5 22:49:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c: improve conversion if wide enabled
+ 
+@@ -2645,4 +2650,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3063 2010/07/05 20:49:47 freddy77 Exp $
++$Id: ChangeLog,v 1.3064 2010/07/06 09:23:43 freddy77 Exp $
+diff --git a/src/odbc/checkexport.sh b/src/odbc/checkexport.sh
+index 142cd4e..5b0884a 100755
+--- a/src/odbc/checkexport.sh
++++ b/src/odbc/checkexport.sh
+@@ -1,10 +1,13 @@
+ #!/bin/sh
++
++EXP="nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g'"
++
+ echo Function not exported by VMS driver
+-(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^\(SQL\|ODBC\)'; cat ../../vms/odbc_driver_axp.opt | grep -v '^!' | grep 'SQL' | sed 's,.*SQL\(.*\)=PROCEDURE.*,SQL\1,g') | sort | uniq -u | grep -v ODBCINSTGetProperties
++(eval "$EXP" | grep '^\(SQL\|ODBC\)'; cat ../../vms/odbc_driver_axp.opt | grep -v '^!' | grep 'SQL' | sed 's,.*SQL\(.*\)=PROCEDURE.*,SQL\1,g') | sort | uniq -u | grep -v ODBCINSTGetProperties
+ 
+ echo Function not exported by windows driver
+-(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^\(SQL\|ODBC\)'; cat ../../win32/FreeTDS.def | grep -v '^;' | grep 'SQL' | sed 's,.*SQL,SQL,g' | perl -pe 's,\r,,g') | sort | uniq -u | grep -v ODBCINSTGetProperties
++(eval "$EXP" | grep '^\(SQL\|ODBC\)'; cat ../../win32/FreeTDS.def | grep -v '^;' | grep 'SQL' | sed 's,.*SQL,SQL,g' | perl -pe 's,\r,,g') | sort | uniq -u | grep -v ODBCINSTGetProperties
+ 
+ echo Function not declared as implemented
+-(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^SQL' | perl -pe 'tr/a-z/A-Z/'; cat odbc.c | grep 'X(SQL_API_' | sed 's,.*SQL_API_SQL,SQL,g; s,).*,,g' | sort | uniq) | sort | uniq -u
+-(nm .libs/libtdsodbc.so | grep ' T ' | sed 's,.* T ,,g' | grep '^SQL' | perl -pe 'tr/a-z/A-Z/'; cat odbc.c | grep '_(SQL_API_' | sed 's,.*SQL_API_SQL,SQL,g; s,).*,,g' | sort | uniq) | sort | uniq -d
++(eval "$EXP" | grep '^SQL' | grep -v '[a-z]W$' | perl -pe 'tr/a-z/A-Z/'; cat odbc.c | grep 'X(SQL_API_' | sed 's,.*SQL_API_SQL,SQL,g; s,).*,,g' | sort | uniq) | sort | uniq -u
++(eval "$EXP" | grep '^SQL' | grep -v '[a-z]W$' | perl -pe 'tr/a-z/A-Z/'; cat odbc.c | grep '_(SQL_API_' | sed 's,.*SQL_API_SQL,SQL,g; s,).*,,g' | sort | uniq) | sort | uniq -d
+diff --git a/vms/odbc_driver_axp.opt b/vms/odbc_driver_axp.opt
+index 4a933b6..9b144b9 100644
+--- a/vms/odbc_driver_axp.opt
++++ b/vms/odbc_driver_axp.opt
+@@ -89,7 +89,36 @@ SYMBOL_VECTOR = (SQLAllocConnect=PROCEDURE,-
+ 		SQLStatistics=PROCEDURE,-
+ 		SQLTablePrivileges=PROCEDURE,-
+ 		SQLTables=PROCEDURE,-
+-		SQLTransact=PROCEDURE)
++		SQLTransact=PROCEDURE,-
++		SQLColAttributeW=PROCEDURE,-
++		SQLColumnPrivilegesW=PROCEDURE,-
++		SQLColumnsW=PROCEDURE,-
++		SQLConnectW=PROCEDURE,-
++		SQLDescribeColW=PROCEDURE,-
++		SQLDriverConnectW=PROCEDURE,-
++		SQLErrorW=PROCEDURE,-
++		SQLExecDirectW=PROCEDURE,-
++		SQLForeignKeysW=PROCEDURE,-
++		SQLGetConnectAttrW=PROCEDURE,-
++		SQLGetCursorNameW=PROCEDURE,-
++		SQLGetDescFieldW=PROCEDURE,-
++		SQLGetDescRecW=PROCEDURE,-
++		SQLGetDiagFieldW=PROCEDURE,-
++		SQLGetDiagRecW=PROCEDURE,-
++		SQLGetInfoW=PROCEDURE,-
++		SQLNativeSqlW=PROCEDURE,-
++		SQLPrepareW=PROCEDURE,-
++		SQLPrimaryKeysW=PROCEDURE,-
++		SQLProcedureColumnsW=PROCEDURE,-
++		SQLProceduresW=PROCEDURE,-
++		SQLSetConnectAttrW=PROCEDURE,-
++		SQLSetCursorNameW=PROCEDURE,-
++		SQLSetDescFieldW=PROCEDURE,-
++		SQLSpecialColumnsW=PROCEDURE,-
++		SQLStatisticsW=PROCEDURE,-
++		SQLTablePrivilegesW=PROCEDURE,-
++		SQLTablesW=PROCEDURE)
++)
+ !
+ !		SQLBrowseConnect=PROCEDURE,-
+ !		SQLDescribeParam=PROCEDURE,-
+diff --git a/win32/FreeTDS.def b/win32/FreeTDS.def
+index 11b898f..3b7e3cd 100644
+--- a/win32/FreeTDS.def
++++ b/win32/FreeTDS.def
+@@ -78,3 +78,32 @@ EXPORTS
+ 	ConfigTranslator
+ 	DllRegisterServer
+ 	DllUnregisterServer
++	SQLColAttributeW
++	SQLColumnPrivilegesW
++	SQLColumnsW
++	SQLConnectW
++	SQLDescribeColW
++	SQLDriverConnectW
++	SQLErrorW
++	SQLExecDirectW
++	SQLForeignKeysW
++	SQLGetConnectAttrW
++	SQLGetCursorNameW
++	SQLGetDescFieldW
++	SQLGetDescRecW
++	SQLGetDiagFieldW
++	SQLGetDiagRecW
++	SQLGetInfoW
++	SQLNativeSqlW
++	SQLPrepareW
++	SQLPrimaryKeysW
++	SQLProcedureColumnsW
++	SQLProceduresW
++	SQLSetConnectAttrW
++	SQLSetCursorNameW
++	SQLSetDescFieldW
++	SQLSpecialColumnsW
++	SQLStatisticsW
++	SQLTablePrivilegesW
++	SQLTablesW
++
+
+commit 334849bd280f6f500d3db429306715fae57081f0
+Author: freddy77 <freddy77>
+Date:   Wed Jul 7 13:39:36 2010 +0000
+
+    add missing symbols
+
+diff --git a/ChangeLog b/ChangeLog
+index 046f1e0..75db591 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jul  7 15:39:20 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/check_symbols.txt: add missing symbols
++
+ Tue Jul  6 11:23:28 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/checkexport.sh vms/odbc_driver_axp.opt:
+ 	* win32/FreeTDS.def:
+@@ -2650,4 +2653,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3064 2010/07/06 09:23:43 freddy77 Exp $
++$Id: ChangeLog,v 1.3065 2010/07/07 13:39:36 freddy77 Exp $
+diff --git a/misc/check_symbols.txt b/misc/check_symbols.txt
+index cc67f42..d693968 100644
+--- a/misc/check_symbols.txt
++++ b/misc/check_symbols.txt
+@@ -192,6 +192,7 @@ tds_submit_execdirect
+ tds_submit_execute
+ tds_submit_optioncmd
+ tds_submit_prepare
++tds8_submit_prepexec
+ tds_submit_query
+ tds_submit_query_params
+ tds_submit_queryf
+@@ -219,3 +220,6 @@ tdsdump_off
+ tdsdump_on
+ tdsdump_open
+ !tdserror
++tds_config_boolean
++tds_write_dump
++
+
+commit e9e2025e7b8e166334bff7e6646509f4fd3f5337
+Author: freddy77 <freddy77>
+Date:   Wed Jul 7 13:57:02 2010 +0000
+
+    update script to build tests even for ctlib
+
+diff --git a/ChangeLog b/ChangeLog
+index 75db591..a841c6f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jul  7 15:56:44 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/sybase_tests src/ctlib/unittests/datafmt.c:
++	- update script to build tests even for ctlib
++
+ Wed Jul  7 15:39:20 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/check_symbols.txt: add missing symbols
+ 
+@@ -2653,4 +2657,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3065 2010/07/07 13:39:36 freddy77 Exp $
++$Id: ChangeLog,v 1.3066 2010/07/07 13:57:02 freddy77 Exp $
+diff --git a/misc/sybase_tests b/misc/sybase_tests
+index 1d13d16..2d9a8e9 100755
+--- a/misc/sybase_tests
++++ b/misc/sybase_tests
+@@ -1,7 +1,7 @@
+ #!/bin/bash
+ 
+-# $Id: sybase_tests,v 1.4 2009/04/23 09:41:08 freddy77 Exp $
+-# these commands build dblib tests using Sybase dblib
++# $Id: sybase_tests,v 1.5 2010/07/07 13:57:02 freddy77 Exp $
++# these commands build dblib and ctlib tests using Sybase libraries
+ 
+ errore() {
+ 	echo $* >&2
+@@ -25,22 +25,26 @@ fi
+ # build
+ trap 'echo Error at line $LINENO' ERR
+ set -e
+-make -j4
+-TESTS_ENVIRONMENT=true make -j4 check
++make
+ 
+ # rebuild tests
+-cd src/dblib/unittests
+-if test ! -r Makefile.no_sybase -o Makefile -nt Makefile.no_sybase; then
+-	rm -f Makefile.no_sybase
+-	echo '#include <sybfront.h>' > sqlfront.h
+-	echo '#include <sybdb.h>' > sqldb.h
+-	perl -pi.no_sybase -e "\$_ =~ s{ -I\\\$\\(top_(build|src)dir\\)/include}{ -I$SYBASE/$OCSDIR/include -I\\\$(top_builddir)/include} if (/^(DEFAULT_INCLUDES|AM_CPPFLAGS)\s*=/);
++for dir in src/ctlib/unittests src/ctlib/unittests; do
++	cd $dir
++	if test ! -r Makefile.no_sybase -o Makefile -nt Makefile.no_sybase; then
++		rm -f Makefile.no_sybase
++		echo '#include <sybfront.h>' > sqlfront.h
++		echo '#include <sybdb.h>' > sqldb.h
++		perl -pi.no_sybase -e "\$_ =~ s{ -I\\\$\\(top_(build|src)dir\\)/include}{ -I$SYBASE/$OCSDIR/include -I\\\$(top_builddir)/include} if (/^(DEFAULT_INCLUDES|AM_CPPFLAGS)\s*=/);
+ \$_ =~ s{../libsybdb.la}{-lsybdb -lsybunic} if (/^LIBS\s*=/);
++\$_ =~ s{../libct.la}{-lsybct -lsybcs -lsybblk} if (/^LIBS\s*=/);
+ \$_ =~ s{-L../.libs -R \\\$\\(abs_builddir\\)/../.libs}{-L$SYBASE/$OCSDIR/lib} if (/^AM_LDFLAGS\s*=/);
+ " Makefile
+-	touch Makefile.no_sybase
+-	rm -f *.o *.exe
++		touch Makefile.no_sybase
++		rm -f *.o *.exe
++		make clean
++	fi
+ 	make clean
+-fi
+-TESTS_ENVIRONMENT=true make -j4 check 
++	TESTS_ENVIRONMENT=true make check
++	cd ../../..
++done
+ 
+diff --git a/src/ctlib/unittests/datafmt.c b/src/ctlib/unittests/datafmt.c
+index 473cf1b..c613b07 100644
+--- a/src/ctlib/unittests/datafmt.c
++++ b/src/ctlib/unittests/datafmt.c
+@@ -11,7 +11,7 @@
+ #include <ctpublic.h>
+ #include "common.h"
+ 
+-static char software_version[] = "$Id: datafmt.c,v 1.3 2008/07/15 09:53:00 freddy77 Exp $";
++static char software_version[] = "$Id: datafmt.c,v 1.4 2010/07/07 13:57:02 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ /* Testing: data truncation behavior of ct_fetch */
+@@ -116,7 +116,7 @@ main(int argc, char *argv[])
+ 
+ 			while ((ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count)) != CS_END_DATA) {
+ 
+-				fprintf(stderr, "ct_fetch() row %d returned %s.\n", row_count, cs_prretcode(ret));
++				fprintf(stderr, "ct_fetch() row %d returned %d.\n", row_count, (int) ret);
+ 				addr[copied] = '\0';
+ 				fprintf(stderr, "copied %d bytes: [%s]\n", copied, addr);
+ 				row_count += count;
+
+commit 1dc5170b70d292635378212210981a9e06e30429
+Author: freddy77 <freddy77>
+Date:   Wed Jul 7 14:56:21 2010 +0000
+
+    update automatic test
+
+diff --git a/ChangeLog b/ChangeLog
+index a841c6f..caf8331 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Jul  7 16:56:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/freetds_autobuild: update automatic test
++
+ Wed Jul  7 15:56:44 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/sybase_tests src/ctlib/unittests/datafmt.c:
+ 	- update script to build tests even for ctlib
+@@ -2657,4 +2660,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3066 2010/07/07 13:57:02 freddy77 Exp $
++$Id: ChangeLog,v 1.3067 2010/07/07 14:56:21 freddy77 Exp $
+diff --git a/misc/freetds_autobuild b/misc/freetds_autobuild
+index 238a4fb..46ddc76 100755
+--- a/misc/freetds_autobuild
++++ b/misc/freetds_autobuild
+@@ -174,11 +174,23 @@ perl -pe "\$_ = '' if \$_ =~ /^2:bcp.c: In function 'bcp_colfmt'|^2:bcp.c:\\d+:
+ upload "$OUTDIR/test" '*.html'
+ cd ..
+ 
++# test connection using named port
++save_coverage
++# using tsql directly with grep do not update coverage informations
++echo -e 'select @@version\ngo\nbye' | TDSPORT=ms-sql-s ./src/apps/tsql -S $tSRV -U "$tUID" -P "$tPWD" > out.txt || true
++if grep -q 'Microsoft Corporation' out.txt; then
++	echo "named port ok"
++else
++	echo "named port failed!"
++	restore_coverage
++fi
++rm -f out.txt
++
+ # test domain password and TDSPORT with service name
+ if test "$DOMAIN_UID" != ""; then
+ 	save_coverage
+ 	# using tsql directly with grep do not update coverage informations
+-	echo -e 'select @@version\ngo\nbye' | TDSPORT=ms-sql-s TDSDUMP=stdout ./src/apps/tsql -S $tSRV -U "$DOMAIN_UID" -P "$DOMAIN_PWD" > out.txt || true
++	echo -e 'select @@version\ngo\nbye' | TDSDUMP=stdout ./src/apps/tsql -S $tSRV -U "$DOMAIN_UID" -P "$DOMAIN_PWD" > out.txt || true
+ 	if grep -q 'Microsoft Corporation' out.txt; then
+ 		echo "domain password ok"
+ 	else
+@@ -188,6 +200,7 @@ if test "$DOMAIN_UID" != ""; then
+ 	rm -f out.txt
+ fi
+ 
++# test connection forcing port
+ if test "$MSSQL_PORT" != ""; then
+ 	save_coverage
+ 	# using tsql directly with grep do not update coverage informations
+@@ -201,6 +214,7 @@ if test "$MSSQL_PORT" != ""; then
+ 	rm -f out.txt
+ fi
+ 
++# test connection using instance name
+ if test "$MSSQL_INSTANCE" != ""; then
+ 	save_coverage
+ 	# using tsql directly with grep do not update coverage informations
+
+commit 4fe70ff356bb720080f1eea3dd2754a596fcad07
+Author: freddy77 <freddy77>
+Date:   Thu Jul 8 09:39:34 2010 +0000
+
+    support comma syntax with SERVER parameter
+
+diff --git a/ChangeLog b/ChangeLog
+index caf8331..2f2cfb0 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Thu Jul  8 11:39:24 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/connectparams.c:
++	- support comma syntax with SERVER parameter
++
+ Wed Jul  7 16:56:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/freetds_autobuild: update automatic test
+ 
+@@ -2660,4 +2664,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3067 2010/07/07 14:56:21 freddy77 Exp $
++$Id: ChangeLog,v 1.3068 2010/07/08 09:39:34 freddy77 Exp $
+diff --git a/src/odbc/connectparams.c b/src/odbc/connectparams.c
+index 1f9be9b..0ba1417 100644
+--- a/src/odbc/connectparams.c
++++ b/src/odbc/connectparams.c
+@@ -37,7 +37,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: connectparams.c,v 1.86 2010/02/01 10:16:05 freddy77 Exp $");
++TDS_RCSID(var, "$Id: connectparams.c,v 1.87 2010/07/08 09:39:34 freddy77 Exp $");
+ 
+ #define ODBC_PARAM(p) static const char odbc_param_##p[] = #p;
+ ODBC_PARAM_LIST
+@@ -119,6 +119,12 @@ parse_server(TDS_ERRS *errs, char *server, TDSCONNECTION * connection)
+ 			return 0;
+ 		}
+ 		*p = 0;
++	} else {
++		p = (char *) strchr(server, ',');
++		if (p && atoi(p+1) > 0) {
++			connection->port = atoi(p+1);
++			*p = 0;
++		}
+ 	}
+ 
+ 	if (tds_lookup_host(server, ip) == TDS_SUCCEED)
+
+commit d88b2ab554aa86731f49c71a8d8bc2a14261f950
+Author: freddy77 <freddy77>
+Date:   Fri Jul 9 15:18:22 2010 +0000
+
+    update Windows project files
+
+diff --git a/ChangeLog b/ChangeLog
+index 2f2cfb0..c2b43c4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jul  9 17:17:56 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/config.h win32/msvc6/FreeTDS.dsp win32/msvc6/libTDS.dsp:
++	- update Windows project files
++
+ Thu Jul  8 11:39:24 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/connectparams.c:
+ 	- support comma syntax with SERVER parameter
+@@ -2664,4 +2668,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3068 2010/07/08 09:39:34 freddy77 Exp $
++$Id: ChangeLog,v 1.3069 2010/07/09 15:18:22 freddy77 Exp $
+diff --git a/win32/config.h b/win32/config.h
+index 0a0005c..4a32318 100644
+--- a/win32/config.h
++++ b/win32/config.h
+@@ -10,6 +10,12 @@
+ /* Define to enable extra checks on code */
+ /* #undef ENABLE_EXTRA_CHECKS 1 */
+ 
++/* Defined if --enable-krb5 used and library detected */
++/* #undef ENABLE_KRB5 1 */
++
++/* Define to enable ODBC wide string support */
++#define ENABLE_ODBC_WIDE 1
++
+ /* Define to 1 if you have the <arpa/inet.h> header file. */
+ /* #undef HAVE_ARPA_INET_H */
+ 
+@@ -29,7 +35,7 @@
+    gethostbyaddr_r(). */
+ /* #undef HAVE_FUNC_GETHOSTBYADDR_R_5 */
+ 
+-/* Define to 1 if your system provides the 6-parameter version of
++/* Define to 1 if your system provides the 7-parameter version of
+    gethostbyaddr_r(). */
+ /* #undef HAVE_FUNC_GETHOSTBYADDR_R_7 */
+ 
+@@ -97,6 +103,9 @@
+ /* Define to 1 if you have the <netinet/in.h> header file. */
+ /* #undef HAVE_NETINET_IN_H */
+ 
++/* Define to 1 if you have the <odbcss.h> header file. */
++/* #undef HAVE_ODBCSS_H */
++
+ /* Define to 1 if you have the <paths.h> header file. */
+ /* #undef HAVE_PATHS_H */
+ 
+@@ -106,6 +115,21 @@
+ /* Define to 1 if you have the SQLGetPrivateProfileString function. */
+ #define HAVE_SQLGETPRIVATEPROFILESTRING 1
+ 
++/* Define if sqltypes.h define SQLLEN */
++#define HAVE_SQLLEN 1
++
++/* Define to 1 if the system has the type `SQLROWOFFSET'. */
++/* #undef HAVE_SQLROWOFFSET */
++
++/* Define to 1 if the system has the type `SQLROWSETSIZE'. */
++/* #undef HAVE_SQLROWSETSIZE */
++
++/* Define to 1 if the system has the type `SQLSETPOSIROW'. */
++/* #undef HAVE_SQLSETPOSIROW */
++
++/* Defined if --enable-sspi and SSPI detected */
++#define HAVE_SSPI 1
++
+ /* Define to 1 if you have the <stdint.h> header file. */
+ #define HAVE_STDINT_H 1
+ 
+@@ -170,7 +194,7 @@
+ #define PACKAGE_BUGREPORT ""
+ 
+ /* Define to the full name of this package. */
+-#define PACKAGE_NAME ""
++#define PACKAGE_NAME "FreeTDS"
+ 
+ /* Define to the full name and version of this package. */
+ #define PACKAGE_STRING ""
+@@ -202,6 +226,9 @@
+ /* The size of a `short', as computed by sizeof. */
+ #define SIZEOF_SHORT 2
+ 
++/* The size of `SQLWCHAR', as computed by sizeof. */
++#define SIZEOF_SQLWCHAR 2
++
+ /* The size of a `__int64', as computed by sizeof. */
+ #define SIZEOF___INT64 8
+ 
+diff --git a/win32/msvc6/FreeTDS.dsp b/win32/msvc6/FreeTDS.dsp
+index e17dc79..d14b1b8 100644
+--- a/win32/msvc6/FreeTDS.dsp
++++ b/win32/msvc6/FreeTDS.dsp
+@@ -141,6 +141,10 @@ SOURCE=..\..\src\odbc\sql2tds.c
+ # End Source File
+ # Begin Source File
+ 
++SOURCE=..\..\src\odbc\sqlwchar.c
++# End Source File
++# Begin Source File
++
+ SOURCE=..\winlogin.c
+ # End Source File
+ # Begin Source File
+diff --git a/win32/msvc6/libTDS.dsp b/win32/msvc6/libTDS.dsp
+index 13900b1..1db1154 100644
+--- a/win32/msvc6/libTDS.dsp
++++ b/win32/msvc6/libTDS.dsp
+@@ -183,6 +183,14 @@ SOURCE=..\..\src\tds\vstrbuild.c
+ 
+ SOURCE=..\..\src\tds\write.c
+ # End Source File
++# Begin Source File
++
++SOURCE=..\..\src\tds\sspi.c
++# End Source File
++# Begin Source File
++
++SOURCE=..\..\src\tds\win_mutex.c
++# End Source File
+ # End Group
+ # Begin Group "Header Files"
+ 
+
+commit 60988f2dbc9bc1b35a3ac4489aae341d4d362a16
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 14:25:49 2010 +0000
+
+    added missing declaration
+
+diff --git a/ChangeLog b/ChangeLog
+index c2b43c4..5640c0b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 17 16:25:40 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/config.h: added missing declaration
++
+ Fri Jul  9 17:17:56 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/config.h win32/msvc6/FreeTDS.dsp win32/msvc6/libTDS.dsp:
+ 	- update Windows project files
+@@ -2668,4 +2671,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3069 2010/07/09 15:18:22 freddy77 Exp $
++$Id: ChangeLog,v 1.3070 2010/07/17 14:25:49 freddy77 Exp $
+diff --git a/win32/config.h b/win32/config.h
+index 4a32318..c158760 100644
+--- a/win32/config.h
++++ b/win32/config.h
+@@ -5,13 +5,13 @@
+ /* #undef BSD_COMP */
+ 
+ /* Define to enable work in progress code */
+-/* #undef ENABLE_DEVELOPING 1 */
++/* #undef ENABLE_DEVELOPING */
+ 
+ /* Define to enable extra checks on code */
+-/* #undef ENABLE_EXTRA_CHECKS 1 */
++/* #undef ENABLE_EXTRA_CHECKS */
+ 
+ /* Defined if --enable-krb5 used and library detected */
+-/* #undef ENABLE_KRB5 1 */
++/* #undef ENABLE_KRB5 */
+ 
+ /* Define to enable ODBC wide string support */
+ #define ENABLE_ODBC_WIDE 1
+@@ -205,31 +205,34 @@
+ /* Define to the version of this package. */
+ #define PACKAGE_VERSION ""
+ 
+-/* The size of a `char', as computed by sizeof. */
++/* The size of `char', as computed by sizeof. */
+ #define SIZEOF_CHAR 1
+ 
+-/* The size of a `double', as computed by sizeof. */
++/* The size of `double', as computed by sizeof. */
+ #define SIZEOF_DOUBLE 8
+ 
+-/* The size of a `float', as computed by sizeof. */
++/* The size of `float', as computed by sizeof. */
+ #define SIZEOF_FLOAT 4
+ 
+-/* The size of a `int', as computed by sizeof. */
++/* The size of `int', as computed by sizeof. */
+ #define SIZEOF_INT 4
+ 
+-/* The size of a `long', as computed by sizeof. */
++/* The size of `long', as computed by sizeof. */
+ #define SIZEOF_LONG 4
+ 
+-/* The size of a `long long', as computed by sizeof. */
++/* The size of `long long', as computed by sizeof. */
+ #define SIZEOF_LONG_LONG 0
+ 
+-/* The size of a `short', as computed by sizeof. */
++/* The size of `short', as computed by sizeof. */
+ #define SIZEOF_SHORT 2
+ 
+ /* The size of `SQLWCHAR', as computed by sizeof. */
+ #define SIZEOF_SQLWCHAR 2
+ 
+-/* The size of a `__int64', as computed by sizeof. */
++/* The size of `wchar_t', as computed by sizeof. */
++#define SIZEOF_WCHAR_T 2
++
++/* The size of `__int64', as computed by sizeof. */
+ #define SIZEOF___INT64 8
+ 
+ /* Define to 1 if you want to use SSPI for Win32 */
+
+commit 4e1513d17132e917a183e4218eda27b1a6a244c1
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 14:42:33 2010 +0000
+
+    add some missing functions for wide support
+
+diff --git a/ChangeLog b/ChangeLog
+index 5640c0b..7ed5570 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 17 16:42:27 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: add some missing functions for wide support
++
+ Sat Jul 17 16:25:40 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/config.h: added missing declaration
+ 
+@@ -2671,4 +2674,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3070 2010/07/17 14:25:49 freddy77 Exp $
++$Id: ChangeLog,v 1.3071 2010/07/17 14:42:33 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index e13ae7d..20e879e 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.543 2010/07/05 14:22:40 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.544 2010/07/17 14:42:33 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -4395,6 +4395,17 @@ SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGE
+ 
+ 	return _SQLGetStmtAttr(hstmt, Attribute, Value, BufferLength, StringLength);
+ }
++
++#ifdef ENABLE_ODBC_WIDE
++SQLRETURN ODBC_API
++SQLGetStmtAttrW(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)
++{
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetStmtAttr(%p, %d, %p, %d, %p)\n",
++			hstmt, (int)Attribute, Value, (int)BufferLength, StringLength);
++
++	return _SQLGetStmtAttr(hstmt, Attribute, Value, BufferLength, StringLength);
++}
++#endif
+ #endif
+ 
+ SQLRETURN ODBC_API
+@@ -4788,6 +4799,16 @@ SQLGetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam)
+ 	return _SQLGetConnectAttr(hdbc, (SQLINTEGER) fOption, pvParam, SQL_MAX_OPTION_STRING_LENGTH, NULL _wide0);
+ }
+ 
++#ifdef ENABLE_ODBC_WIDE
++SQLRETURN ODBC_API
++SQLGetConnectOptionW(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam)
++{
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetConnectOptionW(%p, %u, %p)\n", hdbc, fOption, pvParam);
++
++	return _SQLGetConnectAttr(hdbc, (SQLINTEGER) fOption, pvParam, SQL_MAX_OPTION_STRING_LENGTH, NULL, 1);
++}
++#endif
++
+ SQLRETURN ODBC_API
+ SQLGetData(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLSMALLINT fCType, SQLPOINTER rgbValue, SQLLEN cbValueMax, SQLLEN FAR * pcbValue)
+ {
+@@ -6192,6 +6213,15 @@ SQLSetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
+ 	return _SQLSetConnectAttr(hdbc, (SQLINTEGER) fOption, (SQLPOINTER) vParam, SQL_NTS _wide0);
+ }
+ 
++#ifdef ENABLE_ODBC_WIDE
++SQLRETURN ODBC_API
++SQLSetConnectOptionW(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
++{
++	tdsdump_log(TDS_DBG_FUNC, "SQLSetConnectOptionW(%p, %d, %u)\n", hdbc, fOption, (unsigned)vParam);
++	return _SQLSetConnectAttr(hdbc, (SQLINTEGER) fOption, (SQLPOINTER) vParam, SQL_NTS, 1);
++}
++#endif
++
+ static SQLRETURN
+ _SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength)
+ {
+@@ -6483,6 +6513,17 @@ SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINT
+ 
+ 	return _SQLSetStmtAttr(hstmt, Attribute, ValuePtr, StringLength);
+ }
++
++#ifdef ENABLE_ODBC_WIDE
++SQLRETURN ODBC_API
++SQLSetStmtAttrW(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength)
++{
++	tdsdump_log(TDS_DBG_FUNC, "SQLSetStmtAttr(%p, %d, %p, %d)\n",
++			hstmt, (int)Attribute, ValuePtr, (int)StringLength);
++
++	return _SQLSetStmtAttr(hstmt, Attribute, ValuePtr, StringLength);
++}
++#endif
+ #endif
+ 
+ SQLRETURN ODBC_API
+
+commit af932b41e787665cd753a21881e505c4aad44eff
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 14:49:52 2010 +0000
+
+    do not core if no connection, typos
+
+diff --git a/ChangeLog b/ChangeLog
+index 7ed5570..f084bd3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 17 16:49:46 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: do not core if no connection, typos
++
+ Sat Jul 17 16:42:27 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: add some missing functions for wide support
+ 
+@@ -2674,4 +2677,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3071 2010/07/17 14:42:33 freddy77 Exp $
++$Id: ChangeLog,v 1.3072 2010/07/17 14:49:52 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 20e879e..55b5fa3 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.544 2010/07/17 14:42:33 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.545 2010/07/17 14:49:52 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -1531,7 +1531,6 @@ SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLAllocConnect(%p, %p)\n", henv, phdbc);
+ 
+-	odbc_errs_reset(&((TDS_ENV *) henv)->errs);
+ 	return _SQLAllocConnect(henv, phdbc);
+ }
+ 
+@@ -1800,6 +1799,10 @@ SQLCancel(SQLHSTMT hstmt)
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLCancel(%p)\n", hstmt);
+ 
+ 	tds = stmt->dbc->tds_socket;
++	if (!tds) {
++		odbc_errs_add(&stmt->errs, "HY010", NULL);
++		ODBC_RETURN(stmt, SQL_ERROR);
++	}
+ 
+ 	/* FIXME test current statement */
+ 
+@@ -4106,7 +4109,7 @@ _SQLFreeStmt(SQLHSTMT hstmt, SQLUSMALLINT fOption, int force)
+ 		 * FIXME -- otherwise make sure the current statement is complete
+ 		 */
+ 		/* do not close other running query ! */
+-		if (tds->state != TDS_IDLE && tds->state != TDS_DEAD && stmt->dbc->current_statement == stmt) {
++		if (tds && tds->state != TDS_IDLE && tds->state != TDS_DEAD && stmt->dbc->current_statement == stmt) {
+ 			if (tds_send_cancel(tds) == TDS_SUCCEED)
+ 				tds_process_cancel(tds);
+ 		}
+@@ -5087,7 +5090,7 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 	SQLUINTEGER mssql7plus_mask = 0;
+ 	int out_len = -1;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_SQLGetInfo(%p, %u, %p, %d, %p\n", 
++	tdsdump_log(TDS_DBG_FUNC, "_SQLGetInfo(%p, %u, %p, %d, %p)\n",
+ 			dbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue);
+ 
+ #define SIVAL out_len = sizeof(SQLSMALLINT), *((SQLSMALLINT *) rgbInfoValue)
+@@ -5325,7 +5328,7 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 		break;
+ #endif /* ODBCVER >= 0x0300 */
+ 	case SQL_DBMS_NAME:
+-		p = tds->product_name;
++		p = tds ? tds->product_name : NULL;
+ 		break;
+ 	case SQL_DBMS_VER:
+ 		if (!dbc->tds_socket)
+@@ -5846,7 +5849,7 @@ SQLGetInfoW(SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSM
+ {
+ 	INIT_HDBC;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "SQLGetInfo(%p, %d, %p, %d, %p)\n",
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetInfoW(%p, %d, %p, %d, %p)\n",
+ 			hdbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue);
+ 
+ 	ODBC_RETURN(dbc, _SQLGetInfo(dbc, fInfoType, rgbInfoValue, cbInfoValueMax, pcbInfoValue, 1));
+@@ -7136,7 +7139,7 @@ odbc_free_cursor(TDS_STMT * stmt)
+ 	TDSCURSOR *cursor = stmt->cursor;
+ 	TDSSOCKET *tds = stmt->dbc->tds_socket;
+ 
+-	if (cursor) {
++	if (cursor && tds) {
+ 		int error = 1;
+ 		cursor->status.dealloc   = TDS_CURSOR_STATE_REQUESTED;
+ 		/* TODO if fail add to odbc to free later, when we are in idle */
+
+commit ccb02bea262c6ece3c145e5e718a682c5c07fac0
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 17:45:51 2010 +0000
+
+    adding missing wide exports
+
+diff --git a/ChangeLog b/ChangeLog
+index f084bd3..7633474 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 17 19:45:43 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* win32/FreeTDS.def: adding missing wide exports
++
+ Sat Jul 17 16:49:46 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: do not core if no connection, typos
+ 
+@@ -2677,4 +2680,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3072 2010/07/17 14:49:52 freddy77 Exp $
++$Id: ChangeLog,v 1.3073 2010/07/17 17:45:51 freddy77 Exp $
+diff --git a/win32/FreeTDS.def b/win32/FreeTDS.def
+index 3b7e3cd..43bca48 100644
+--- a/win32/FreeTDS.def
++++ b/win32/FreeTDS.def
+@@ -88,20 +88,25 @@ EXPORTS
+ 	SQLExecDirectW
+ 	SQLForeignKeysW
+ 	SQLGetConnectAttrW
++	SQLGetConnectOptionW
+ 	SQLGetCursorNameW
+ 	SQLGetDescFieldW
+ 	SQLGetDescRecW
+ 	SQLGetDiagFieldW
+ 	SQLGetDiagRecW
+ 	SQLGetInfoW
++	SQLGetTypeInfoW = SQLGetTypeInfo
++	SQLGetStmtAttrW
+ 	SQLNativeSqlW
+ 	SQLPrepareW
+ 	SQLPrimaryKeysW
+ 	SQLProcedureColumnsW
+ 	SQLProceduresW
+ 	SQLSetConnectAttrW
++	SQLSetConnectOptionW
+ 	SQLSetCursorNameW
+ 	SQLSetDescFieldW
++	SQLSetStmtAttrW
+ 	SQLSpecialColumnsW
+ 	SQLStatisticsW
+ 	SQLTablePrivilegesW
+
+commit a81b2a0d9faf3d3c85ac88e2bc8ca2f67e843adc
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 18:05:24 2010 +0000
+
+    small optimization
+
+diff --git a/ChangeLog b/ChangeLog
+index 7633474..73c99da 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 17 20:05:19 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/error.c: small optimization
++
+ Sat Jul 17 19:45:43 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* win32/FreeTDS.def: adding missing wide exports
+ 
+@@ -2680,4 +2683,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3073 2010/07/17 17:45:51 freddy77 Exp $
++$Id: ChangeLog,v 1.3074 2010/07/17 18:05:24 freddy77 Exp $
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index f2dd7f6..c8b406e 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.62 2010/07/03 06:57:02 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.63 2010/07/17 18:05:24 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -553,19 +553,18 @@ sqlstate2to3(char *state)
+ 	rank_errors(errs);
+ 
+ 	if (szSqlState) {
+-		if (odbc_ver == SQL_OV_ODBC3)
+-			odbc_set_string(dbc, szSqlState, 24, NULL, errs->errs[numRecord].state3, -1 _wide);
+-		else
+-			odbc_set_string(dbc, szSqlState, 24, NULL, errs->errs[numRecord].state2, -1 _wide);
++		const char *state =
++			(odbc_ver == SQL_OV_ODBC3) ? errs->errs[numRecord].state3 : errs->errs[numRecord].state2;
++		odbc_set_string(dbc, szSqlState, 24, NULL, state, -1 _wide);
+ 	}
+ 
+ 	msg = errs->errs[numRecord].msg;
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "_SQLError: \"%s\"\n", msg);
+-
+ 	if (asprintf(&p, "%s%s", msgprefix, msg) < 0)
+ 		return SQL_ERROR;
+ 
++	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec: \"%s\"\n", p);
++
+ 	result = odbc_set_string(dbc, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1 _wide);
+ 	free(p);
+ 
+
+commit 93bf7f2ab46a5225b38d0426c53f747480bf1ce6
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 19:58:23 2010 +0000
+
+    fix nasty problem with wide encoding (octect/character counts)
+
+diff --git a/ChangeLog b/ChangeLog
+index 73c99da..e21c840 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sat Jul 17 21:58:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
++	* src/odbc/odbc_util.c:
++	- fix nasty problem with wide encoding (octect/character counts)
++
+ Sat Jul 17 20:05:19 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/error.c: small optimization
+ 
+@@ -2683,4 +2688,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3074 2010/07/17 18:05:24 freddy77 Exp $
++$Id: ChangeLog,v 1.3075 2010/07/17 19:58:23 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 8d0d972..5dbe87d 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.123 2010/07/03 09:14:36 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.124 2010/07/17 19:58:24 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -569,19 +569,30 @@ SQLINTEGER odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col);
+ int odbc_get_string_size(int size, ODBC_CHAR * str _WIDE);
+ void odbc_rdbms_version(TDSSOCKET * tds_socket, char *pversion_string);
+ SQLINTEGER odbc_get_param_len(const struct _drecord *drec_axd, const struct _drecord *drec_ixd, const TDS_DESC* axd, unsigned int n_row);
+-DSTR* odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE);
++
++#ifdef ENABLE_ODBC_WIDE
++DSTR* odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str, int flag);
++#define odbc_dstr_copy(dbc, s, len, out) \
++	odbc_dstr_copy_flag(dbc, s, len, sizeof((out)->mb) ? (out) : (out), wide)
++#define odbc_dstr_copy_oct(dbc, s, len, out) \
++	odbc_dstr_copy_flag(dbc, s, len, out, wide|0x20)
++#else
++DSTR* odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str);
++#define odbc_dstr_copy_oct odbc_dstr_copy
++#endif
++
+ 
+ SQLRETURN odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void FAR * pcbBuffer, const char *s, int len, int flag);
+ #ifdef ENABLE_ODBC_WIDE
+-static inline SQLRETURN odbc_set_string(TDS_DBC *dbc, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len _WIDE)
+-{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0|wide); }
+-static inline SQLRETURN odbc_set_string_i(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len _WIDE)
+-{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0x10|wide); }
++#define odbc_set_string(dbc, buf, buf_len, out_len, s, s_len) \
++	odbc_set_string_flag(dbc, sizeof((buf)->mb) ? (buf) : (buf), buf_len, out_len, s, s_len, (wide) | (sizeof(*(out_len)) == sizeof(SQLSMALLINT)?0:0x10))
++#define odbc_set_string_oct(dbc, buf, buf_len, out_len, s, s_len) \
++	odbc_set_string_flag(dbc, buf, buf_len, out_len, s, s_len, (wide) | (sizeof(*(out_len)) == sizeof(SQLSMALLINT)?0x20:0x30))
+ #else
+-static inline SQLRETURN odbc_set_string(TDS_DBC *dbc, SQLPOINTER buffer, SQLSMALLINT cbBuffer, SQLSMALLINT FAR * pcbBuffer, const char *s, int len _WIDE)
+-{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0); }
+-static inline SQLRETURN odbc_set_string_i(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, SQLINTEGER FAR * pcbBuffer, const char *s, int len _WIDE)
+-{ return odbc_set_string_flag(dbc, buffer, cbBuffer, (void FAR*) pcbBuffer, s, len, 0x10); }
++#define odbc_set_string(dbc, buf, buf_len, out_len, s, s_len) \
++	odbc_set_string_flag(dbc, buf, buf_len, out_len, s, s_len, (sizeof(*(out_len)) == sizeof(SQLSMALLINT)?0:0x10))
++#define odbc_set_string_oct(dbc, buf, buf_len, out_len, s, s_len) \
++	odbc_set_string_flag(dbc, buf, buf_len, out_len, s, s_len, (sizeof(*(out_len)) == sizeof(SQLSMALLINT)?0x20:0x30))
+ #endif
+ 
+ SQLSMALLINT odbc_get_concise_sql_type(SQLSMALLINT type, SQLSMALLINT interval);
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index c8b406e..430cfba 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.63 2010/07/17 18:05:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.64 2010/07/17 19:58:24 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -555,7 +555,7 @@ sqlstate2to3(char *state)
+ 	if (szSqlState) {
+ 		const char *state =
+ 			(odbc_ver == SQL_OV_ODBC3) ? errs->errs[numRecord].state3 : errs->errs[numRecord].state2;
+-		odbc_set_string(dbc, szSqlState, 24, NULL, state, -1 _wide);
++		odbc_set_string(dbc, szSqlState, 24, NULL, state, -1);
+ 	}
+ 
+ 	msg = errs->errs[numRecord].msg;
+@@ -565,7 +565,7 @@ sqlstate2to3(char *state)
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDiagRec: \"%s\"\n", p);
+ 
+-	result = odbc_set_string(dbc, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1 _wide);
++	result = odbc_set_string(dbc, szErrorMsg, cbErrorMsgMax, pcbErrorMsg, p, -1);
+ 	free(p);
+ 
+ 	if (pfNativeError)
+@@ -665,7 +665,7 @@ sqlstate2to3(char *state)
+ 			return SQL_ERROR;
+ 
+ 		/* TODO */
+-		return odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, "", 0 _wide);
++		return odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "", 0);
+ 
+ 	case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
+ 		*(SQLINTEGER *) buffer = 0;
+@@ -709,9 +709,9 @@ sqlstate2to3(char *state)
+ 	case SQL_DIAG_CLASS_ORIGIN:
+ 	case SQL_DIAG_SUBCLASS_ORIGIN:
+ 		if (odbc_ver == SQL_OV_ODBC2)
+-			result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, "ISO 9075", -1 _wide);
++			result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "ISO 9075", -1);
+ 		else
+-			result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1 _wide);
++			result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, "ODBC 3.0", -1);
+ 		break;
+ 
+ 	case SQL_DIAG_COLUMN_NUMBER:
+@@ -738,12 +738,12 @@ sqlstate2to3(char *state)
+ 		else
+ 			cplen = 0;
+ 
+-		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, tmp, cplen _wide);
++		result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, tmp, cplen);
+ 		break;
+ 
+ 	case SQL_DIAG_MESSAGE_TEXT:
+ 		msg = errs->errs[numRecord].msg;
+-		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, msg, -1 _wide);
++		result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, -1);
+ 		break;
+ 
+ 	case SQL_DIAG_NATIVE:
+@@ -770,7 +770,7 @@ sqlstate2to3(char *state)
+ 			}
+ 			break;
+ 		}
+-		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, msg, -1 _wide);
++		result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, -1);
+ 		break;
+ 
+ 	case SQL_DIAG_SQLSTATE:
+@@ -779,7 +779,7 @@ sqlstate2to3(char *state)
+ 		else
+ 			msg = errs->errs[numRecord].state2;
+ 
+-		result = odbc_set_string(dbc, buffer, cbBuffer, pcbBuffer, msg, 5 _wide);
++		result = odbc_set_string_oct(dbc, buffer, cbBuffer, pcbBuffer, msg, 5);
+ 		break;
+ 
+ 	default:
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 55b5fa3..13885fb 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.545 2010/07/17 14:49:52 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.546 2010/07/17 19:58:24 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -547,7 +547,7 @@ odbc_prepare(TDS_STMT *stmt)
+ #endif
+ 
+ 	tds_dstr_init(&conn_str);
+-	if (!odbc_dstr_copy(dbc, &conn_str, cbConnStrIn, szConnStrIn _wide)) {
++	if (!odbc_dstr_copy(dbc, &conn_str, cbConnStrIn, szConnStrIn)) {
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+@@ -569,7 +569,7 @@ odbc_prepare(TDS_STMT *stmt)
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+ 
+-	odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, tds_dstr_buf(&conn_str), tds_dstr_len(&conn_str) _wide);
++	odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, tds_dstr_buf(&conn_str), tds_dstr_len(&conn_str));
+ 	tds_dstr_free(&conn_str);
+ 
+ 	/* add login info */
+@@ -600,7 +600,7 @@ odbc_prepare(TDS_STMT *stmt)
+ 		if (!odbc_build_connect_string(&dbc->errs, params, &out))
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 
+-		odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, out, -1 _wide);
++		odbc_set_string(dbc, szConnStrOut, cbConnStrOutMax, pcbConnStrOut, out, -1);
+ 		tdsdump_log(TDS_DBG_INFO1, "connection string is now: %s\n", out);
+ 		free(out);
+ #else
+@@ -978,7 +978,7 @@ SQLMoreResults(SQLHSTMT hstmt)
+ 	}
+ #endif
+ 
+-	if (!odbc_dstr_copy(dbc, &query, cbSqlStrIn, szSqlStrIn _wide)) {
++	if (!odbc_dstr_copy(dbc, &query, cbSqlStrIn, szSqlStrIn)) {
+ 		odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 		ODBC_RETURN(dbc, SQL_ERROR);
+ 	}
+@@ -986,7 +986,7 @@ SQLMoreResults(SQLHSTMT hstmt)
+ 	/* TODO support not null terminated in native_sql */
+ 	native_sql(dbc, tds_dstr_buf(&query));
+ 
+-	ret = odbc_set_string_i(dbc, szSqlStr, cbSqlStrMax, pcbSqlStr, tds_dstr_cstr(&query), -1 _wide);
++	ret = odbc_set_string(dbc, szSqlStr, cbSqlStrMax, pcbSqlStr, tds_dstr_cstr(&query), -1);
+ 
+ 	tds_dstr_free(&query);
+ 
+@@ -1861,7 +1861,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 
+ 	/* data source name */
+ 	if (odbc_get_string_size(cbDSN, szDSN _wide))
+-		odbc_dstr_copy(dbc, &dbc->dsn, cbDSN, szDSN _wide);
++		odbc_dstr_copy(dbc, &dbc->dsn, cbDSN, szDSN);
+ 	else
+ 		tds_dstr_copy(&dbc->dsn, "DEFAULT");
+ 
+@@ -1880,7 +1880,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 	 */
+ 	/* user id */
+ 	if (odbc_get_string_size(cbUID, szUID _wide)) {
+-		if (!odbc_dstr_copy(dbc, &connection->user_name, cbUID, szUID _wide)) {
++		if (!odbc_dstr_copy(dbc, &connection->user_name, cbUID, szUID)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+@@ -1889,7 +1889,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 
+ 	/* password */
+ 	if (szAuthStr && !tds_dstr_isempty(&connection->user_name)) {
+-		if (!odbc_dstr_copy(dbc, &connection->password, cbAuthStr, szAuthStr _wide)) {
++		if (!odbc_dstr_copy(dbc, &connection->password, cbAuthStr, szAuthStr)) {
+ 			tds_free_connection(connection);
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+@@ -1938,7 +1938,7 @@ SQLCancel(SQLHSTMT hstmt)
+ 		SQLRETURN result;
+ 
+ 		/* straight copy column name up to cbColNameMax */
+-		result = odbc_set_string(stmt->dbc, szColName, cbColNameMax, pcbColName, tds_dstr_cstr(&drec->sql_desc_label), -1 _wide);
++		result = odbc_set_string(stmt->dbc, szColName, cbColNameMax, pcbColName, tds_dstr_cstr(&drec->sql_desc_label), -1);
+ 		if (result == SQL_SUCCESS_WITH_INFO) {
+ 			odbc_errs_add(&stmt->errs, "01004", NULL);
+ 			stmt->errs.lastrc = SQL_SUCCESS_WITH_INFO;
+@@ -1986,8 +1986,8 @@ _SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType, SQLP
+ 
+ 	ird = stmt->ird;
+ 
+-#define COUT(src) result = odbc_set_string(stmt->dbc, rgbDesc, cbDescMax, pcbDesc, src ? src : "", -1 _wide);
+-#define SOUT(src) result = odbc_set_string(stmt->dbc, rgbDesc, cbDescMax, pcbDesc, tds_dstr_cstr(&src), -1 _wide);
++#define COUT(src) result = odbc_set_string_oct(stmt->dbc, rgbDesc, cbDescMax, pcbDesc, src ? src : "", -1);
++#define SOUT(src) result = odbc_set_string_oct(stmt->dbc, rgbDesc, cbDescMax, pcbDesc, tds_dstr_cstr(&src), -1);
+ 
+ /* SQLColAttribute returns always attributes using SQLINTEGER */
+ #if ENABLE_EXTRA_CHECKS
+@@ -2436,7 +2436,7 @@ SQLSetDescRec(SQLHDESC hdesc, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLS
+ 
+ 	drec = &desc->records[RecordNumber - 1];
+ 
+-	if ((rc = odbc_set_string(desc_get_dbc(desc), Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1 _wide)) != SQL_SUCCESS)
++	if ((rc = odbc_set_string(desc_get_dbc(desc), Name, BufferLength, StringLength, tds_dstr_cstr(&drec->sql_desc_name), -1)) != SQL_SUCCESS)
+ 		odbc_errs_add(&desc->errs, "01004", NULL);
+ 
+ 	if (Type)
+@@ -2467,8 +2467,8 @@ SQLSetDescRec(SQLHDESC hdesc, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLS
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetDescField(%p, %d, %d, %p, %d, %p)\n", 
+ 			hdesc, icol, fDescType, Value, (int)BufferLength, StringLength);
+ 
+-#define COUT(src) result = odbc_set_string_i(desc_get_dbc(desc), Value, BufferLength, StringLength, src, -1 _wide);
+-#define SOUT(src) result = odbc_set_string_i(desc_get_dbc(desc), Value, BufferLength, StringLength, tds_dstr_cstr(&src), -1 _wide);
++#define COUT(src) result = odbc_set_string_oct(desc_get_dbc(desc), Value, BufferLength, StringLength, src, -1);
++#define SOUT(src) result = odbc_set_string_oct(desc_get_dbc(desc), Value, BufferLength, StringLength, tds_dstr_cstr(&src), -1);
+ 
+ #if ENABLE_EXTRA_CHECKS
+ #define IOUT(type, src) do { \
+@@ -2790,7 +2790,7 @@ SQLSetDescRec(SQLHDESC hdesc, SQLSMALLINT nRecordNumber, SQLSMALLINT nType, SQLS
+ 		result = SQL_ERROR;
+ 		break;
+ 	case SQL_DESC_NAME:
+-		if (!odbc_dstr_copy(desc_get_dbc(desc), &drec->sql_desc_name, BufferLength, Value _wide)) {
++		if (!odbc_dstr_copy_oct(desc_get_dbc(desc), &drec->sql_desc_name, BufferLength, Value)) {
+ 			odbc_errs_add(&desc->errs, "HY001", NULL);
+ 			result = SQL_ERROR;
+ 		}
+@@ -4548,7 +4548,7 @@ SQLRowCount(SQLHSTMT hstmt, SQLLEN FAR * pcrow)
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+ 
+-	if (!odbc_dstr_copy(stmt->dbc, &stmt->cursor_name, cbCursor, szCursor _wide)) {
++	if (!odbc_dstr_copy(stmt->dbc, &stmt->cursor_name, cbCursor, szCursor)) {
+ 		odbc_errs_add(&stmt->errs, "HY001", NULL);
+ 		ODBC_RETURN(stmt, SQL_ERROR);
+ 	}
+@@ -4565,7 +4565,7 @@ SQLRowCount(SQLHSTMT hstmt, SQLLEN FAR * pcrow)
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetCursorName(%p, %p, %d, %p)\n", 
+ 			hstmt, szCursor, cbCursorMax, pcbCursor);
+ 
+-	if ((rc = odbc_set_string(stmt->dbc, szCursor, cbCursorMax, pcbCursor, tds_dstr_cstr(&stmt->cursor_name), -1 _wide)))
++	if ((rc = odbc_set_string(stmt->dbc, szCursor, cbCursorMax, pcbCursor, tds_dstr_cstr(&stmt->cursor_name), -1)))
+ 		odbc_errs_add(&stmt->errs, "01004", NULL);
+ 
+ 	ODBC_RETURN(stmt, rc);
+@@ -4790,7 +4790,7 @@ SQLSetParam(SQLHSTMT hstmt, SQLUSMALLINT ipar, SQLSMALLINT fCType, SQLSMALLINT f
+ 
+ 	assert(p);
+ 
+-	rc = odbc_set_string_i(dbc, Value, BufferLength, StringLength, p, -1 _wide);
++	rc = odbc_set_string_oct(dbc, Value, BufferLength, StringLength, p, -1);
+ 	ODBC_RETURN(dbc, rc);
+ }
+ 
+@@ -5817,7 +5817,7 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 
+ 	/* char data */
+ 	if (p) {
+-		return odbc_set_string(dbc, rgbInfoValue, cbInfoValueMax, pcbInfoValue, p, -1 _wide);
++		return odbc_set_string_oct(dbc, rgbInfoValue, cbInfoValueMax, pcbInfoValue, p, -1);
+ 	} else {
+ 		if (out_len > 0 && pcbInfoValue)
+ 			*pcbInfoValue = out_len;
+@@ -6142,7 +6142,7 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 			SQLRETURN ret;
+ 
+ 			tds_dstr_init(&s);
+-			if (!odbc_dstr_copy(dbc, &s, StringLength, ValuePtr _wide)) {
++			if (!odbc_dstr_copy_oct(dbc, &s, StringLength, ValuePtr)) {
+ 				odbc_errs_add(&dbc->errs, "HY001", NULL);
+ 				ODBC_RETURN(dbc, SQL_ERROR);
+ 			}
+@@ -6184,7 +6184,7 @@ SQLPutData(SQLHSTMT hstmt, SQLPOINTER rgbValue, SQLLEN cbValue)
+ 			odbc_errs_add(&dbc->errs, "HY090", NULL);
+ 			ODBC_RETURN(dbc, SQL_ERROR);
+ 		}
+-		if (odbc_dstr_copy(dbc, &dbc->attr.tracefile, StringLength, (ODBC_CHAR *) ValuePtr _wide))
++		if (odbc_dstr_copy(dbc, &dbc->attr.tracefile, StringLength, (ODBC_CHAR *) ValuePtr))
+ 			ODBC_RETURN_(dbc);
+ 		else {
+ 			odbc_errs_add(&dbc->errs, "HY001", NULL);
+@@ -6698,9 +6698,9 @@ SQLSetStmtOption(SQLHSTMT hstmt, SQLUSMALLINT fOption, SQLULEN vParam)
+ 
+ 	tds = stmt->dbc->tds_socket;
+ 
+-	if (!odbc_dstr_copy(stmt->dbc, &catalog_name, cbCatalogName, szCatalogName _wide)
+-	    || !odbc_dstr_copy(stmt->dbc, &schema_name, cbSchemaName, szSchemaName _wide)
+-	    || !odbc_dstr_copy(stmt->dbc, &table_type, cbTableType, szTableType _wide)) {
++	if (!odbc_dstr_copy(stmt->dbc, &catalog_name, cbCatalogName, szCatalogName)
++	    || !odbc_dstr_copy(stmt->dbc, &schema_name, cbSchemaName, szSchemaName)
++	    || !odbc_dstr_copy(stmt->dbc, &table_type, cbTableType, szTableType)) {
+ 		tds_dstr_free(&schema_name);
+ 		tds_dstr_free(&catalog_name);
+ 		tds_dstr_free(&table_type);
+@@ -7040,9 +7040,9 @@ odbc_stat_execute(TDS_STMT * stmt _WIDE, const char *begin, int nparams, ...)
+ 		if (!convert)
+ 			out = tds_dstr_copyn(&params[i].value, p, param_len);
+ 		else
+-			out = odbc_dstr_copy(stmt->dbc, &params[i].value, param_len, (ODBC_CHAR *) p _wide);
++			out = odbc_dstr_copy(stmt->dbc, &params[i].value, param_len, (ODBC_CHAR *) p);
+ #else
+-		out = odbc_dstr_copy(stmt->dbc, &params[i].value, param_len, (ODBC_CHAR *) p _wide);
++		out = odbc_dstr_copy(stmt->dbc, &params[i].value, param_len, (ODBC_CHAR *) p);
+ #endif
+ 		if (!out) {
+ 			while (--i >= 0)
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 08a73da..dbbfc92 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.116 2010/07/05 20:49:50 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.117 2010/07/17 19:58:25 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -284,11 +284,12 @@ odbc_mb2utf(TDS_DBC *dbc, const char *s, int len)
+ }
+ #endif
+ 
++#ifdef ENABLE_ODBC_WIDE
+ DSTR*
+-odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE)
++odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str, int flag)
+ {
+-#ifdef ENABLE_ODBC_WIDE
+-	int len = odbc_get_string_size(size, str _wide);
++	int wide = flag&1;
++	int len = odbc_get_string_size((flag&0x20) && size >= 0 ? size/SIZEOF_SQLWCHAR : size, str, wide);
+ 	char *buf;
+ 
+ 	if (wide)
+@@ -299,10 +300,14 @@ odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str _WIDE)
+ 		return NULL;
+ 
+ 	return tds_dstr_set(s, buf);
++}
+ #else
++DSTR*
++odbc_dstr_copy(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str)
++{
+ 	return tds_dstr_copyn(s, (const char *) str, odbc_get_string_size(size, str));
+-#endif
+ }
++#endif
+ 
+ /**
+  * Copy a string to client setting size according to ODBC convenction
+@@ -329,7 +334,10 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 		const unsigned char *p = (const unsigned char*) s;
+ 		SQLWCHAR *dest = (SQLWCHAR*) buffer;
+ 
+-		cbBuffer = cbBuffer >= 0 ? cbBuffer / SIZEOF_SQLWCHAR : 0;
++		if (cbBuffer < 0)
++			cbBuffer = 0;
++		if (!(flag&0x20))
++			cbBuffer /= SIZEOF_SQLWCHAR;
+ 		while (len) {
+ 			unsigned char mask;
+ 			unsigned u;
+@@ -367,7 +375,8 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 		/* terminate buffer */
+ 		if (dest && cbBuffer)
+ 			*dest = 0;
+-		out_len *= SIZEOF_SQLWCHAR;
++		if (!(flag&0x20))
++			out_len *= SIZEOF_SQLWCHAR;
+ 	} else if (!dbc || !dbc->mb_conv) {
+ 		/* to ISO-8859-1 */
+ 		const unsigned char *p = (const unsigned char*) s;
+
+commit 1af18dc46ba3cc65f56a57783ed4ce0ea1cf1a54
+Author: freddy77 <freddy77>
+Date:   Sat Jul 17 20:05:52 2010 +0000
+
+    small optimization
+
+diff --git a/ChangeLog b/ChangeLog
+index e21c840..ffc453b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 17 22:05:47 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsbytes.h src/tds/challenge.c: small optimization
++
+ Sat Jul 17 21:58:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsodbc.h src/odbc/error.c src/odbc/odbc.c:
+ 	* src/odbc/odbc_util.c:
+@@ -2688,4 +2691,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3075 2010/07/17 19:58:23 freddy77 Exp $
++$Id: ChangeLog,v 1.3076 2010/07/17 20:05:52 freddy77 Exp $
+diff --git a/include/tdsbytes.h b/include/tdsbytes.h
+index d0a3b87..c4fbc47 100644
+--- a/include/tdsbytes.h
++++ b/include/tdsbytes.h
+@@ -20,7 +20,7 @@
+ #ifndef _tdsbytes_h_
+ #define _tdsbytes_h_
+ 
+-/* $Id: tdsbytes.h,v 1.4 2008/08/18 13:31:26 freddy77 Exp $ */
++/* $Id: tdsbytes.h,v 1.5 2010/07/17 20:05:52 freddy77 Exp $ */
+ 
+ #ifndef _tds_h_
+ #error tds.h must be included before tdsbytes.h
+@@ -109,6 +109,10 @@
+ # undef TDS_PUT_A4BE
+ # define TDS_PUT_A2BE(ptr,val) (*((TDS_USMALLINT*)(ptr)) = (val))
+ # define TDS_PUT_A4BE(ptr,val) (*((TDS_UINT*)(ptr)) = (val))
++# define TDS_HOST2LE(val) TDS_BYTE_SWAP16(val)
++# define TDS_HOST4LE(val) TDS_BYTE_SWAP32(val)
++# define TDS_HOST2BE(val) (val)
++# define TDS_HOST4BE(val) (val)
+ #else
+ # define TDS_GET_A1(ptr)  TDS_GET_A1LE(ptr)
+ # define TDS_GET_UA1(ptr) TDS_GET_UA1LE(ptr)
+@@ -131,6 +135,10 @@
+ # undef TDS_PUT_A4LE
+ # define TDS_PUT_A2LE(ptr,val) (*((TDS_USMALLINT*)(ptr)) = (val))
+ # define TDS_PUT_A4LE(ptr,val) (*((TDS_UINT*)(ptr)) = (val))
++# define TDS_HOST2LE(val) (val)
++# define TDS_HOST4LE(val) (val)
++# define TDS_HOST2BE(val) TDS_BYTE_SWAP16(val)
++# define TDS_HOST4BE(val) TDS_BYTE_SWAP32(val)
+ #endif
+ 
+ /* these platform support unaligned fetch/store */
+diff --git a/src/tds/challenge.c b/src/tds/challenge.c
+index 7422046..d048a90 100644
+--- a/src/tds/challenge.c
++++ b/src/tds/challenge.c
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: challenge.c,v 1.40 2009/09/03 09:25:55 freddy77 Exp $");
++TDS_RCSID(var, "$Id: challenge.c,v 1.41 2010/07/17 20:05:52 freddy77 Exp $");
+ 
+ /**
+  * \ingroup libtds
+@@ -732,9 +732,9 @@ tds_ntlm_get_auth(TDSSOCKET * tds)
+ 	/* built NTLMSSP authentication packet */
+ 	memcpy(packet, ntlm_id, 8);
+ 	/* sequence 1 client -> server */
+-	TDS_PUT_A4LE(packet + 8, 1);
++	TDS_PUT_A4(packet + 8, TDS_HOST4LE(1));
+ 	/* flags */
+-	TDS_PUT_A4LE(packet + 12, 0x08b201);
++	TDS_PUT_A4(packet + 12, TDS_HOST4LE(0x08b201));
+ 
+ 	/* domain info */
+ 	TDS_PUT_A2LE(packet + 16, domain_len);
+
+commit 12b58b60d8e4af49d4dcf167488cf3c7d81709b3
+Author: freddy77 <freddy77>
+Date:   Sun Jul 18 06:45:00 2010 +0000
+
+    wrong logic converting octect <-> character count
+
+diff --git a/ChangeLog b/ChangeLog
+index ffc453b..e277958 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Jul 18 08:44:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c:
++	- wrong logic converting octect <-> character count
++
+ Sat Jul 17 22:05:47 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsbytes.h src/tds/challenge.c: small optimization
+ 
+@@ -2691,4 +2695,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3076 2010/07/17 20:05:52 freddy77 Exp $
++$Id: ChangeLog,v 1.3077 2010/07/18 06:45:00 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index dbbfc92..1b850c3 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.117 2010/07/17 19:58:25 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.118 2010/07/18 06:45:00 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -336,7 +336,7 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 
+ 		if (cbBuffer < 0)
+ 			cbBuffer = 0;
+-		if (!(flag&0x20))
++		if (flag&0x20)
+ 			cbBuffer /= SIZEOF_SQLWCHAR;
+ 		while (len) {
+ 			unsigned char mask;
+@@ -375,7 +375,7 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 		/* terminate buffer */
+ 		if (dest && cbBuffer)
+ 			*dest = 0;
+-		if (!(flag&0x20))
++		if (flag&0x20)
+ 			out_len *= SIZEOF_SQLWCHAR;
+ 	} else if (!dbc || !dbc->mb_conv) {
+ 		/* to ISO-8859-1 */
+
+commit 2088561aac50d014338227bcccc9d04406ccf781
+Author: freddy77 <freddy77>
+Date:   Sun Jul 18 06:45:23 2010 +0000
+
+    update driver version
+
+diff --git a/ChangeLog b/ChangeLog
+index e277958..498926b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jul 18 08:45:14 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c: update driver version
++
+ Sun Jul 18 08:44:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c:
+ 	- wrong logic converting octect <-> character count
+@@ -2695,4 +2698,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3077 2010/07/18 06:45:00 freddy77 Exp $
++$Id: ChangeLog,v 1.3078 2010/07/18 06:45:23 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 13885fb..0e5469c 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.546 2010/07/17 19:58:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.547 2010/07/18 06:45:23 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -5365,7 +5365,7 @@ _SQLGetInfo(TDS_DBC * dbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLS
+ 		p = "libtdsodbc.so";
+ 		break;
+ 	case SQL_DRIVER_ODBC_VER:
+-		p = "03.00";
++		p = "03.50";
+ 		break;
+ 	case SQL_DRIVER_VER:
+ 		/* TODO check ##.##.#### format */
+
+commit c4df2e181dd1c7f07e821edbf741b31679b7bd1d
+Author: freddy77 <freddy77>
+Date:   Sun Jul 18 07:26:24 2010 +0000
+
+    add some checks
+
+diff --git a/ChangeLog b/ChangeLog
+index 498926b..cd98157 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jul 18 09:26:18 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c: add some checks
++
+ Sun Jul 18 08:45:14 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c: update driver version
+ 
+@@ -2698,4 +2701,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3078 2010/07/18 06:45:23 freddy77 Exp $
++$Id: ChangeLog,v 1.3079 2010/07/18 07:26:24 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 1b850c3..7edd8e7 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.118 2010/07/18 06:45:00 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.119 2010/07/18 07:26:24 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -153,6 +153,7 @@ odbc_iso2utf(const char *s, int len)
+ 	int i, o_len = len + 1;
+ 	char *out, *p;
+ 
++	assert(s && len >= 0);
+ 	for (i = 0; i < len; ++i)
+ 		if ((s[i] & 0x80) != 0)
+ 			++o_len;
+@@ -170,6 +171,7 @@ odbc_iso2utf(const char *s, int len)
+ 		}
+ 	}
+ 	*p = 0;
++	assert(p+1-out <= o_len);
+ 	return out;
+ }
+ 
+@@ -184,6 +186,7 @@ odbc_wide2utf(const SQLWCHAR *s, int len)
+ # define MASK(n) ((0xffffu << (n)) & 0xffffu)
+ #endif
+ 
++	assert(len >= 0 && (s || len == 0));
+ 	for (i = 0; i < len; ++i) {
+ 		if ((s[i] & MASK(7)) == 0)
+ 			continue;
+@@ -242,6 +245,7 @@ odbc_wide2utf(const SQLWCHAR *s, int len)
+ 		*p++ = 0x80 | (0x3f & u);
+ 	}
+ 	*p = 0;
++	assert(p+1-out <= o_len);
+ 	return out;
+ }
+ 
+@@ -265,6 +269,7 @@ odbc_mb2utf(TDS_DBC *dbc, const char *s, int len)
+ 
+ 	/* allocate needed buffer (+1 is to exclude 0 case) */
+ 	ol = il * char_conv->server_charset.max_bytes_per_char / char_conv->client_charset.min_bytes_per_char + 1;
++	assert(ol > 0);
+ 	buf = (char *) malloc(ol);
+ 	if (!buf)
+ 		return NULL;
+@@ -324,6 +329,9 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ {
+ 	SQLRETURN result = SQL_SUCCESS;
+ 	int out_len = 0;
++#ifndef NDEBUG
++	size_t initial_size;
++#endif
+ 
+ 	if (len < 0)
+ 		len = strlen(s);
+@@ -338,6 +346,9 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 			cbBuffer = 0;
+ 		if (flag&0x20)
+ 			cbBuffer /= SIZEOF_SQLWCHAR;
++#ifndef NDEBUG
++		initial_size = cbBuffer;
++#endif
+ 		while (len) {
+ 			unsigned char mask;
+ 			unsigned u;
+@@ -373,8 +384,12 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 			result = SQL_SUCCESS_WITH_INFO;
+ 		}
+ 		/* terminate buffer */
+-		if (dest && cbBuffer)
+-			*dest = 0;
++		assert(dest == NULL || dest-(SQLWCHAR*) buffer == out_len);
++		if (dest && cbBuffer) {
++			*dest++ = 0;
++			assert(dest-(SQLWCHAR*) buffer <= initial_size);
++		}
++		assert(dest == NULL || dest-(SQLWCHAR*) buffer <= initial_size);
+ 		if (flag&0x20)
+ 			out_len *= SIZEOF_SQLWCHAR;
+ 	} else if (!dbc || !dbc->mb_conv) {
+@@ -382,6 +397,10 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 		const unsigned char *p = (const unsigned char*) s;
+ 		unsigned char *dest = (unsigned char*) buffer;
+ 
++		assert(cbBuffer >= 0);
++#ifndef NDEBUG
++		initial_size = cbBuffer;
++#endif
+ 		while (len) {
+ 			unsigned char mask;
+ 			unsigned u;
+@@ -416,9 +435,13 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ 			}
+ 			result = SQL_SUCCESS_WITH_INFO;
+ 		}
++		assert(dest == NULL || dest-(unsigned char*) buffer == out_len);
+ 		/* terminate buffer */
+-		if (dest && cbBuffer)
+-			*dest = 0;
++		if (dest && cbBuffer) {
++			*dest++ = 0;
++			assert(dest-(unsigned char*) buffer <= initial_size);
++		}
++		assert(dest == NULL || dest-(unsigned char*) buffer <= initial_size);
+ 	} else if (dbc->mb_conv->flags == TDS_ENCODING_MEMCPY) {
+ 		/* to UTF-8 */
+ 		if (len >= cbBuffer) {
+
+commit 5389464dfd7a2fba8c1947ea7ea07fa0360dfe08
+Author: freddy77 <freddy77>
+Date:   Mon Jul 19 10:06:07 2010 +0000
+
+    applied patch from Shatam Bhattacharya for blk_rowxfer
+
+diff --git a/ChangeLog b/ChangeLog
+index cd98157..a49531b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jul 19 12:05:46 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/blk.c:
++	- applied patch from Shatam Bhattacharya for blk_rowxfer
++
+ Sun Jul 18 09:26:18 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c: add some checks
+ 
+@@ -2701,4 +2705,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3079 2010/07/18 07:26:24 freddy77 Exp $
++$Id: ChangeLog,v 1.3080 2010/07/19 10:06:07 freddy77 Exp $
+diff --git a/src/ctlib/blk.c b/src/ctlib/blk.c
+index b061b16..0818fed 100644
+--- a/src/ctlib/blk.c
++++ b/src/ctlib/blk.c
+@@ -1,5 +1,5 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+- * Copyright (C) 1998-2004, 2005  Brian Bruns, Bill Thompson
++ * Copyright (C) 1998-2004, 2005, 2010  Brian Bruns, Bill Thompson
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -38,7 +38,7 @@
+ #include "ctlib.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: blk.c,v 1.52 2009/06/09 08:55:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: blk.c,v 1.53 2010/07/19 10:06:07 freddy77 Exp $");
+ 
+ static void _blk_null_error(TDSBCPINFO *bcpinfo, int index, int offset);
+ static int _blk_get_col_data(TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
+@@ -435,11 +435,9 @@ blk_rowdrop(SRV_PROC * srvproc, CS_BLK_ROW * row)
+ CS_RETCODE
+ blk_rowxfer(CS_BLKDESC * blkdesc)
+ {
+-	CS_INT row_count = 1;
+-
+ 	tdsdump_log(TDS_DBG_FUNC, "blk_rowxfer(%p)\n", blkdesc);
+ 
+-	return blk_rowxfer_mult(blkdesc, &row_count);
++	return blk_rowxfer_mult(blkdesc, NULL);
+ }
+ 
+ CS_RETCODE
+
+commit 56c22660f61b6d05297fab819820dd59b0f109e5
+Author: freddy77 <freddy77>
+Date:   Mon Jul 19 11:52:15 2010 +0000
+
+    fix connect test for windows
+
+diff --git a/ChangeLog b/ChangeLog
+index a49531b..e4616d3 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Mon Jul 19 13:51:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/Makefile.am src/odbc/unittests/connect.c:
++	- fix connect test for windows
++
+ Mon Jul 19 12:05:46 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/blk.c:
+ 	- applied patch from Shatam Bhattacharya for blk_rowxfer
+@@ -2705,4 +2709,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3080 2010/07/19 10:06:07 freddy77 Exp $
++$Id: ChangeLog,v 1.3081 2010/07/19 11:52:15 freddy77 Exp $
+diff --git a/src/odbc/unittests/Makefile.am b/src/odbc/unittests/Makefile.am
+index 8675be9..f38b57b 100644
+--- a/src/odbc/unittests/Makefile.am
++++ b/src/odbc/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.82 2010/03/02 15:41:37 freddy77 Exp $
++# $Id: Makefile.am,v 1.83 2010/07/19 11:52:15 freddy77 Exp $
+ TESTS		=	\
+ 			t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) connect$(EXEEXT) print$(EXEEXT)\
+@@ -32,6 +32,7 @@ t0002_SOURCES	=	t0002.c common.c common.h
+ t0003_SOURCES	=	t0003.c common.c common.h
+ t0004_SOURCES	=	t0004.c common.c common.h
+ connect_SOURCES	=	connect.c common.c common.h
++connect_LDFLAGS = $(ODBCINSTLIB)
+ print_SOURCES	=	print.c common.c common.h
+ date_SOURCES	=	date.c common.c common.h
+ norowset_SOURCES	= norowset.c common.c common.h
+diff --git a/src/odbc/unittests/connect.c b/src/odbc/unittests/connect.c
+index 99090fa..e0cc2e7 100644
+--- a/src/odbc/unittests/connect.c
++++ b/src/odbc/unittests/connect.c
+@@ -1,7 +1,7 @@
+ #include "common.h"
+ 
+ 
+-static char software_version[] = "$Id: connect.c,v 1.13 2010/07/05 09:20:32 freddy77 Exp $";
++static char software_version[] = "$Id: connect.c,v 1.14 2010/07/19 11:52:15 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static void init_connect(void);
+@@ -13,12 +13,30 @@ init_connect(void)
+ 	CHKAllocConnect(&odbc_conn, "S");
+ }
+ 
++#ifdef _WIN32
++#include <odbcinst.h>
++
++static char *entry = NULL;
++
++static char *
++get_entry(const char *key)
++{
++	static char buf[256];
++
++	entry = NULL;
++	if (SQLGetPrivateProfileString(odbc_server, key, "", buf, sizeof(buf), "odbc.ini") > 0)
++		entry = buf;
++
++	return entry;
++}
++#endif
++
+ int
+ main(int argc, char *argv[])
+ {
+ 	char tmp[2048];
+ 	SQLSMALLINT len;
+-	int failures = 0;
++	int succeeded = 0;
+ 	int is_freetds = 1;
+ 	SQLRETURN rc;
+ 
+@@ -49,6 +67,7 @@ main(int argc, char *argv[])
+ 	if (!odbc_driver_is_freetds())
+ 		is_freetds = 0;
+ 	odbc_disconnect();
++	++succeeded;
+ 
+ 	if (!is_freetds) {
+ 		printf("Driver is not FreeTDS, exiting\n");
+@@ -61,6 +80,7 @@ main(int argc, char *argv[])
+ 	sprintf(tmp, "DSN=%s;UID=%s;PWD=%s;DATABASE=%s;", odbc_server, odbc_user, odbc_password, odbc_database);
+ 	CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SI");
+ 	odbc_disconnect();
++	++succeeded;
+ 
+ 	/* try connect string using old SERVERNAME specification */
+ 	printf("connect string SERVERNAME connect..\n");
+@@ -72,7 +92,8 @@ main(int argc, char *argv[])
+ 	rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+ 	if (rc == SQL_ERROR) {
+ 		printf("Unable to open data source (ret=%d)\n", rc);
+-		++failures;
++	} else {
++		++succeeded;
+ 	}
+ 	odbc_disconnect();
+ 
+@@ -82,13 +103,30 @@ main(int argc, char *argv[])
+ 	rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
+ 	if (rc == SQL_ERROR) {
+ 		printf("Unable to open data source (ret=%d)\n", rc);
+-		++failures;
++	} else {
++		++succeeded;
+ 	}
+ 	odbc_disconnect();
+ 
++#ifdef _WIN32
++	if (get_entry("SERVER")) {
++		init_connect();
++		sprintf(tmp, "DRIVER=FreeTDS;SERVER=%s;UID=%s;PWD=%s;DATABASE=%s;", entry, odbc_user, odbc_password, odbc_database);
++		if (get_entry("TDS_Version"))
++			sprintf(strchr(tmp, 0), "TDS_Version=%s;", entry);
++		rc = CHKDriverConnect(NULL, (SQLCHAR *) tmp, SQL_NTS, (SQLCHAR *) tmp, sizeof(tmp), &len, SQL_DRIVER_NOPROMPT, "SIE");
++		if (rc == SQL_ERROR) {
++			printf("Unable to open data source (ret=%d)\n", rc);
++		} else {
++			++succeeded;
++		}
++		odbc_disconnect();
++	}
++#endif
++
+ 	/* at least one should success.. */
+-	if (failures > 1) {
+-		ODBC_REPORT_ERROR("Too much failures");
++	if (succeeded < 3) {
++		ODBC_REPORT_ERROR("Too few successes");
+ 		exit(1);
+ 	}
+ 
+
+commit c1c164161063fdc9a5b3b298d62767b78cc18155
+Author: freddy77 <freddy77>
+Date:   Tue Jul 20 07:56:51 2010 +0000
+
+    fix compile using no-gnu compiler
+
+diff --git a/ChangeLog b/ChangeLog
+index e4616d3..7609a57 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 20 09:56:36 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/error.c: fix compile using no-gnu compiler
++
+ Mon Jul 19 13:51:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/Makefile.am src/odbc/unittests/connect.c:
+ 	- fix connect test for windows
+@@ -2709,4 +2712,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3081 2010/07/19 11:52:15 freddy77 Exp $
++$Id: ChangeLog,v 1.3082 2010/07/20 07:56:51 freddy77 Exp $
+diff --git a/src/odbc/error.c b/src/odbc/error.c
+index 430cfba..4a2532d 100644
+--- a/src/odbc/error.c
++++ b/src/odbc/error.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2003-2008  Frediano Ziglio
++ * Copyright (C) 2003-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -44,7 +44,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: error.c,v 1.64 2010/07/17 19:58:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: error.c,v 1.65 2010/07/20 07:56:51 freddy77 Exp $");
+ 
+ static void odbc_errs_pop(struct _sql_errors *errs);
+ static const char *odbc_get_msg(const char *sqlstate);
+@@ -555,7 +555,7 @@ sqlstate2to3(char *state)
+ 	if (szSqlState) {
+ 		const char *state =
+ 			(odbc_ver == SQL_OV_ODBC3) ? errs->errs[numRecord].state3 : errs->errs[numRecord].state2;
+-		odbc_set_string(dbc, szSqlState, 24, NULL, state, -1);
++		odbc_set_string(dbc, szSqlState, 24, (SQLSMALLINT *) NULL, state, -1);
+ 	}
+ 
+ 	msg = errs->errs[numRecord].msg;
+
+commit 3b15983d32305b58581cf7eda4c92d24ac9772fc
+Author: freddy77 <freddy77>
+Date:   Wed Jul 21 05:56:27 2010 +0000
+
+    avoid core if locale not detected
+
+diff --git a/ChangeLog b/ChangeLog
+index 7609a57..11fee4c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Jul 21 07:56:18 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/convert_tds2sql.c src/tds/mem.c:
++	- avoid core if locale not detected
++
+ Tue Jul 20 09:56:36 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/error.c: fix compile using no-gnu compiler
+ 
+@@ -2712,4 +2716,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3082 2010/07/20 07:56:51 freddy77 Exp $
++$Id: ChangeLog,v 1.3083 2010/07/21 05:56:27 freddy77 Exp $
+diff --git a/src/odbc/convert_tds2sql.c b/src/odbc/convert_tds2sql.c
+index 57e3af2..cb07a0e 100644
+--- a/src/odbc/convert_tds2sql.c
++++ b/src/odbc/convert_tds2sql.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.71 2010/07/03 09:14:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: convert_tds2sql.c,v 1.72 2010/07/21 05:56:27 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -70,6 +70,10 @@ odbc_convert_char(TDS_STMT * stmt, TDSCOLUMN * curcol, TDS_CHAR * src, TDS_UINT
+ #ifdef ENABLE_ODBC_WIDE
+ 	} else {
+ 		conv = tds_iconv_get(tds, tds_dstr_cstr(&stmt->dbc->original_charset), conv->server_charset.name);
++		if (!conv)
++			conv = tds_iconv_get(tds, tds_dstr_cstr(&stmt->dbc->original_charset), "ISO-8859-1");
++		if (!conv)
++			conv = tds_iconv_get(tds, "ISO-8859-1", "ISO-8859-1");
+ #endif
+ 	}
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index d5d8b01..f3167c3 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005  Brian Bruns
+- * Copyright (C) 2005-2008 Frediano Ziglio
++ * Copyright (C) 2005-2010 Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.201 2010/06/29 12:07:54 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.202 2010/07/21 05:56:27 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -850,6 +850,16 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 
+ 	if (strtok_r(lc_all, ".", &tok)) {
+ 		char *encoding = strtok_r(NULL, "@", &tok);
++#ifdef _WIN32
++		/* windows give numeric codepage*/
++		if (encoding && atoi(encoding) > 0) {
++			char *p;
++			if (asprintf(&p, "CP%s", encoding) >= 0) {
++				free(encoding);
++				lc_all = encoding = p;
++			}
++		}
++#endif
+ 		if (encoding) {
+ 			if (!tds_dstr_copy(&connection->client_charset, encoding))
+ 				goto Cleanup;
+
+commit adb5f0f1bbf55748312a2ab5fb4f91e3a928639f
+Author: freddy77 <freddy77>
+Date:   Wed Jul 21 20:12:17 2010 +0000
+
+    move setlocale call to applications to avoid global side effects
+
+diff --git a/ChangeLog b/ChangeLog
+index 11fee4c..f09568d 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Jul 21 22:12:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqldb.c src/apps/bsqlodbc.c src/apps/datacopy.c:
++	* src/apps/defncopy.c src/apps/fisql/fisql.c src/apps/freebcp.c:
++	* src/apps/tsql.c src/tds/locale.c src/tds/mem.c:
++	- move setlocale call to applications to avoid global side effects
++
+ Wed Jul 21 07:56:18 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/convert_tds2sql.c src/tds/mem.c:
+ 	- avoid core if locale not detected
+@@ -2716,4 +2722,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3083 2010/07/21 05:56:27 freddy77 Exp $
++$Id: ChangeLog,v 1.3084 2010/07/21 20:12:17 freddy77 Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index c59db09..f54b5d9 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -49,7 +49,7 @@
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.43 2010/06/27 23:58:12 berryc Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.44 2010/07/21 20:12:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+@@ -115,6 +115,8 @@ main(int argc, char *argv[])
+ 	DBPROCESS *dbproc;
+ 	RETCODE erc;
+ 
++	setlocale(LC_ALL, "");
++
+ 	/* Initialize db-lib */
+ 	erc = dbinit();	
+ 	if (erc == FAIL) {
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index 39a0744..603c695 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -50,7 +50,7 @@
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.15 2010/06/27 23:58:12 berryc Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.16 2010/07/21 20:12:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+@@ -223,6 +223,8 @@ main(int argc, char *argv[])
+ 	SQLRETURN erc;
+ 	const char *sql;
+ 
++	setlocale(LC_ALL, "");
++
+ 	memset(&options, 0, sizeof(options));
+ 	options.headers = stderr;
+ 	login = get_login(argc, argv, &options); /* get command-line parameters and call dblogin() */
+diff --git a/src/apps/datacopy.c b/src/apps/datacopy.c
+index d8e8dd7..15c92ac 100644
+--- a/src/apps/datacopy.c
++++ b/src/apps/datacopy.c
+@@ -110,6 +110,8 @@ main(int argc, char **argv)
+ 	DBPROCESS *dbsrc;
+ 	DBPROCESS *dbtarget;
+ 
++	setlocale(LC_ALL, "");
++
+ 	memset(&params, '\0', sizeof(params));
+ 
+ 	if (process_parameters(argc, argv, &params) == FALSE) {
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index 2d04824..cb1a579 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -87,7 +87,7 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.21 2010/06/27 23:58:12 berryc Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.22 2010/07/21 20:12:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+@@ -143,6 +143,8 @@ main(int argc, char *argv[])
+ 	RETCODE erc;
+ 	int i, nrows;
+ 
++	setlocale(LC_ALL, "");
++
+ #ifdef __VMS
+         /* Convert VMS-style arguments to Unix-style */
+         parse_vms_args(&argc, &argv);
+diff --git a/src/apps/fisql/fisql.c b/src/apps/fisql/fisql.c
+index 3c2d0a9..ef300c2 100644
+--- a/src/apps/fisql/fisql.c
++++ b/src/apps/fisql/fisql.c
+@@ -268,6 +268,8 @@ main(int argc, char *argv[])
+ 	int nby;
+ 	char adash;
+ 
++	setlocale(LC_ALL, "");
++
+ #ifdef __VMS
+         /* Convert VMS-style arguments to Unix-style */
+         parse_vms_args(&argc, &argv);
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 7942cab..9af3fa7 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -50,7 +50,7 @@
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.55 2010/06/27 23:58:12 berryc Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.56 2010/07/21 20:12:18 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+@@ -74,6 +74,8 @@ main(int argc, char **argv)
+ 	DBPROCESS *dbproc;
+ 	int ok = FALSE;
+ 
++	setlocale(LC_ALL, "");
++
+ #ifdef __VMS
+         /* Convert VMS-style arguments to Unix-style */
+         parse_vms_args(&argc, &argv);
+diff --git a/src/apps/tsql.c b/src/apps/tsql.c
+index 543bff4..b48640c 100644
+--- a/src/apps/tsql.c
++++ b/src/apps/tsql.c
+@@ -87,7 +87,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: tsql.c,v 1.135 2010/06/27 23:58:12 berryc Exp $");
++TDS_RCSID(var, "$Id: tsql.c,v 1.136 2010/07/21 20:12:18 freddy77 Exp $");
+ 
+ #define TDS_ISSPACE(c) isspace((unsigned char) (c))
+ 
+@@ -675,6 +675,8 @@ main(int argc, char **argv)
+ 		return 1;
+ 	}
+ 
++	setlocale(LC_ALL, "");
++
+ 	/* grab a login structure */
+ 	login = tds_alloc_login();
+ 
+@@ -696,7 +698,6 @@ main(int argc, char **argv)
+ 	tds_set_parent(tds, NULL);
+ 	connection = tds_read_config_info(tds, login, context->locale);
+ 
+-	setlocale(LC_ALL, "");
+ 	locale = setlocale(LC_ALL, NULL);
+ 
+ #if HAVE_LOCALE_CHARSET
+diff --git a/src/tds/locale.c b/src/tds/locale.c
+index 8190f36..fe47b65 100644
+--- a/src/tds/locale.c
++++ b/src/tds/locale.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998-1999  Brian Bruns
+- * Copyright (C) 2005-2007  Frediano Ziglio
++ * Copyright (C) 2005-2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -45,7 +45,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: locale.c,v 1.29 2010/06/27 17:46:43 berryc Exp $");
++TDS_RCSID(var, "$Id: locale.c,v 1.30 2010/07/21 20:12:18 freddy77 Exp $");
+ 
+ 
+ static void tds_parse_locale(const char *option, const char *value, void *param);
+@@ -73,7 +73,6 @@ tds_get_locale(void)
+ 		tds_read_conf_section(in, "default", tds_parse_locale, locale);
+ 
+ #if HAVE_LOCALE_H
+-		setlocale(LC_ALL, "");
+ 		s = setlocale(LC_ALL, NULL);
+ #else
+ 		s = getenv("LANG");
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index f3167c3..de4a355 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.202 2010/07/21 05:56:27 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.203 2010/07/21 20:12:18 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -834,7 +834,6 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 	connection->tds_version = TDS_DEFAULT_VERSION;
+ 	connection->block_size = 0;
+ 
+-	setlocale(LC_ALL, "");
+ #if HAVE_NL_LANGINFO && defined(CODESET)
+ 	charset = nl_langinfo(CODESET);
+ 	if (strcmp(tds_canonical_charset_name(charset), "US-ASCII") == 0)
+
+commit 13ca5a4b9afdfd809d4e38a9ba431144a6837aac
+Author: freddy77 <freddy77>
+Date:   Thu Jul 22 09:55:37 2010 +0000
+
+    make applications compile including missing header
+
+diff --git a/ChangeLog b/ChangeLog
+index f09568d..253a504 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jul 22 11:55:12 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/apps/bsqldb.c src/apps/bsqlodbc.c src/apps/datacopy.c:
++	* src/apps/defncopy.c src/apps/fisql/fisql.c src/apps/freebcp.c:
++	- make applications compile including missing header
++
+ Wed Jul 21 22:12:05 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqldb.c src/apps/bsqlodbc.c src/apps/datacopy.c:
+ 	* src/apps/defncopy.c src/apps/fisql/fisql.c src/apps/freebcp.c:
+@@ -2722,4 +2727,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3084 2010/07/21 20:12:17 freddy77 Exp $
++$Id: ChangeLog,v 1.3085 2010/07/22 09:55:37 freddy77 Exp $
+diff --git a/src/apps/bsqldb.c b/src/apps/bsqldb.c
+index f54b5d9..e9ab043 100644
+--- a/src/apps/bsqldb.c
++++ b/src/apps/bsqldb.c
+@@ -45,11 +45,15 @@
+ #include <limits.h>
+ #endif
+ 
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include <sqlfront.h>
+ #include <sybdb.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqldb.c,v 1.44 2010/07/21 20:12:18 freddy77 Exp $";
++static char software_version[] = "$Id: bsqldb.c,v 1.45 2010/07/22 09:55:37 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifdef _WIN32
+diff --git a/src/apps/bsqlodbc.c b/src/apps/bsqlodbc.c
+index 603c695..3f949ac 100644
+--- a/src/apps/bsqlodbc.c
++++ b/src/apps/bsqlodbc.c
+@@ -45,12 +45,16 @@
+ #include <libgen.h>
+ #endif
+ 
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include "tds_sysdep_public.h"
+ #include <sql.h>
+ #include <sqlext.h>
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: bsqlodbc.c,v 1.16 2010/07/21 20:12:18 freddy77 Exp $";
++static char software_version[] = "$Id: bsqlodbc.c,v 1.17 2010/07/22 09:55:37 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static char * next_query(void);
+diff --git a/src/apps/datacopy.c b/src/apps/datacopy.c
+index 15c92ac..7ad1ddb 100644
+--- a/src/apps/datacopy.c
++++ b/src/apps/datacopy.c
+@@ -50,6 +50,10 @@
+ # endif
+ #endif
+ 
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include <sybfront.h>
+ #include <sybdb.h>
+ 
+diff --git a/src/apps/defncopy.c b/src/apps/defncopy.c
+index cb1a579..82671fd 100644
+--- a/src/apps/defncopy.c
++++ b/src/apps/defncopy.c
+@@ -76,6 +76,10 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #include <libgen.h>
+ #endif
+ 
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include <sqlfront.h>
+ #include <sybdb.h>
+ #ifndef MicrosoftsDbLib
+@@ -87,7 +91,7 @@ int getopt(int argc, const char *argv[], char *optstring);
+ #endif
+ #endif /* MicrosoftsDbLib */
+ 
+-static char software_version[] = "$Id: defncopy.c,v 1.22 2010/07/21 20:12:18 freddy77 Exp $";
++static char software_version[] = "$Id: defncopy.c,v 1.23 2010/07/22 09:55:37 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #ifndef MicrosoftsDbLib
+diff --git a/src/apps/fisql/fisql.c b/src/apps/fisql/fisql.c
+index ef300c2..21717a6 100644
+--- a/src/apps/fisql/fisql.c
++++ b/src/apps/fisql/fisql.c
+@@ -31,6 +31,11 @@
+ #include <readline/readline.h>
+ #include <readline/history.h>
+ #endif
++
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include <sybfront.h>
+ #include <sybdb.h>
+ #include "terminal.h"
+diff --git a/src/apps/freebcp.c b/src/apps/freebcp.c
+index 9af3fa7..10b9219 100644
+--- a/src/apps/freebcp.c
++++ b/src/apps/freebcp.c
+@@ -44,13 +44,17 @@
+ #include <unistd.h>
+ #endif
+ 
++#if HAVE_LOCALE_H
++#include <locale.h>
++#endif
++
+ #include "tds.h"
+ #include "replacements.h"
+ #include <sybfront.h>
+ #include <sybdb.h>
+ #include "freebcp.h"
+ 
+-static char software_version[] = "$Id: freebcp.c,v 1.56 2010/07/21 20:12:18 freddy77 Exp $";
++static char software_version[] = "$Id: freebcp.c,v 1.57 2010/07/22 09:55:37 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ void pusage(void);
+
+commit ff03a1e6d87b727f2ab22c0bf1dc8bfe9bb8b85b
+Author: freddy77 <freddy77>
+Date:   Thu Jul 22 14:11:40 2010 +0000
+
+    fix truncation problem setting an ascii string attribute (like catalog)
+
+diff --git a/ChangeLog b/ChangeLog
+index 253a504..aa0f8cc 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Thu Jul 22 16:11:23 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c:
++	- fix truncation problem setting an ascii string attribute (like
++	  catalog)
++
+ Thu Jul 22 11:55:12 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/apps/bsqldb.c src/apps/bsqlodbc.c src/apps/datacopy.c:
+ 	* src/apps/defncopy.c src/apps/fisql/fisql.c src/apps/freebcp.c:
+@@ -2727,4 +2732,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3085 2010/07/22 09:55:37 freddy77 Exp $
++$Id: ChangeLog,v 1.3086 2010/07/22 14:11:40 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 7edd8e7..a96d410 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.119 2010/07/18 07:26:24 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.120 2010/07/22 14:11:41 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -294,7 +294,7 @@ DSTR*
+ odbc_dstr_copy_flag(TDS_DBC *dbc, DSTR *s, int size, ODBC_CHAR * str, int flag)
+ {
+ 	int wide = flag&1;
+-	int len = odbc_get_string_size((flag&0x20) && size >= 0 ? size/SIZEOF_SQLWCHAR : size, str, wide);
++	int len = odbc_get_string_size((flag&0x21) == 0x21 && size >= 0 ? size/SIZEOF_SQLWCHAR : size, str, wide);
+ 	char *buf;
+ 
+ 	if (wide)
+
+commit 94f88926392ad8021092d5d557f073df4d6168d3
+Author: freddy77 <freddy77>
+Date:   Thu Jul 22 14:24:14 2010 +0000
+
+    fix cursor2 issue
+
+diff --git a/ChangeLog b/ChangeLog
+index aa0f8cc..b3ea9ef 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Jul 22 16:23:52 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/unittests/cursor2.c: fix cursor2 issue
++
+ Thu Jul 22 16:11:23 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c:
+ 	- fix truncation problem setting an ascii string attribute (like
+@@ -2732,4 +2735,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3086 2010/07/22 14:11:40 freddy77 Exp $
++$Id: ChangeLog,v 1.3087 2010/07/22 14:24:14 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0e5469c..78c2773 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.547 2010/07/18 06:45:23 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.548 2010/07/22 14:24:14 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -3190,12 +3190,14 @@ odbc_cursor_execute(TDS_STMT * stmt)
+ 	tds_set_state(tds, TDS_PENDING);
+ 	/* set cursor name for TDS7+ */
+ 	if (ret == TDS_SUCCEED && IS_TDS7_PLUS(tds) && !tds_dstr_isempty(&stmt->cursor_name)) {
+-		ret = tds_process_simple_query(tds);
++		ret = odbc_process_tokens(stmt, TDS_RETURN_MSG|TDS_RETURN_DONE|TDS_STOPAT_ROW|TDS_STOPAT_COMPUTE);
+ 		stmt->row_count = tds->rows_affected;
+ 		stmt->dbc->current_statement = NULL;
+-		if (ret == TDS_SUCCEED && cursor->cursor_id != 0) {
++		if (ret == TDS_CMD_DONE && cursor->cursor_id != 0) {
+ 			ret = tds_cursor_setname(tds, cursor);
+ 			tds_set_state(tds, TDS_PENDING);
++		} else {
++			ret = (ret == TDS_CMD_FAIL) ? TDS_FAIL : TDS_SUCCEED;
+ 		}
+ 		if (!cursor->cursor_id) {
+ 			stmt->cursor = NULL;
+diff --git a/src/odbc/unittests/cursor2.c b/src/odbc/unittests/cursor2.c
+index 141f352..954b833 100644
+--- a/src/odbc/unittests/cursor2.c
++++ b/src/odbc/unittests/cursor2.c
+@@ -5,7 +5,7 @@
+  * 2) Test cursor returns results on language RPCs
+  */
+ 
+-static char software_version[] = "$Id: cursor2.c,v 1.10 2010/07/05 09:20:32 freddy77 Exp $";
++static char software_version[] = "$Id: cursor2.c,v 1.11 2010/07/22 14:24:14 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ int
+@@ -15,11 +15,10 @@ main(int argc, char *argv[])
+ 	unsigned char msg[256];
+ 
+ 	odbc_connect();
++	odbc_check_cursor();
+ 
+ 	odbc_command("CREATE TABLE #cursor2_test (i INT)");
+ 
+-	odbc_check_cursor();
+-
+ 	odbc_reset_statement();
+ 	CHKSetStmtAttr(SQL_ATTR_CURSOR_TYPE, (SQLPOINTER) SQL_CURSOR_DYNAMIC, SQL_IS_INTEGER, "S");
+ 
+@@ -30,7 +29,7 @@ main(int argc, char *argv[])
+ 
+ 
+ 	odbc_reset_statement();
+-	odbc_command_with_result(odbc_stmt, "drop proc sp_test");
++	odbc_command_with_result(odbc_stmt, "if object_id('sp_test') is not null drop proc sp_test");
+ 	odbc_command("create proc sp_test @name varchar(30) as select 0 as pippo select 1 as 'test', @name as 'nome'");
+ 
+ 	odbc_reset_statement();
+
+commit af569192112c0abe1078fc976183264294a67bc9
+Author: freddy77 <freddy77>
+Date:   Fri Jul 23 07:42:25 2010 +0000
+
+    use ird to get column count
+
+diff --git a/ChangeLog b/ChangeLog
+index b3ea9ef..75ae0bf 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jul 23 09:42:11 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/unittests/prepare_results.c: use ird to get column count
++
+ Thu Jul 22 16:23:52 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/unittests/cursor2.c: fix cursor2 issue
+ 
+@@ -2735,4 +2738,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3087 2010/07/22 14:24:14 freddy77 Exp $
++$Id: ChangeLog,v 1.3088 2010/07/23 07:42:25 freddy77 Exp $
+diff --git a/src/odbc/unittests/prepare_results.c b/src/odbc/unittests/prepare_results.c
+index cd18246..888b569 100644
+--- a/src/odbc/unittests/prepare_results.c
++++ b/src/odbc/unittests/prepare_results.c
+@@ -2,39 +2,35 @@
+ 
+ /* Test for data format returned from SQLPrepare */
+ 
+-static char software_version[] = "$Id: prepare_results.c,v 1.12 2010/07/05 09:20:33 freddy77 Exp $";
++static char software_version[] = "$Id: prepare_results.c,v 1.13 2010/07/23 07:42:25 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+-int
+-main(int argc, char *argv[])
++static void
++Test(int use_ird)
+ {
+ 	SQLSMALLINT count, namelen, type, digits, nullable;
+ 	SQLULEN size;
++	SQLHDESC desc;
++	SQLINTEGER ind;
+ 	char name[128];
+ 
+-	odbc_connect();
+-
+-	odbc_command("create table #odbctestdata (i int, c char(20), n numeric(34,12) )");
+-
+-	/* reset state */
+-	odbc_command("select * from #odbctestdata");
+-	SQLFetch(odbc_stmt);
+-	SQLMoreResults(odbc_stmt);
+-
+-	/* test query returns column information for update */
+-	CHKPrepare((SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS, "S");
+-
+-	CHKNumResultCols(&count, "S");
++	/* test query returns column information */
++	CHKPrepare((SQLCHAR *) "select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
+ 
++	SQLNumParams(odbc_stmt, &count);
+ 	if (count != 0) {
+-		fprintf(stderr, "Wrong number of columns returned. Got %d expected 0\n", (int) count);
++		fprintf(stderr, "Wrong number of params returned. Got %d expected 0\n", (int) count);
+ 		exit(1);
+ 	}
+ 
+-	/* test query returns column information */
+-	CHKPrepare((SQLCHAR *) "select * from #odbctestdata select * from #odbctestdata", SQL_NTS, "S");
++	if (use_ird) {
++		/* get IRD */
++		CHKGetStmtAttr(SQL_ATTR_IMP_ROW_DESC, &desc, sizeof(desc), &ind, "S");
+ 
+-	CHKNumResultCols(&count, "S");
++		CHKR(SQLGetDescField, (desc, 0, SQL_DESC_COUNT, &count, sizeof(count), &ind), "S");
++	} else {
++		CHKNumResultCols(&count, "S");
++	}
+ 
+ 	if (count != 3) {
+ 		fprintf(stderr, "Wrong number of columns returned. Got %d expected 3\n", (int) count);
+@@ -61,6 +57,35 @@ main(int argc, char *argv[])
+ 		fprintf(stderr, "wrong column 3 informations (type %d name '%s' size %d)\n", (int) type, name, (int) size);
+ 		exit(1);
+ 	}
++}
++
++int
++main(int argc, char *argv[])
++{
++	SQLSMALLINT count;
++
++	odbc_connect();
++
++	odbc_command("create table #odbctestdata (i int, c char(20), n numeric(34,12) )");
++
++	/* reset state */
++	odbc_command("select * from #odbctestdata");
++	SQLFetch(odbc_stmt);
++	SQLMoreResults(odbc_stmt);
++
++	/* test query returns column information for update */
++	CHKPrepare((SQLCHAR *) "update #odbctestdata set i = 20", SQL_NTS, "S");
++
++	CHKNumResultCols(&count, "S");
++
++	if (count != 0) {
++		fprintf(stderr, "Wrong number of columns returned. Got %d expected 0\n", (int) count);
++		exit(1);
++	}
++
++	Test(0);
++	odbc_reset_statement();
++	Test(1);
+ 
+ 	/* TODO test SQLDescribeParam (when implemented) */
+ 	odbc_command("drop table #odbctestdata");
+
+commit 10b678e6b45405140a929329e28ac051448d3780
+Author: freddy77 <freddy77>
+Date:   Fri Jul 23 13:07:56 2010 +0000
+
+    updated
+
+diff --git a/ChangeLog b/ChangeLog
+index 75ae0bf..41b4527 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jul 23 15:07:21 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* TODO TODO.freddy: updated
++
+ Fri Jul 23 09:42:11 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/unittests/prepare_results.c: use ird to get column count
+ 
+@@ -2738,4 +2741,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3088 2010/07/23 07:42:25 freddy77 Exp $
++$Id: ChangeLog,v 1.3089 2010/07/23 13:07:56 freddy77 Exp $
+diff --git a/TODO b/TODO
+index 89eb4e9..ae78851 100644
+--- a/TODO
++++ b/TODO
+@@ -8,7 +8,7 @@ anyone else can post a patch to SourceForge.
+ In this way we can communicate with each
+ other about the project's priorities and needs.  
+ 
+-To Do List	$Id: TODO,v 1.174 2009/09/03 11:53:47 freddy77 Exp $
++To Do List	$Id: TODO,v 1.175 2010/07/23 13:07:56 freddy77 Exp $
+ ------------
+ 
+ Bug? ML 2007-05-30 "dbsqlexec() never returns" 
+@@ -48,7 +48,7 @@ For future versions (in priority order within library):
+ . retain values used from freetds.conf, so we can report them.
+ . add a way for tsql to report host, port, and TDS version for 
+   the connection it's attempting.  
+-. create "TDSVER=auto": try 8.0, 7.0, 5.0, 4.2 (in that order)?  Must support
++. create "TDSVER=auto": try 7.2, 7.1, 7.0, 5.0, 4.2 (in that order)?  Must support
+   instance names, too, and tsql should report progress in verbose mode.
+   Currently supported using TDSVER=0.0, check for instances, tsql do not say
+   nothing.
+@@ -119,7 +119,6 @@ For future versions (in priority order within library):
+   to store error, cache some errors (truncated output)
+   optimize ODBC_RETURN (remove useless)
+ . handle no termination on odbc_set_string*
+-. *W functions support (wide version, ODBC 3.51)
+ . handle async flags ??
+ . it seems that if statement it's wrong and we issue SQLPrepare on SQLExecute
+   it try to send unprepared dynamic... state on dynamic??
+diff --git a/TODO.freddy b/TODO.freddy
+index 8668fb5..cc823ff 100644
+--- a/TODO.freddy
++++ b/TODO.freddy
+@@ -65,8 +65,6 @@ char, variable and so on
+ 
+ Possibility to lock TDSSOCKET (see odbc, multiple RPCs)
+ 
+-Support Unicode under ODBC, use iso8859-1 by default and large characters
+-
+ If application rebind with compatible types do not prepare twice.
+ Compatible (tds_match_dynamic ??) if:
+ - same query
+
+commit 3697b8214b56bbce34c5461338d9696832f7491c
+Author: freddy77 <freddy77>
+Date:   Sat Jul 24 08:08:09 2010 +0000
+
+    fix rpc test for Sybase
+
+diff --git a/ChangeLog b/ChangeLog
+index 41b4527..c60805b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sat Jul 24 10:08:00 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/unittests/common.c src/dblib/unittests/rpc.sql:
++	- fix rpc test for Sybase
++
+ Fri Jul 23 15:07:21 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* TODO TODO.freddy: updated
+ 
+@@ -2741,4 +2745,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3089 2010/07/23 13:07:56 freddy77 Exp $
++$Id: ChangeLog,v 1.3090 2010/07/24 08:08:09 freddy77 Exp $
+diff --git a/src/dblib/unittests/common.c b/src/dblib/unittests/common.c
+index 45d4534..a353f45 100644
+--- a/src/dblib/unittests/common.c
++++ b/src/dblib/unittests/common.c
+@@ -22,7 +22,7 @@
+ 
+ #include "replacements.h"
+ 
+-static char software_version[] = "$Id: common.c,v 1.40 2010/01/10 14:43:11 freddy77 Exp $";
++static char software_version[] = "$Id: common.c,v 1.41 2010/07/24 08:08:09 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ typedef struct _tag_memcheck_t
+@@ -448,6 +448,7 @@ syb_msg_handler(DBPROCESS * dbproc, DBINT msgno, int msgstate, int severity, cha
+ 			 */
+ 			fprintf(stdout, "%s\n", msgtext);
+ 			fflush(stdout);
++			severity = 0;
+ 		}
+ 	}
+ 
+diff --git a/src/dblib/unittests/rpc.sql b/src/dblib/unittests/rpc.sql
+index a1fb520..9b44f7a 100644
+--- a/src/dblib/unittests/rpc.sql
++++ b/src/dblib/unittests/rpc.sql
+@@ -8,7 +8,7 @@ CREATE PROCEDURE #t0022
+ AS 
+ BEGIN 
+ if @null_input is not NULL begin 
+-	select 'error: should be NULL' as status, @null_input as '@null_input'
++	select 'error: should be NULL' as status, @null_input as 'null_input'
+ 	return -42
+ end else begin
+ 	print 'Good: @null_input is NULL'
+@@ -26,12 +26,12 @@ select distinct convert(varchar(30), name) as 'type'  from systypes
+ where name in ('int', 'char', 'text') 
+ select @nrows = @@rowcount 
+ select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' 
+-select	  @null_input as '@null_input'
+-	, @first_type as '@first_type'
+-	, @nullout as '@nullout'
+-	, @nrows as '@nrows'
+-	, @c as '@c'
+-	, @nv as '@nv'
++select	  @null_input as 'null_input'
++	, @first_type as 'first_type'
++	, @nullout as 'nullout'
++	, @nrows as 'nrows'
++	, @c as 'c'
++	, @nv as 'nv'
+ 	into #parameters
+ select * from #parameters
+ return 42 
+@@ -50,7 +50,7 @@ CREATE PROCEDURE t0022
+ AS 
+ BEGIN 
+ if @null_input is not NULL begin 
+-	select 'error: should be NULL' as status, @null_input as '@null_input'
++	select 'error: should be NULL' as status, @null_input as 'null_input'
+ 	return -42
+ end else begin
+ 	print '@null_input is NULL, as expected'
+@@ -68,12 +68,12 @@ select distinct convert(varchar(30), name) as 'type'  from systypes
+ where name in ('int', 'char', 'text') 
+ select @nrows = @@rowcount 
+ select distinct @nv as '@nv', convert(varchar(30), name) as name  from sysobjects where type = 'S' 
+-select	  @null_input as '@null_input'
+-	, @first_type as '@first_type'
+-	, @nullout as '@nullout'
+-	, @nrows as '@nrows'
+-	, @c as '@c'
+-	, @nv as '@nv'
++select	  @null_input as 'null_input'
++	, @first_type as 'first_type'
++	, @nullout as 'nullout'
++	, @nrows as 'nrows'
++	, @c as 'c'
++	, @nv as 'nv'
+ 	into #parameters
+ select * from #parameters
+ return 42 
+
+commit 63981e7d2a2c224632c11ca0df0c4de95ca9349a
+Author: freddy77 <freddy77>
+Date:   Sat Jul 24 08:26:01 2010 +0000
+
+    remove warning
+
+diff --git a/ChangeLog b/ChangeLog
+index c60805b..2d671ea 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 24 10:25:53 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c: remove warning
++
+ Sat Jul 24 10:08:00 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/unittests/common.c src/dblib/unittests/rpc.sql:
+ 	- fix rpc test for Sybase
+@@ -2745,4 +2748,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3090 2010/07/24 08:08:09 freddy77 Exp $
++$Id: ChangeLog,v 1.3091 2010/07/24 08:26:01 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index a96d410..d98d30e 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.120 2010/07/22 14:11:41 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.121 2010/07/24 08:26:01 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -329,7 +329,7 @@ odbc_set_string_flag(TDS_DBC *dbc, SQLPOINTER buffer, SQLINTEGER cbBuffer, void
+ {
+ 	SQLRETURN result = SQL_SUCCESS;
+ 	int out_len = 0;
+-#ifndef NDEBUG
++#if !defined(NDEBUG) && defined(ENABLE_ODBC_WIDE)
+ 	size_t initial_size;
+ #endif
+ 
+
+commit fdda43839d1737da8cb8ca98c1b6e1a89e5eb7d7
+Author: freddy77 <freddy77>
+Date:   Sat Jul 24 12:41:01 2010 +0000
+
+    avoid overflow skipping wrong characters
+
+diff --git a/ChangeLog b/ChangeLog
+index 2d671ea..d6723f4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 24 14:40:44 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/iconv.c: avoid overflow skipping wrong characters
++
+ Sat Jul 24 10:25:53 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c: remove warning
+ 
+@@ -2748,4 +2751,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3091 2010/07/24 08:26:01 freddy77 Exp $
++$Id: ChangeLog,v 1.3092 2010/07/24 12:41:01 freddy77 Exp $
+diff --git a/src/tds/iconv.c b/src/tds/iconv.c
+index 2825f0d..3fb27ee 100644
+--- a/src/tds/iconv.c
++++ b/src/tds/iconv.c
+@@ -49,7 +49,7 @@
+ /* define this for now; remove when done testing */
+ #define HAVE_ICONV_ALWAYS 1
+ 
+-TDS_RCSID(var, "$Id: iconv.c,v 1.144 2010/06/27 17:46:43 berryc Exp $");
++TDS_RCSID(var, "$Id: iconv.c,v 1.145 2010/07/24 12:41:03 freddy77 Exp $");
+ 
+ #define CHARSIZE(charset) ( ((charset)->min_bytes_per_char == (charset)->max_bytes_per_char )? \
+ 				(charset)->min_bytes_per_char : 0 )
+@@ -1101,6 +1101,8 @@ skip_one_input_sequence(iconv_t cd, const TDS_ENCODING * charset, const char **i
+ 
+ 	/* usually fixed size and UTF-8 do not have state, so do not reset it */
+ 	if (charsize) {
++		if (charsize > *input_size)
++			return 0;
+ 		*input += charsize;
+ 		*input_size -= charsize;
+ 		return charsize;
+@@ -1121,6 +1123,8 @@ skip_one_input_sequence(iconv_t cd, const TDS_ENCODING * charset, const char **i
+ 		do {
+ 			++charsize;
+ 		} while ((c <<= 1) & 0x80);
++		if (charsize > *input_size)
++			return 0;
+ 		*input += charsize;
+ 		*input_size -= charsize;
+ 		return charsize;
+
+commit 5a154443c75ced83386c009f0baa3eb66771bfd3
+Author: freddy77 <freddy77>
+Date:   Sun Jul 25 07:49:00 2010 +0000
+
+    cleanup unused declarations
+
+diff --git a/ChangeLog b/ChangeLog
+index d6723f4..32fef44 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Sun Jul 25 09:48:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/ctlib/ct.c src/tds/mem.c:
++	- cleanup unused declarations
++
+ Sat Jul 24 14:40:44 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/iconv.c: avoid overflow skipping wrong characters
+ 
+@@ -2751,4 +2755,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3092 2010/07/24 12:41:01 freddy77 Exp $
++$Id: ChangeLog,v 1.3093 2010/07/25 07:49:00 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 8813fbe..68990b6 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.338 2010/07/02 18:57:32 freddy77 Exp $ */
++/* $Id: tds.h,v 1.339 2010/07/25 07:49:01 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -375,24 +375,6 @@ enum {
+ 	TDS_CUR_ISTAT_DEALLOC   = 0x40
+ };
+ 
+-/* 
+- * Cursor Declare, SetRows, Open and Close all return 0x83 token. 
+- * But only SetRows includes the rowcount (4 byte) in the stream. 
+- * So for Setrows we read the rowcount from the stream and not for others. 
+- * These values are useful to determine when to read the rowcount from the packet
+- */
+-#define IS_DECLARE  100
+-#define IS_CURROW   200
+-#define IS_OPEN     300
+-#define IS_CLOSE    400
+-
+-/* states for tds_process_messages() */
+-#define PROCESS_ROWS    0
+-#define PROCESS_RESULTS 1
+-#define CANCEL_PROCESS  2
+-#define GOTO_1ST_ROW    3
+-#define LOGIN           4
+-
+ /* environment type field */
+ #define TDS_ENV_DATABASE  	1
+ #define TDS_ENV_LANG      	2
+@@ -1360,7 +1342,6 @@ struct tds_socket
+ 	TDSDYNAMIC *cur_dyn;		/**< dynamic structure in use */
+ 	TDSDYNAMIC *dyns;		/**< list of dynamic allocate for this connection */
+ 
+-	char *date_fmt;
+ 	const TDSCONTEXT *tds_ctx;
+ 	int char_conv_count;
+ 	TDSICONV **char_convs;
+diff --git a/src/ctlib/ct.c b/src/ctlib/ct.c
+index e103f55..df16d6d 100644
+--- a/src/ctlib/ct.c
++++ b/src/ctlib/ct.c
+@@ -39,7 +39,7 @@
+ #include "tdsstring.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: ct.c,v 1.204 2010/04/26 09:09:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: ct.c,v 1.205 2010/07/25 07:49:01 freddy77 Exp $");
+ 
+ 
+ static char * ct_describe_cmd_state(CS_INT state);
+@@ -628,11 +628,12 @@ ct_connect(CS_CONNECTION * con, CS_CHAR * servername, CS_INT snamelen)
+ 			if (!tds_dstr_copy(&connection->language, con->locale->language)) 
+ 				goto Cleanup;
+ 		}
+-		if (con->locale->time) {
+-			free(con->tds_socket->date_fmt);
++		if (con->locale->time && con->tds_socket->tds_ctx) {
++			TDSLOCALE *locale = con->tds_socket->tds_ctx->locale;
++			free(locale->date_fmt);
+ 			/* TODO convert format from CTLib to libTDS */
+-			con->tds_socket->date_fmt = strdup(con->locale->time);
+-			if (!con->tds_socket->date_fmt)
++			locale->date_fmt = strdup(con->locale->time);
++			if (!locale->date_fmt)
+ 				goto Cleanup;
+ 		}
+ 		/* TODO how to handle this?
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index de4a355..14a9bd2 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.203 2010/07/21 20:12:18 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.204 2010/07/25 07:49:01 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -1149,7 +1149,6 @@ tds_free_socket(TDSSOCKET * tds)
+ 		tds_ssl_deinit(tds);
+ #endif
+ 		tds_close_socket(tds);
+-		free(tds->date_fmt);
+ 		tds_iconv_free(tds);
+ 		free(tds->product_name);
+ 		free(tds);
+
+commit 818ba0dcd645bfcf35f434c08825aa7b7f1f752a
+Author: freddy77 <freddy77>
+Date:   Sun Jul 25 08:40:18 2010 +0000
+
+    normalize some names
+
+diff --git a/ChangeLog b/ChangeLog
+index 32fef44..1243f3a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sun Jul 25 10:40:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h include/tds_sysdep_private.h include/tdsiconv.h:
++	* src/tds/mem.c src/tds/net.c src/tds/token.c src/tds/util.c:
++	- normalize some names
++
+ Sun Jul 25 09:48:50 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/ctlib/ct.c src/tds/mem.c:
+ 	- cleanup unused declarations
+@@ -2755,4 +2760,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3093 2010/07/25 07:49:00 freddy77 Exp $
++$Id: ChangeLog,v 1.3094 2010/07/25 08:40:18 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 68990b6..461614b 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.339 2010/07/25 07:49:01 freddy77 Exp $ */
++/* $Id: tds.h,v 1.340 2010/07/25 08:40:19 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -58,7 +58,7 @@ extern "C"
+  * This structure is returned by tds_get_compiletime_settings
+  */
+ 
+-typedef struct _tds_compiletime_settings
++typedef struct tds_compiletime_settings
+ {
+ 	const char *freetds_version;	/* release version of FreeTDS */
+ 	const char *sysconfdir;		/* location of freetds.conf */
+@@ -73,11 +73,10 @@ typedef struct _tds_compiletime_settings
+ 
+ } TDS_COMPILETIME_SETTINGS;
+ 
+-struct DSTR_STRUCT {
++typedef struct tds_dstr {
+ 	char *dstr_s;
+ 	size_t dstr_size;
+-};
+-typedef struct DSTR_STRUCT DSTR;
++} DSTR;
+ 
+ /**
+  * @file tds.h
+@@ -935,14 +934,14 @@ typedef struct
+  * Information relevant to libiconv.  The name is an iconv name, not 
+  * the same as found in master..syslanguages. 
+  */
+-typedef struct _tds_encoding
++typedef struct tds_encoding
+ {
+ 	const char *name;
+ 	unsigned char min_bytes_per_char;
+ 	unsigned char max_bytes_per_char;
+ } TDS_ENCODING;
+ 
+-typedef struct _tds_bcpcoldata
++typedef struct tds_bcpcoldata
+ {
+ 	TDS_UCHAR *data;
+ 	TDS_INT    datalen;
+@@ -1146,7 +1145,7 @@ typedef enum {
+ 	, TDS_CURSOR_STATE_ACTIONED = 3		/* acknowledged by server */
+ } TDS_CURSOR_STATE;
+ 
+-typedef struct _tds_cursor_status
++typedef struct tds_cursor_status
+ {
+ 	TDS_CURSOR_STATE declare;
+ 	TDS_CURSOR_STATE cursor_row;
+@@ -1156,7 +1155,7 @@ typedef struct _tds_cursor_status
+ 	TDS_CURSOR_STATE dealloc;
+ } TDS_CURSOR_STATUS;
+ 
+-typedef enum _tds_cursor_operation
++typedef enum tds_cursor_operation
+ {
+ 	TDS_CURSOR_POSITION = 0,
+ 	TDS_CURSOR_UPDATE = 1,
+@@ -1164,7 +1163,7 @@ typedef enum _tds_cursor_operation
+ 	TDS_CURSOR_INSERT = 4
+ } TDS_CURSOR_OPERATION;
+ 
+-typedef enum _tds_cursor_fetch
++typedef enum tds_cursor_fetch
+ {
+ 	TDS_CURSOR_FETCH_NEXT = 1,
+ 	TDS_CURSOR_FETCH_PREV,
+@@ -1177,9 +1176,9 @@ typedef enum _tds_cursor_fetch
+ /**
+  * Holds informations about a cursor
+  */
+-typedef struct _tds_cursor 
++typedef struct tds_cursor
+ {
+-	struct _tds_cursor *next;	/**< next in linked list, keep first */
++	struct tds_cursor *next;	/**< next in linked list, keep first */
+ 	TDS_INT ref_count;		/**< reference counter so client can retain safely a pointer */
+ 	TDS_TINYINT cursor_name_len;	/**< length of cursor name > 0 and <= 30  */
+ 	char *cursor_name;		/**< name of the cursor */
+@@ -1278,15 +1277,13 @@ enum TDS_ICONV_ENTRY
+ 	, initial_char_conv_count	/* keep last */
+ };
+ 
+-struct tds_authentication
++typedef struct tds_authentication
+ {
+ 	TDS_UCHAR *packet;
+ 	int packet_len;
+ 	int (*free)(TDSSOCKET * tds, struct tds_authentication * auth);
+ 	int (*handle_next)(TDSSOCKET * tds, struct tds_authentication * auth, size_t len);
+-};
+-
+-typedef struct tds_authentication TDSAUTHENTICATION;
++} TDSAUTHENTICATION;
+ 
+ /**
+  * Information for a server connection
+diff --git a/include/tds_sysdep_private.h b/include/tds_sysdep_private.h
+index c04a39d..0bea2e5 100644
+--- a/include/tds_sysdep_private.h
++++ b/include/tds_sysdep_private.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_sysdep_private_h_
+ #define _tds_sysdep_private_h_
+ 
+-/* $Id: tds_sysdep_private.h,v 1.34 2010/05/12 08:13:58 freddy77 Exp $ */
++/* $Id: tds_sysdep_private.h,v 1.35 2010/07/25 08:40:19 freddy77 Exp $ */
+ 
+ #undef TDS_RCSID
+ #if defined(__GNUC__) && __GNUC__ >= 3
+@@ -76,10 +76,10 @@ typedef int pid_t;
+ #define CLOSESOCKET(a)		closesocket((a))
+ #define IOCTLSOCKET(a,b,c)	ioctlsocket((a), (b), (c))
+ #define SOCKLEN_T int
+-int  _tds_socket_init(void);
+-#define INITSOCKET()	_tds_socket_init()
+-void _tds_socket_done(void);
+-#define DONESOCKET()	_tds_socket_done()
++int  tds_socket_init(void);
++#define INITSOCKET()	tds_socket_init()
++void tds_socket_done(void);
++#define DONESOCKET()	tds_socket_done()
+ #define NETDB_REENTRANT 1	/* BSD-style netdb interface is reentrant */
+ 
+ #define TDSSOCK_EINTR WSAEINTR
+diff --git a/include/tdsiconv.h b/include/tdsiconv.h
+index ed0131c..85e6414 100644
+--- a/include/tdsiconv.h
++++ b/include/tdsiconv.h
+@@ -20,7 +20,7 @@
+ #ifndef _tds_iconv_h_
+ #define _tds_iconv_h_
+ 
+-/* $Id: tdsiconv.h,v 1.39 2010/07/02 23:55:56 freddy77 Exp $ */
++/* $Id: tdsiconv.h,v 1.40 2010/07/25 08:40:19 freddy77 Exp $ */
+ 
+ #if HAVE_ICONV
+ #include <iconv.h>
+@@ -79,7 +79,7 @@ typedef struct _character_set_alias
+ 	int canonic;
+ } CHARACTER_SET_ALIAS;
+ 
+-typedef struct _tds_errno_message_flags {
++typedef struct tds_errno_message_flags {
+ 	unsigned int e2big:1;
+ 	unsigned int eilseq:1;
+ 	unsigned int einval:1;
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 14a9bd2..85f8ff6 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.204 2010/07/25 07:49:01 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.205 2010/07/25 08:40:19 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -298,7 +298,7 @@ tds_free_param_result(TDSPARAMINFO * param_info)
+ }
+ 
+ static void
+-_tds_param_free(TDSCOLUMN *col)
++tds_param_free(TDSCOLUMN *col)
+ {
+ 	if (!col->column_data)
+ 		return;
+@@ -335,7 +335,7 @@ tds_alloc_param_data(TDSCOLUMN * curparam)
+ 	/* allocate data */
+ 	if (curparam->column_data && curparam->column_data_free)
+ 		curparam->column_data_free(curparam);
+-	curparam->column_data_free = _tds_param_free;
++	curparam->column_data_free = tds_param_free;
+ 
+ 	data = malloc(data_size);
+ 	curparam->column_data = data;
+@@ -439,7 +439,7 @@ tds_alloc_results(int num_cols)
+ }
+ 
+ static void
+-_tds_row_free(TDSRESULTINFO *res_info, unsigned char *row)
++tds_row_free(TDSRESULTINFO *res_info, unsigned char *row)
+ {
+ 	int i;
+ 	const TDSCOLUMN *col;
+@@ -495,7 +495,7 @@ tds_alloc_row(TDSRESULTINFO * res_info)
+ 	res_info->current_row = ptr;
+ 	if (!ptr)
+ 		return TDS_FAIL;
+-	res_info->row_free = _tds_row_free;
++	res_info->row_free = tds_row_free;
+ 
+ 	/* fill column_data */
+ 	row_size = 0;
+diff --git a/src/tds/net.c b/src/tds/net.c
+index 5fe7d72..fff325c 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.103 2010/05/12 08:00:11 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.104 2010/07/25 08:40:19 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -134,7 +134,7 @@ static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned i
+ 
+ #ifdef _WIN32
+ int
+-_tds_socket_init(void)
++tds_socket_init(void)
+ {
+ 	WSADATA wsadata;
+ 
+@@ -142,7 +142,7 @@ _tds_socket_init(void)
+ }
+ 
+ void
+-_tds_socket_done(void)
++tds_socket_done(void)
+ {
+ 	WSACleanup();
+ }
+diff --git a/src/tds/token.c b/src/tds/token.c
+index 52575b4..502da71 100644
+--- a/src/tds/token.c
++++ b/src/tds/token.c
+@@ -43,7 +43,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: token.c,v 1.387 2010/07/02 18:57:32 freddy77 Exp $");
++TDS_RCSID(var, "$Id: token.c,v 1.388 2010/07/25 08:40:19 freddy77 Exp $");
+ 
+ #define USE_ICONV tds->use_iconv
+ 
+@@ -75,7 +75,7 @@ static int tds_process_end(TDSSOCKET * tds, int marker, /*@out@*/ int *flags_par
+ 
+ static int tds_get_data(TDSSOCKET * tds, TDSCOLUMN * curcol);
+ static int tds_get_data_info(TDSSOCKET * tds, TDSCOLUMN * curcol, int is_param);
+-static /*@observer@*/ const char *_tds_token_name(unsigned char marker);
++static /*@observer@*/ const char *tds_token_name(unsigned char marker);
+ static void adjust_character_column_size(const TDSSOCKET * tds, TDSCOLUMN * curcol);
+ static int determine_adjusted_size(const TDSICONV * char_conv, int size);
+ static /*@observer@*/ const char *tds_pr_op(int op);
+@@ -119,7 +119,7 @@ tds_process_default_tokens(TDSSOCKET * tds, int marker)
+ 
+ 	CHECK_TDS_EXTRA(tds);
+ 
+-	tdsdump_log(TDS_DBG_FUNC, "tds_process_default_tokens() marker is %x(%s)\n", marker, _tds_token_name(marker));
++	tdsdump_log(TDS_DBG_FUNC, "tds_process_default_tokens() marker is %x(%s)\n", marker, tds_token_name(marker));
+ 
+ 	if (IS_TDSDEAD(tds)) {
+ 		tdsdump_log(TDS_DBG_FUNC, "leaving tds_process_default_tokens() connection dead\n");
+@@ -234,7 +234,7 @@ tds_process_default_tokens(TDSSOCKET * tds, int marker)
+ 	case TDS_LOGINACK_TOKEN:
+ 	case TDS_ORDERBY_TOKEN:
+ 	case TDS_CONTROL_TOKEN:
+-		tdsdump_log(TDS_DBG_WARN, "Eating %s token\n", _tds_token_name(marker));
++		tdsdump_log(TDS_DBG_WARN, "Eating %s token\n", tds_token_name(marker));
+ 		tds_get_n(tds, NULL, tds_get_smallint(tds));
+ 		break;
+ 	case TDS_TABNAME_TOKEN:	/* used for FOR BROWSE query */
+@@ -244,7 +244,7 @@ tds_process_default_tokens(TDSSOCKET * tds, int marker)
+ 		return tds_process_colinfo(tds, NULL, 0);
+ 		break;
+ 	case TDS_ORDERBY2_TOKEN:
+-		tdsdump_log(TDS_DBG_WARN, "Eating %s token\n", _tds_token_name(marker));
++		tdsdump_log(TDS_DBG_WARN, "Eating %s token\n", tds_token_name(marker));
+ 		tds_get_n(tds, NULL, tds_get_int(tds));
+ 		break;
+ 	case TDS_NBC_ROW_TOKEN:
+@@ -334,7 +334,7 @@ tds_process_login_tokens(TDSSOCKET * tds)
+ 			} ver;
+ 		
+ 		marker = tds_get_byte(tds);
+-		tdsdump_log(TDS_DBG_FUNC, "looking for login token, got  %x(%s)\n", marker, _tds_token_name(marker));
++		tdsdump_log(TDS_DBG_FUNC, "looking for login token, got  %x(%s)\n", marker, tds_token_name(marker));
+ 
+ 		switch (marker) {
+ 		case TDS_AUTH_TOKEN:
+@@ -551,7 +551,7 @@ tds_process_tokens(TDSSOCKET *tds, TDS_INT *result_type, int *done_flags, unsign
+ 	for (;;) {
+ 
+ 		marker = tds_get_byte(tds);
+-		tdsdump_log(TDS_DBG_INFO1, "processing result tokens.  marker is  %x(%s)\n", marker, _tds_token_name(marker));
++		tdsdump_log(TDS_DBG_INFO1, "processing result tokens.  marker is  %x(%s)\n", marker, tds_token_name(marker));
+ 
+ 		switch (marker) {
+ 		case TDS7_RESULT_TOKEN:
+@@ -3445,7 +3445,7 @@ tds_prtype(int token)
+ /** @} */
+ 
+ static const char *
+-_tds_token_name(unsigned char marker)
++tds_token_name(unsigned char marker)
+ {
+ 	switch (marker) {
+ 
+diff --git a/src/tds/util.c b/src/tds/util.c
+index c4b6eb1..459094a 100644
+--- a/src/tds/util.c
++++ b/src/tds/util.c
+@@ -65,7 +65,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: util.c,v 1.92 2010/07/02 18:57:34 freddy77 Exp $");
++TDS_RCSID(var, "$Id: util.c,v 1.93 2010/07/25 08:40:19 freddy77 Exp $");
+ 
+ void
+ tds_set_parent(TDSSOCKET * tds, void *the_parent)
+@@ -233,7 +233,7 @@ tds_gettime_ms(void)
+ #define EXFATAL       10
+ #define EXCONSISTENCY 11
+ 
+-typedef struct _tds_error_message 
++typedef struct tds_error_message
+ {
+ 	TDSERRNO msgno;
+ 	int severity;
+
+commit d2384a2f0f4b41b3ecd3e0cbfdd46c8471608fe7
+Author: freddy77 <freddy77>
+Date:   Sun Jul 25 10:02:56 2010 +0000
+
+    add php test
+
+diff --git a/ChangeLog b/ChangeLog
+index 1243f3a..eb401f4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jul 25 12:02:49 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* phptests/types.php: add php test
++
+ Sun Jul 25 10:40:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h include/tds_sysdep_private.h include/tdsiconv.h:
+ 	* src/tds/mem.c src/tds/net.c src/tds/token.c src/tds/util.c:
+@@ -2760,4 +2763,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3094 2010/07/25 08:40:18 freddy77 Exp $
++$Id: ChangeLog,v 1.3095 2010/07/25 10:02:56 freddy77 Exp $
+diff --git a/phptests/types.php b/phptests/types.php
+new file mode 100644
+index 0000000..c865735
+--- /dev/null
++++ b/phptests/types.php
+@@ -0,0 +1,59 @@
++<?php
++
++// $Id: types.php,v 1.1 2010/07/25 10:02:56 freddy77 Exp $
++
++require_once("pwd.inc");
++
++$conn = odbc_connect($server,$user,$pass) or die("opps");
++
++$sql = <<<EOSQL
++CREATE TABLE php_types (
++	ui SMALLINT,
++	i INT,
++	ti TINYINT,
++	c CHAR(123),
++	vc VARCHAR(125)
++)
++EOSQL;
++
++odbc_exec($conn, "IF OBJECT_ID('php_types') IS NOT NULL DROP TABLE php_types") or die(odbc_errormsg());
++odbc_exec($conn, $sql) or die(odbc_errormsg());
++$sql = "select * from php_types";
++echo "Query: $sql\n";
++$result = odbc_exec($conn, $sql) or die(odbc_errormsg());
++
++$all = array (
++	'ui' => 'smallint-5',
++	'i'  => 'int-10',
++	'ti' => 'tinyint-3',
++	'c'  => 'char-123',
++	'vc' => 'varchar-125'
++);
++
++$err = '';
++$ok = 0;
++for($i=1;$i<=odbc_num_fields($result);$i++) {
++	$name = odbc_field_name($result,$i);
++	$type = odbc_field_type($result,$i);
++	$len = odbc_field_len($result,$i);
++	echo "column $name type $type len $len\n";
++	$type = strtolower($type);
++	if ($all[$name] != "$type-$len")
++		$err .= "Invalid column $name\n";
++	else
++		++$ok;
++}
++
++if ($ok != 5)
++	$err .= "Expected 5 columns\n";
++
++if ($err) {
++	echo "$err";
++	exit(1);
++}
++echo "all columns seems ok\n";
++
++odbc_exec($conn, "IF OBJECT_ID('php_types') IS NOT NULL DROP TABLE php_types") or die(odbc_errormsg());
++
++exit(0);
++?>
+
+commit 0c85786f726563e209328c149fec09cef7fbb369
+Author: freddy77 <freddy77>
+Date:   Sun Jul 25 10:46:25 2010 +0000
+
+    update year
+
+diff --git a/ChangeLog b/ChangeLog
+index eb401f4..168ae5a 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sun Jul 25 12:46:17 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/test-other.sh: update year
++
+ Sun Jul 25 12:02:49 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* phptests/types.php: add php test
+ 
+@@ -2763,4 +2766,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3095 2010/07/25 10:02:56 freddy77 Exp $
++$Id: ChangeLog,v 1.3096 2010/07/25 10:46:25 freddy77 Exp $
+diff --git a/misc/test-other.sh b/misc/test-other.sh
+index d20591a..2fd0c6f 100755
+--- a/misc/test-other.sh
++++ b/misc/test-other.sh
+@@ -184,9 +184,9 @@ FILE='php5.2-latest.tar.bz2'
+ if test $do_php = yes -a -f "$FILE"; then
+ 	# need to recompile ??
+ 	if test ! -x phpinst/bin/php -o "$FILE" -nt phpinst/bin/php; then
+-		rm -rf php5.2-200* phpinst lib
++		rm -rf php5.2-201* phpinst lib
+ 		bunzip2 -c "$FILE" | tar xvf -
+-		DIR=`echo php5.2-200*`
++		DIR=`echo php5.2-201*`
+ 		MAINDIR=$PWD
+ 		mkdir lib
+ 		cp src/dblib/.libs/lib*.s[ol]* lib
+
+commit 26667685a0fdaeb2a61788f0f33fb6c17406547c
+Author: freddy77 <freddy77>
+Date:   Tue Jul 27 07:19:18 2010 +0000
+
+    fix dblib build with Sybase libraries
+
+diff --git a/ChangeLog b/ChangeLog
+index 168ae5a..5968fa7 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Jul 27 09:18:53 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* misc/sybase_tests: fix dblib build with Sybase libraries
++
+ Sun Jul 25 12:46:17 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/test-other.sh: update year
+ 
+@@ -2766,4 +2769,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3096 2010/07/25 10:46:25 freddy77 Exp $
++$Id: ChangeLog,v 1.3097 2010/07/27 07:19:18 freddy77 Exp $
+diff --git a/misc/sybase_tests b/misc/sybase_tests
+index 2d9a8e9..00ec8d2 100755
+--- a/misc/sybase_tests
++++ b/misc/sybase_tests
+@@ -1,6 +1,6 @@
+ #!/bin/bash
+ 
+-# $Id: sybase_tests,v 1.5 2010/07/07 13:57:02 freddy77 Exp $
++# $Id: sybase_tests,v 1.6 2010/07/27 07:19:18 freddy77 Exp $
+ # these commands build dblib and ctlib tests using Sybase libraries
+ 
+ errore() {
+@@ -28,8 +28,9 @@ set -e
+ make
+ 
+ # rebuild tests
+-for dir in src/ctlib/unittests src/ctlib/unittests; do
++for dir in src/dblib/unittests src/ctlib/unittests; do
+ 	cd $dir
++	export LD_RUN_PATH="$SYBASE/$OCSDIR/lib"
+ 	if test ! -r Makefile.no_sybase -o Makefile -nt Makefile.no_sybase; then
+ 		rm -f Makefile.no_sybase
+ 		echo '#include <sybfront.h>' > sqlfront.h
+
+commit 0fa4e6bfc8ee81705d9b7f693c153a250ddc4485
+Author: freddy77 <freddy77>
+Date:   Tue Jul 27 08:53:12 2010 +0000
+
+    moved option_flag2 from tds_socket to tds_connection
+
+diff --git a/ChangeLog b/ChangeLog
+index 5968fa7..17fe857 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Tue Jul 27 10:52:58 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/dblib/dblib.c src/tds/login.c src/tds/mem.c:
++	- moved option_flag2 from tds_socket to tds_connection
++
+ Tue Jul 27 09:18:53 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* misc/sybase_tests: fix dblib build with Sybase libraries
+ 
+@@ -2769,4 +2773,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3097 2010/07/27 07:19:18 freddy77 Exp $
++$Id: ChangeLog,v 1.3098 2010/07/27 08:53:12 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index 461614b..c442f4a 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.340 2010/07/25 08:40:19 freddy77 Exp $ */
++/* $Id: tds.h,v 1.341 2010/07/27 08:53:12 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -864,6 +864,7 @@ typedef struct tds_connection
+ 
+ 	TDS_INT query_timeout;
+ 	unsigned char capabilities[TDS_MAX_CAPABILITY];
++	unsigned char option_flag2;
+ 	DSTR client_charset;
+ 
+ 	DSTR ip_addr;	  	/**< ip of server */
+@@ -1297,7 +1298,6 @@ struct tds_socket
+ 	char *product_name;
+ 
+ 	unsigned char capabilities[TDS_MAX_CAPABILITY];
+-	unsigned char option_flag2;
+ 	unsigned int broken_dates:1;
+ 	unsigned int emul_little_endian:1;
+ 	unsigned int use_iconv:1;
+diff --git a/src/dblib/dblib.c b/src/dblib/dblib.c
+index 00e2145..6fd790c 100644
+--- a/src/dblib/dblib.c
++++ b/src/dblib/dblib.c
+@@ -75,7 +75,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: dblib.c,v 1.364 2010/05/21 15:18:49 freddy77 Exp $");
++TDS_RCSID(var, "$Id: dblib.c,v 1.365 2010/07/27 08:53:12 freddy77 Exp $");
+ 
+ static RETCODE _dbresults(DBPROCESS * dbproc);
+ static int _db_get_server_type(int bindtype);
+@@ -1157,7 +1157,6 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 	
+ 
+ 	tds_set_parent(dbproc->tds_socket, dbproc);
+-	dbproc->tds_socket->option_flag2 &= ~0x02;	/* we're not an ODBC driver */
+ 	dbproc->tds_socket->env_chg_func = db_env_chg;
+ 	dbproc->envchange_rcv = 0;
+ 	dbproc->dbcurdb[0] = '\0';
+@@ -1168,6 +1167,7 @@ tdsdbopen(LOGINREC * login, const char *server, int msdblib)
+ 		dbclose(dbproc);
+ 		return NULL;
+ 	}
++	connection->option_flag2 &= ~0x02;	/* we're not an ODBC driver */
+ 
+ 	dbproc->chkintr = NULL;
+ 	dbproc->hndlintr = NULL;
+diff --git a/src/tds/login.c b/src/tds/login.c
+index 6fa7650..bf4d45d 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.196 2010/03/01 12:38:10 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.197 2010/07/27 08:53:12 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -692,7 +692,7 @@ tds7_send_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	static const unsigned char connection_id[] = { 0x00, 0x00, 0x00, 0x00 };
+ 	unsigned char option_flag1 = 0x00;
+-	unsigned char option_flag2 = tds->option_flag2;
++	unsigned char option_flag2 = connection->option_flag2;
+ 	static const unsigned char sql_type_flag = 0x00;
+ 	static const unsigned char reserved_flag = 0x00;
+ 
+diff --git a/src/tds/mem.c b/src/tds/mem.c
+index 85f8ff6..9ad97cb 100644
+--- a/src/tds/mem.c
++++ b/src/tds/mem.c
+@@ -53,7 +53,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: mem.c,v 1.205 2010/07/25 08:40:19 freddy77 Exp $");
++TDS_RCSID(var, "$Id: mem.c,v 1.206 2010/07/27 08:53:12 freddy77 Exp $");
+ 
+ static void tds_free_env(TDSSOCKET * tds);
+ static void tds_free_compute_results(TDSSOCKET * tds);
+@@ -831,6 +831,12 @@ tds_alloc_connection(TDSLOCALE * locale)
+ 	/* fill in all hardcoded defaults */
+ 	if (!tds_dstr_copy(&connection->server_name, TDS_DEF_SERVER))
+ 		goto Cleanup;
++	/*
++	 * TDS 7.0:
++	 * 0x02 indicates ODBC driver
++	 * 0x01 means change to initial language must succeed
++	 */
++	connection->option_flag2 = 0x03;
+ 	connection->tds_version = TDS_DEFAULT_VERSION;
+ 	connection->block_size = 0;
+ 
+@@ -1087,12 +1093,6 @@ tds_alloc_socket(TDSCONTEXT * context, int bufsize)
+ 	TEST_CALLOC(tds_socket->out_buf, unsigned char, bufsize + TDS_ADDITIONAL_SPACE);
+ 
+ 	tds_socket->parent = NULL;
+-	/*
+-	 * TDS 7.0: 
+-	 * 0x02 indicates ODBC driver
+-	 * 0x01 means change to initial language must succeed
+-	 */
+-	tds_socket->option_flag2 = 0x03;
+ 	tds_socket->env.block_size = bufsize;
+ 
+ 	tds_socket->use_iconv = 1;
+
+commit 90f7a18734e0e5f1acc5b5ce5c203c938cdaed22
+Author: freddy77 <freddy77>
+Date:   Fri Jul 30 07:17:27 2010 +0000
+
+    fix MingW compile if wide odbc disabled
+
+diff --git a/ChangeLog b/ChangeLog
+index 17fe857..3a2b4e4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Fri Jul 30 09:17:15 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac src/odbc/Makefile.am win32/FreeTDS.def:
++	- win32/FreeTDSW.def
++	* win32/Makefile.am: fix MingW compile if wide odbc disabled
++
+ Tue Jul 27 10:52:58 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/dblib/dblib.c src/tds/login.c src/tds/mem.c:
+ 	- moved option_flag2 from tds_socket to tds_connection
+@@ -2773,4 +2778,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3098 2010/07/27 08:53:12 freddy77 Exp $
++$Id: ChangeLog,v 1.3099 2010/07/30 07:17:27 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 6c797be..73f08ee 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.52 2010/07/03 09:49:12 freddy77 Exp $
++dnl $Id: configure.ac,v 1.53 2010/07/30 07:17:27 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.52 $)
++AC_REVISION($Revision: 1.53 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -774,6 +774,7 @@ AC_ARG_ENABLE(odbc-wide,
+ if test "$enable_odbc_wide" = "yes" ; then
+ 	AC_DEFINE_UNQUOTED(ENABLE_ODBC_WIDE, 1, [Define to enable ODBC wide string support])
+ fi
++AM_CONDITIONAL(ODBC_WIDE, test "$enable_odbc_wide" = "yes")
+ 
+ AC_ARG_ENABLE(distcheck_build,
+   AS_HELP_STRING([--enable-distcheck-build], [used internally for testing]))
+diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am
+index 36dd26c..b2e1f7f 100644
+--- a/src/odbc/Makefile.am
++++ b/src/odbc/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.48 2010/07/02 14:07:57 freddy77 Exp $
++# $Id: Makefile.am,v 1.49 2010/07/30 07:17:27 freddy77 Exp $
+ SUBDIRS		= unittests
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC)
+ 
+@@ -13,9 +13,14 @@ libtdsodbc_la_SOURCES=	odbc.c connectparams.c convert_tds2sql.c \
+ 	descriptor.c prepare_query.c odbc_util.c \
+ 	native.c sql2tds.c error.c odbc_checks.c sqlwchar.c sqlwparams.h $(MINGW_SOURCES)
+ if MINGW32
++if ODBC_WIDE
++DEFFILE = FreeTDSW.def
++else
++DEFFILE = FreeTDS.def
++endif
+ libtdsodbc_la_LIBADD=	../../win32/setup.res ../tds/libtds.la ../replacements/libreplacements.la $(ODBCINSTLIB) \
+ 	$(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+-libtdsodbc_la_LDFLAGS = -Wl,--enable-stdcall-fixup -Wl,-s -Wl,$(top_srcdir)/win32/FreeTDS.def -Wl,../../win32/setup.res $(FREETDS_SYMBOLIC)
++libtdsodbc_la_LDFLAGS = -Wl,--enable-stdcall-fixup -Wl,-s -Wl,$(top_srcdir)/win32/$(DEFFILE) -Wl,../../win32/setup.res $(FREETDS_SYMBOLIC)
+ 
+ .rc.res:
+ 	$(RC) -i $< -I $(top_builddir)/win32 --input-format=rc -o $@ -O coff
+diff --git a/win32/FreeTDS.def b/win32/FreeTDS.def
+index 43bca48..97ea274 100644
+--- a/win32/FreeTDS.def
++++ b/win32/FreeTDS.def
+@@ -78,37 +78,4 @@ EXPORTS
+ 	ConfigTranslator
+ 	DllRegisterServer
+ 	DllUnregisterServer
+-	SQLColAttributeW
+-	SQLColumnPrivilegesW
+-	SQLColumnsW
+-	SQLConnectW
+-	SQLDescribeColW
+-	SQLDriverConnectW
+-	SQLErrorW
+-	SQLExecDirectW
+-	SQLForeignKeysW
+-	SQLGetConnectAttrW
+-	SQLGetConnectOptionW
+-	SQLGetCursorNameW
+-	SQLGetDescFieldW
+-	SQLGetDescRecW
+-	SQLGetDiagFieldW
+-	SQLGetDiagRecW
+-	SQLGetInfoW
+-	SQLGetTypeInfoW = SQLGetTypeInfo
+-	SQLGetStmtAttrW
+-	SQLNativeSqlW
+-	SQLPrepareW
+-	SQLPrimaryKeysW
+-	SQLProcedureColumnsW
+-	SQLProceduresW
+-	SQLSetConnectAttrW
+-	SQLSetConnectOptionW
+-	SQLSetCursorNameW
+-	SQLSetDescFieldW
+-	SQLSetStmtAttrW
+-	SQLSpecialColumnsW
+-	SQLStatisticsW
+-	SQLTablePrivilegesW
+-	SQLTablesW
+ 
+diff --git a/win32/Makefile.am b/win32/Makefile.am
+index 78190d0..a92213e 100644
+--- a/win32/Makefile.am
++++ b/win32/Makefile.am
+@@ -1,5 +1,5 @@
+ SUBDIRS	= msvc6
+-EXTRA_DIST      = config.h FreeTDS.def initnet.c \
++EXTRA_DIST      = config.h FreeTDS.def FreeTDSW.def initnet.c \
+ 		tds_sysdep_public.h freetds_sysconfdir.h \
+ 		winsetup.c winlogin.c \
+ 		setup.rc resource.h \
+
+commit 46bd69dd319b52703fdaee37f90492ff4e987814
+Author: freddy77 <freddy77>
+Date:   Fri Jul 30 07:29:48 2010 +0000
+
+    remove oserr from tds_socket
+
+diff --git a/ChangeLog b/ChangeLog
+index 3a2b4e4..8afc970 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Fri Jul 30 09:29:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tds.h src/tds/login.c src/tds/net.c:
++	- remove oserr from tds_socket
++
+ Fri Jul 30 09:17:15 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac src/odbc/Makefile.am win32/FreeTDS.def:
+ 	- win32/FreeTDSW.def
+@@ -2778,4 +2782,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3099 2010/07/30 07:17:27 freddy77 Exp $
++$Id: ChangeLog,v 1.3100 2010/07/30 07:29:48 freddy77 Exp $
+diff --git a/include/tds.h b/include/tds.h
+index c442f4a..577b732 100644
+--- a/include/tds.h
++++ b/include/tds.h
+@@ -21,7 +21,7 @@
+ #ifndef _tds_h_
+ #define _tds_h_
+ 
+-/* $Id: tds.h,v 1.341 2010/07/27 08:53:12 freddy77 Exp $ */
++/* $Id: tds.h,v 1.342 2010/07/30 07:29:48 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include <stdio.h>
+@@ -1292,7 +1292,7 @@ typedef struct tds_authentication
+ struct tds_socket
+ {
+ 	TDS_SYS_SOCKET s;		/**< tcp socket, INVALID_SOCKET if not connected */
+-	int oserr;
++
+ 	TDS_USMALLINT tds_version;
+ 	TDS_UINT product_version;	/**< version of product (Sybase/MS and full version) */
+ 	char *product_name;
+@@ -1331,7 +1331,7 @@ struct tds_socket
+ 
+ 	volatile 
+ 	unsigned char in_cancel; 	/**< indicate we are waiting a cancel reply; discard tokens till acknowledge */
+-	
++
+ 	TDS_INT8 rows_affected;		/**< rows updated/deleted/inserted/selected, TDS_NO_COUNT if not valid */
+ 	TDS_INT query_timeout;
+ 	TDSENV env;
+@@ -1573,7 +1573,7 @@ extern int tds_g_append_mode;
+ 
+ /* net.c */
+ int tds_lastpacket(TDSSOCKET * tds);
+-TDSERRNO tds_connect(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
++TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout, int *p_oserr);
+ int tds_close_socket(TDSSOCKET * tds);
+ int tds_read_packet(TDSSOCKET * tds);
+ int tds_write_packet(TDSSOCKET * tds, unsigned char final);
+diff --git a/src/tds/login.c b/src/tds/login.c
+index bf4d45d..8b94d41 100644
+--- a/src/tds/login.c
++++ b/src/tds/login.c
+@@ -51,7 +51,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: login.c,v 1.197 2010/07/27 08:53:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: login.c,v 1.198 2010/07/30 07:29:48 freddy77 Exp $");
+ 
+ static int tds_send_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+ static int tds8_do_login(TDSSOCKET * tds, TDSCONNECTION * connection);
+@@ -313,8 +313,8 @@ free_save_context(TDSSAVECONTEXT *ctx)
+  * 		- TDSEFCON: connect(2) succeeded, login packet not acknowledged.  
+  *		- TDS_FAIL: connect(2) succeeded, login failed.  
+  */
+-int
+-tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
++static int
++tds_connect(TDSSOCKET * tds, TDSCONNECTION * connection, int *p_oserr)
+ {
+ 	int erc = TDSEFCON;
+ 	int connect_timeout = 0;
+@@ -355,7 +355,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 			connection->tds_version = versions[i];
+ 			reset_save_context(&save_ctx);
+ 
+-			if ((erc = tds_connect_and_login(tds, connection)) != TDS_SUCCEED) {
++			if ((erc = tds_connect(tds, connection, p_oserr)) != TDS_SUCCEED) {
+ 				tds_close_socket(tds);
+ 			}
+ 			
+@@ -370,7 +370,7 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		free_save_context(&save_ctx);
+ 		
+ 		if (erc != TDS_SUCCEED)
+-			tdserror(tds->tds_ctx, tds, erc, tds->oserr); 
++			tdserror(tds->tds_ctx, tds, erc, *p_oserr);
+ 
+ 		return erc;
+ 	}
+@@ -403,12 +403,6 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 		}
+ 	}
+ 
+-	/* specified a date format? */
+-	/*
+-	 * if (connection->date_fmt) {
+-	 * tds->date_fmt=strdup(connection->date_fmt);
+-	 * }
+-	 */
+ 	connect_timeout = connection->connect_timeout;
+ 
+ 	/* Jeff's hack - begin */
+@@ -437,8 +431,10 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 
+ 	memcpy(tds->capabilities, connection->capabilities, TDS_MAX_CAPABILITY);
+ 
+-	if ((erc = tds_connect(tds, tds_dstr_cstr(&connection->ip_addr), connection->port, connect_timeout)) != TDS_SUCCEED)
++	if ((erc = tds_open_socket(tds, tds_dstr_cstr(&connection->ip_addr), connection->port, connect_timeout, p_oserr)) != TDSEOK) {
++		tdserror(tds->tds_ctx, tds, erc, *p_oserr);
+ 		return erc;
++	}
+ 		
+ 	/*
+ 	 * Beyond this point, we're connected to the server.  We know we have a valid TCP/IP address+socket pair.  
+@@ -495,6 +491,13 @@ tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
+ 	return TDS_SUCCEED;
+ }
+ 
++int
++tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection)
++{
++	int oserr = 0;
++	return tds_connect(tds, connection, &oserr);
++}
++
+ static int
+ tds_put_login_string(TDSSOCKET * tds, const char *buf, int n)
+ {
+diff --git a/src/tds/net.c b/src/tds/net.c
+index fff325c..eb11d27 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,7 +107,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.104 2010/07/25 08:40:19 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.105 2010/07/30 07:29:48 freddy77 Exp $");
+ 
+ #undef USE_POLL
+ #if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+@@ -124,7 +124,6 @@ TDS_RCSID(var, "$Id: net.c,v 1.104 2010/07/25 08:40:19 freddy77 Exp $");
+ #endif
+ 
+ static int      tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
+-static TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout);
+ 
+ 
+ /**
+@@ -189,17 +188,7 @@ typedef u_long ioctl_nonblocking_t;
+ #endif
+ 
+ TDSERRNO
+-tds_connect(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout)
+-{
+-	TDSERRNO erc = tds_open_socket(tds, ip_addr, port, timeout);
+-	if (TDSEOK != erc) {
+-		tdserror(tds->tds_ctx, tds, erc, tds->oserr);  
+-	}
+-	return erc;
+-}
+-
+-static TDSERRNO
+-tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout)
++tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout, int *p_oserr)
+ {
+ 	struct sockaddr_in sin;
+ 	ioctl_nonblocking_t ioctl_nonblocking;
+@@ -209,7 +198,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	int tds_error = TDSECONN;
+ 	char ip[20];
+ 
+-	tds->oserr = 0;
++	*p_oserr = 0;
+ 
+ 	memset(&sin, 0, sizeof(sin));
+ 
+@@ -227,7 +216,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 			TDS_MAJOR(tds), TDS_MINOR(tds));
+ 
+ 	if (TDS_IS_SOCKET_INVALID(tds->s = socket(AF_INET, SOCK_STREAM, 0))) {
+-		tds->oserr = sock_errno;
++		*p_oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "socket creation error: %s\n", sock_strerror(sock_errno));
+ 		return TDSESOCK;
+ 	}
+@@ -251,7 +240,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	if (connect(tds->s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
+ 		char *message;
+ 
+-		tds->oserr = sock_errno;
++		*p_oserr = sock_errno;
+ 		if (asprintf(&message, "tds_open_socket(): %s:%d", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)) >= 0) {
+ 			perror(message);
+ 			free(message);
+@@ -268,7 +257,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	/* enable non-blocking mode */
+ 	ioctl_nonblocking = 1;
+ 	if (IOCTLSOCKET(tds->s, FIONBIO, &ioctl_nonblocking) < 0) {
+-		tds->oserr = sock_errno;
++		*p_oserr = sock_errno;
+ 		tds_close_socket(tds);
+ 		return TDSEUSCT; 	/* close enough: "Unable to set communications timer" */
+ 	}
+@@ -277,7 +266,7 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	if (retval == 0) {
+ 		tdsdump_log(TDS_DBG_INFO2, "connection established\n");
+ 	} else {
+-		int err = tds->oserr = sock_errno;
++		int err = *p_oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "tds_open_socket: connect(2) returned \"%s\"\n", sock_strerror(err));
+ #if DEBUGGING_CONNECTING_PROBLEM
+ 		if (err != ECONNREFUSED && err != ENETUNREACH && err != TDSSOCK_EINPROGRESS) {
+@@ -308,12 +297,12 @@ tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int tim
+ 	optlen = sizeof(len);
+ 	len = 0;
+ 	if (tds_getsockopt(tds->s, SOL_SOCKET, SO_ERROR, (char *) &len, &optlen) != 0) {
+-		tds->oserr = sock_errno;
++		*p_oserr = sock_errno;
+ 		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) failed: %s\n", sock_strerror(sock_errno));
+ 		goto not_available;
+ 	}
+ 	if (len != 0) {
+-		tds->oserr = len;
++		*p_oserr = len;
+ 		tdsdump_log(TDS_DBG_ERROR, "getsockopt(2) reported: %s\n", sock_strerror(len));
+ 		goto not_available;
+ 	}
+
+commit 1d0607db4556b8b42eec4a956f2db9d91f28b95d
+Author: freddy77 <freddy77>
+Date:   Fri Jul 30 07:34:06 2010 +0000
+
+    simplify tds_get_byte
+
+diff --git a/ChangeLog b/ChangeLog
+index 8afc970..e656a36 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Fri Jul 30 09:33:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/read.c: simplify tds_get_byte
++
+ Fri Jul 30 09:29:34 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tds.h src/tds/login.c src/tds/net.c:
+ 	- remove oserr from tds_socket
+@@ -2782,4 +2785,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3100 2010/07/30 07:29:48 freddy77 Exp $
++$Id: ChangeLog,v 1.3101 2010/07/30 07:34:06 freddy77 Exp $
+diff --git a/src/tds/read.c b/src/tds/read.c
+index 2a38f51..9e5fad0 100644
+--- a/src/tds/read.c
++++ b/src/tds/read.c
+@@ -1,6 +1,6 @@
+ /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
+  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004  Brian Bruns
+- * Copyright (C) 2005, 2006, 2007  Frediano Ziglio
++ * Copyright (C) 2005, 2006, 2007, 2010  Frediano Ziglio
+  *
+  * This library is free software; you can redistribute it and/or
+  * modify it under the terms of the GNU Library General Public
+@@ -47,7 +47,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: read.c,v 1.111 2009/08/20 17:50:05 freddy77 Exp $");
++TDS_RCSID(var, "$Id: read.c,v 1.112 2010/07/30 07:34:06 freddy77 Exp $");
+ 
+ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ 			    size_t * wire_size, char **outbuf, size_t * outbytesleft);
+@@ -69,13 +69,9 @@ static int read_and_convert(TDSSOCKET * tds, const TDSICONV * char_conv,
+ unsigned char
+ tds_get_byte(TDSSOCKET * tds)
+ {
+-	int rc;
+-
+ 	while (tds->in_pos >= tds->in_len) {
+-		do {
+-			if (IS_TDSDEAD(tds) || (rc = tds_read_packet(tds)) < 0)
+-				return 0;
+-		} while (!rc);
++		if (tds_read_packet(tds) < 0)
++			return 0;
+ 	}
+ 	return tds->in_buf[tds->in_pos++];
+ }
+
+commit 72cb7e3a4608df5b0bd730b3f567994755afaf70
+Author: freddy77 <freddy77>
+Date:   Fri Jul 30 07:35:31 2010 +0000
+
+    module definition file with wide functions
+
+diff --git a/win32/FreeTDSW.def b/win32/FreeTDSW.def
+new file mode 100644
+index 0000000..43bca48
+--- /dev/null
++++ b/win32/FreeTDSW.def
+@@ -0,0 +1,114 @@
++EXPORTS
++	SQLAllocConnect
++	SQLAllocEnv
++	SQLAllocHandle
++	SQLAllocStmt
++	SQLBindCol
++	SQLBindParam
++	SQLBindParameter
++;	SQLBrowseConnect
++	SQLCancel
++	SQLCloseCursor
++	SQLColAttribute
++	SQLColAttributes
++	SQLColumnPrivileges
++	SQLColumns
++	SQLConnect
++	SQLCopyDesc
++	SQLDescribeCol
++;	SQLDescribeParam
++	SQLDisconnect
++	SQLDriverConnect
++	SQLEndTran
++	SQLError
++	SQLExecDirect
++	SQLExecute
++	SQLExtendedFetch
++	SQLFetch
++	SQLFetchScroll
++	SQLForeignKeys
++	SQLFreeConnect
++	SQLFreeEnv
++	SQLFreeHandle
++	SQLFreeStmt
++	SQLGetConnectAttr
++	SQLGetConnectOption
++	SQLGetCursorName
++	SQLGetData
++	SQLGetDescField
++	SQLGetDescRec
++	SQLGetDiagField
++	SQLGetDiagRec
++	SQLGetEnvAttr
++	SQLGetFunctions
++	SQLGetInfo
++	SQLGetStmtAttr
++	SQLGetStmtOption
++	SQLGetTypeInfo
++	SQLMoreResults
++	SQLNativeSql
++	SQLNumParams
++	SQLNumResultCols
++	SQLParamData
++	SQLParamOptions
++	SQLPrepare
++	SQLPrimaryKeys
++	SQLProcedureColumns
++	SQLProcedures
++	SQLPutData
++	SQLRowCount
++	SQLSetConnectAttr
++	SQLSetConnectOption
++	SQLSetCursorName
++	SQLSetDescField
++	SQLSetDescRec
++	SQLSetEnvAttr
++	SQLSetParam
++	SQLSetPos
++	SQLSetScrollOptions
++	SQLSetStmtAttr
++	SQLSetStmtOption
++	SQLSpecialColumns
++	SQLStatistics
++	SQLTablePrivileges
++	SQLTables
++	SQLTransact
++	ConfigDSN
++	ConfigDriver
++	ConfigTranslator
++	DllRegisterServer
++	DllUnregisterServer
++	SQLColAttributeW
++	SQLColumnPrivilegesW
++	SQLColumnsW
++	SQLConnectW
++	SQLDescribeColW
++	SQLDriverConnectW
++	SQLErrorW
++	SQLExecDirectW
++	SQLForeignKeysW
++	SQLGetConnectAttrW
++	SQLGetConnectOptionW
++	SQLGetCursorNameW
++	SQLGetDescFieldW
++	SQLGetDescRecW
++	SQLGetDiagFieldW
++	SQLGetDiagRecW
++	SQLGetInfoW
++	SQLGetTypeInfoW = SQLGetTypeInfo
++	SQLGetStmtAttrW
++	SQLNativeSqlW
++	SQLPrepareW
++	SQLPrimaryKeysW
++	SQLProcedureColumnsW
++	SQLProceduresW
++	SQLSetConnectAttrW
++	SQLSetConnectOptionW
++	SQLSetCursorNameW
++	SQLSetDescFieldW
++	SQLSetStmtAttrW
++	SQLSpecialColumnsW
++	SQLStatisticsW
++	SQLTablePrivilegesW
++	SQLTablesW
++
+
+commit 18b4eb658f87d5122ccd3134e6c3f5d38a58cd5e
+Author: freddy77 <freddy77>
+Date:   Fri Jul 30 09:09:36 2010 +0000
+
+    find a better way to export automatically without DEF changes
+
+diff --git a/ChangeLog b/ChangeLog
+index e656a36..95f173b 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Fri Jul 30 11:08:37 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac include/tdsodbc.h src/odbc/Makefile.am:
++	* src/odbc/odbc.c src/odbc/sqlwparams.h win32/FreeTDS.def:
++	* win32/Makefile.am:
++	- find a better way to export automatically without DEF changes
++
+ Fri Jul 30 09:33:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/read.c: simplify tds_get_byte
+ 
+@@ -2785,4 +2791,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3101 2010/07/30 07:34:06 freddy77 Exp $
++$Id: ChangeLog,v 1.3102 2010/07/30 09:09:36 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 73f08ee..386f776 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.53 2010/07/30 07:17:27 freddy77 Exp $
++dnl $Id: configure.ac,v 1.54 2010/07/30 09:09:36 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.53 $)
++AC_REVISION($Revision: 1.54 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -774,7 +774,6 @@ AC_ARG_ENABLE(odbc-wide,
+ if test "$enable_odbc_wide" = "yes" ; then
+ 	AC_DEFINE_UNQUOTED(ENABLE_ODBC_WIDE, 1, [Define to enable ODBC wide string support])
+ fi
+-AM_CONDITIONAL(ODBC_WIDE, test "$enable_odbc_wide" = "yes")
+ 
+ AC_ARG_ENABLE(distcheck_build,
+   AS_HELP_STRING([--enable-distcheck-build], [used internally for testing]))
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 5dbe87d..4d80815 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.124 2010/07/17 19:58:24 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.125 2010/07/30 09:09:36 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -75,6 +75,16 @@ extern "C"
+ #define ODBC_API SQL_API
+ #endif
+ 
++#if defined(_WIN32) || defined(__CYGWIN__)
++#  ifdef __GNUC__
++#    define ODBC_PUBLIC __attribute__((dllexport))
++#  else
++#    define ODBC_PUBLIC __declspec(dllexport)
++#  endif
++#else
++#  define ODBC_PUBLIC
++#endif
++
+ #define ODBC_MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #define ODBC_MIN(a,b) ( (a) < (b) ? (a) : (b) )
+ 
+diff --git a/src/odbc/Makefile.am b/src/odbc/Makefile.am
+index b2e1f7f..a21d8c3 100644
+--- a/src/odbc/Makefile.am
++++ b/src/odbc/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.49 2010/07/30 07:17:27 freddy77 Exp $
++# $Id: Makefile.am,v 1.50 2010/07/30 09:09:36 freddy77 Exp $
+ SUBDIRS		= unittests
+ AM_CPPFLAGS	=	-I$(top_srcdir)/include $(ODBC_INC)
+ 
+@@ -13,14 +13,9 @@ libtdsodbc_la_SOURCES=	odbc.c connectparams.c convert_tds2sql.c \
+ 	descriptor.c prepare_query.c odbc_util.c \
+ 	native.c sql2tds.c error.c odbc_checks.c sqlwchar.c sqlwparams.h $(MINGW_SOURCES)
+ if MINGW32
+-if ODBC_WIDE
+-DEFFILE = FreeTDSW.def
+-else
+-DEFFILE = FreeTDS.def
+-endif
+ libtdsodbc_la_LIBADD=	../../win32/setup.res ../tds/libtds.la ../replacements/libreplacements.la $(ODBCINSTLIB) \
+ 	$(NETWORK_LIBS) $(LIBICONV) $(FREETDS_LIBGCC)
+-libtdsodbc_la_LDFLAGS = -Wl,--enable-stdcall-fixup -Wl,-s -Wl,$(top_srcdir)/win32/$(DEFFILE) -Wl,../../win32/setup.res $(FREETDS_SYMBOLIC)
++libtdsodbc_la_LDFLAGS = -Wl,--kill-at -Wl,--enable-stdcall-fixup -Wl,-s -Wl,$(top_srcdir)/win32/FreeTDS.def -Wl,../../win32/setup.res $(FREETDS_SYMBOLIC)
+ 
+ .rc.res:
+ 	$(RC) -i $< -I $(top_builddir)/win32 --input-format=rc -o $@ -O coff
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 78c2773..a9db1be 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.548 2010/07/22 14:24:14 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.549 2010/07/30 09:09:36 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -2212,7 +2212,7 @@ SQLColAttribute(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
+ }
+ 
+ #ifdef ENABLE_ODBC_WIDE
+-SQLRETURN ODBC_API
++SQLRETURN ODBC_PUBLIC ODBC_API
+ SQLColAttributeW(SQLHSTMT hstmt, SQLUSMALLINT icol, SQLUSMALLINT fDescType,
+ 		SQLPOINTER rgbDesc, SQLSMALLINT cbDescMax, SQLSMALLINT FAR * pcbDesc,
+ #ifdef TDS_SQLCOLATTRIBUTE_SQLLEN
+@@ -4402,7 +4402,7 @@ SQLGetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGE
+ }
+ 
+ #ifdef ENABLE_ODBC_WIDE
+-SQLRETURN ODBC_API
++SQLRETURN ODBC_PUBLIC ODBC_API
+ SQLGetStmtAttrW(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER Value, SQLINTEGER BufferLength, SQLINTEGER * StringLength)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetStmtAttr(%p, %d, %p, %d, %p)\n",
+@@ -4805,7 +4805,7 @@ SQLGetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam)
+ }
+ 
+ #ifdef ENABLE_ODBC_WIDE
+-SQLRETURN ODBC_API
++SQLRETURN ODBC_PUBLIC ODBC_API
+ SQLGetConnectOptionW(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLPOINTER pvParam)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLGetConnectOptionW(%p, %u, %p)\n", hdbc, fOption, pvParam);
+@@ -5845,7 +5845,7 @@ SQLGetInfo(SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMA
+ }
+ 
+ #ifdef ENABLE_ODBC_WIDE
+-SQLRETURN ODBC_API
++SQLRETURN ODBC_PUBLIC ODBC_API
+ SQLGetInfoW(SQLHDBC hdbc, SQLUSMALLINT fInfoType, SQLPOINTER rgbInfoValue, SQLSMALLINT cbInfoValueMax,
+ 	   SQLSMALLINT FAR * pcbInfoValue)
+ {
+@@ -5965,6 +5965,7 @@ SQLGetTypeInfo(SQLHSTMT hstmt, SQLSMALLINT fSqlType)
+ 			strcat(sql, ",3");
+ 		}
+ 	} else {
++		/* FIXME MS ODBC translate SQL_TIMESTAMP to SQL_TYPE_TIMESTAMP even for ODBC 2 apps */
+ 		sprintf(sql, sql_templ, fSqlType);
+ 	}
+ 	if (SQL_SUCCESS != odbc_set_stmt_query(stmt, (ODBC_CHAR*) sql, strlen(sql) _wide0))
+@@ -6219,7 +6220,7 @@ SQLSetConnectOption(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
+ }
+ 
+ #ifdef ENABLE_ODBC_WIDE
+-SQLRETURN ODBC_API
++SQLRETURN ODBC_PUBLIC ODBC_API
+ SQLSetConnectOptionW(SQLHDBC hdbc, SQLUSMALLINT fOption, SQLULEN vParam)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLSetConnectOptionW(%p, %d, %u)\n", hdbc, fOption, (unsigned)vParam);
+@@ -6520,7 +6521,7 @@ SQLSetStmtAttr(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINT
+ }
+ 
+ #ifdef ENABLE_ODBC_WIDE
+-SQLRETURN ODBC_API
++SQLRETURN ODBC_PUBLIC ODBC_API
+ SQLSetStmtAttrW(SQLHSTMT hstmt, SQLINTEGER Attribute, SQLPOINTER ValuePtr, SQLINTEGER StringLength)
+ {
+ 	tdsdump_log(TDS_DBG_FUNC, "SQLSetStmtAttr(%p, %d, %p, %d)\n",
+diff --git a/src/odbc/sqlwparams.h b/src/odbc/sqlwparams.h
+index 8a83f67..3c8253c 100644
+--- a/src/odbc/sqlwparams.h
++++ b/src/odbc/sqlwparams.h
+@@ -20,7 +20,7 @@ static SQLRETURN FUNC;
+ #define NAME(a) a
+ #define WIDE
+ #define PCHAR(a) SQLCHAR* a
+-SQLRETURN ODBC_API FUNC {
++SQLRETURN ODBC_PUBLIC ODBC_API FUNC {
+ 
+ #undef NAME
+ #undef WIDE
+@@ -43,7 +43,7 @@ SQLRETURN ODBC_API FUNC {
+ #define WIDE
+ #define P(a,b) a b
+ #define PCHAR(a) SQLWCHAR * a
+-SQLRETURN ODBC_API FUNC {
++SQLRETURN ODBC_PUBLIC ODBC_API FUNC {
+ 
+ #undef NAME
+ #undef WIDE
+diff --git a/win32/FreeTDS.def b/win32/FreeTDS.def
+index 97ea274..67308dd 100644
+--- a/win32/FreeTDS.def
++++ b/win32/FreeTDS.def
+@@ -78,4 +78,5 @@ EXPORTS
+ 	ConfigTranslator
+ 	DllRegisterServer
+ 	DllUnregisterServer
++	SQLGetTypeInfoW = SQLGetTypeInfo
+ 
+diff --git a/win32/Makefile.am b/win32/Makefile.am
+index a92213e..78190d0 100644
+--- a/win32/Makefile.am
++++ b/win32/Makefile.am
+@@ -1,5 +1,5 @@
+ SUBDIRS	= msvc6
+-EXTRA_DIST      = config.h FreeTDS.def FreeTDSW.def initnet.c \
++EXTRA_DIST      = config.h FreeTDS.def initnet.c \
+ 		tds_sysdep_public.h freetds_sysconfdir.h \
+ 		winsetup.c winlogin.c \
+ 		setup.rc resource.h \
+
+commit 2d3713fd8e5e56fd2875f508bd0f5759b7e0216a
+Author: freddy77 <freddy77>
+Date:   Sat Jul 31 08:05:59 2010 +0000
+
+    fix link for iconv in unittests
+
+diff --git a/ChangeLog b/ChangeLog
+index 95f173b..e4506ed 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Sat Jul 31 10:05:48 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
++	* src/tds/unittests/Makefile.am:
++	- fix link for iconv in unittests
++
+ Fri Jul 30 11:08:37 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac include/tdsodbc.h src/odbc/Makefile.am:
+ 	* src/odbc/odbc.c src/odbc/sqlwparams.h win32/FreeTDS.def:
+@@ -2791,4 +2796,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3102 2010/07/30 09:09:36 freddy77 Exp $
++$Id: ChangeLog,v 1.3103 2010/07/31 08:05:59 freddy77 Exp $
+diff --git a/src/ctlib/unittests/Makefile.am b/src/ctlib/unittests/Makefile.am
+index 9c0301b..4dac0a2 100644
+--- a/src/ctlib/unittests/Makefile.am
++++ b/src/ctlib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.31 2009/02/11 14:40:15 freddy77 Exp $
++# $Id: Makefile.am,v 1.32 2010/07/31 08:05:59 freddy77 Exp $
+ 
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT) t0004$(EXEEXT) \
+ 			t0005$(EXEEXT) t0006$(EXEEXT) t0007$(EXEEXT) t0008$(EXEEXT) \
+@@ -48,5 +48,5 @@ AM_LDFLAGS	=	-no-fast-install
+ else
+ AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+-LIBS		=	../libct.la ../../replacements/libreplacements.la @NETWORK_LIBS@
++LIBS		=	../libct.la ../../replacements/libreplacements.la $(LIBICONV) @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+diff --git a/src/dblib/unittests/Makefile.am b/src/dblib/unittests/Makefile.am
+index df43a20..5ffbda1 100644
+--- a/src/dblib/unittests/Makefile.am
++++ b/src/dblib/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.49 2009/09/01 05:47:31 freddy77 Exp $
++# $Id: Makefile.am,v 1.50 2010/07/31 08:05:59 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) t0009$(EXEEXT)\
+@@ -61,7 +61,7 @@ AM_LDFLAGS	=	-no-fast-install
+ else
+ AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+-LIBS		=	../libsybdb.la ../../replacements/libreplacements.la @NETWORK_LIBS@
++LIBS		=	../libsybdb.la ../../replacements/libreplacements.la $(LIBICONV) @NETWORK_LIBS@
+ EXTRA_DIST	=	t0016.in t0017.in t0017.in.be data.bin $(EXTRA_DIST_WIN32) $(SQL_DIST)
+ CLEANFILES	=	tdsdump.out t0013.out t0014.out t0016.out \
+ 				t0016.err t0017.err t0017.out
+diff --git a/src/tds/unittests/Makefile.am b/src/tds/unittests/Makefile.am
+index cb11688..60f8a06 100644
+--- a/src/tds/unittests/Makefile.am
++++ b/src/tds/unittests/Makefile.am
+@@ -1,4 +1,4 @@
+-# $Id: Makefile.am,v 1.26 2009/02/11 14:40:15 freddy77 Exp $
++# $Id: Makefile.am,v 1.27 2010/07/31 08:05:59 freddy77 Exp $
+ TESTS		=	t0001$(EXEEXT) t0002$(EXEEXT) t0003$(EXEEXT)\
+ 			t0004$(EXEEXT) t0005$(EXEEXT) t0006$(EXEEXT)\
+ 			t0007$(EXEEXT) t0008$(EXEEXT) dynamic1$(EXEEXT)\
+@@ -36,5 +36,5 @@ AM_LDFLAGS	=	-no-fast-install
+ else
+ AM_LDFLAGS	=	-no-install -L../.libs -R $(abs_builddir)/../.libs
+ endif
+-LIBS		=	../libtds.la ../../replacements/libreplacements.la @NETWORK_LIBS@
++LIBS		=	../libtds.la ../../replacements/libreplacements.la $(LIBICONV) @NETWORK_LIBS@
+ CLEANFILES	=	tdsdump.out
+
+commit a8e033f25853c7c7e6d12241b1be430ceefa36b9
+Author: freddy77 <freddy77>
+Date:   Sat Jul 31 11:20:34 2010 +0000
+
+    allow mutex declaration inside structures
+
+diff --git a/ChangeLog b/ChangeLog
+index e4506ed..dd56276 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 31 13:20:26 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsthread.h: allow mutex declaration inside structures
++
+ Sat Jul 31 10:05:48 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/unittests/Makefile.am src/dblib/unittests/Makefile.am:
+ 	* src/tds/unittests/Makefile.am:
+@@ -2796,4 +2799,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3103 2010/07/31 08:05:59 freddy77 Exp $
++$Id: ChangeLog,v 1.3104 2010/07/31 11:20:34 freddy77 Exp $
+diff --git a/include/tdsthread.h b/include/tdsthread.h
+index 92a17b8..9b24677 100644
+--- a/include/tdsthread.h
++++ b/include/tdsthread.h
+@@ -22,7 +22,7 @@
+ #ifndef TDSTHREAD_H
+ #define TDSTHREAD_H 1
+ 
+-/* $Id: tdsthread.h,v 1.7 2010/02/12 10:16:17 freddy77 Exp $ */
++/* $Id: tdsthread.h,v 1.8 2010/07/31 11:20:35 freddy77 Exp $ */
+ 
+ #undef TDS_HAVE_MUTEX
+ 
+@@ -31,8 +31,11 @@
+ #include <pthread.h>
+ 
+ #define TDS_MUTEX_DEFINE(name) pthread_mutex_t name = PTHREAD_MUTEX_INITIALIZER
+-#define TDS_MUTEX_LOCK(a) pthread_mutex_lock(a)
+-#define TDS_MUTEX_UNLOCK(a) pthread_mutex_unlock(a)
++#define TDS_MUTEX_LOCK(mtx) pthread_mutex_lock(mtx)
++#define TDS_MUTEX_UNLOCK(mtx) pthread_mutex_unlock(mtx)
++#define TDS_MUTEX_DECLARE(name) pthread_mutex_t name
++#define TDS_MUTEX_INIT(mtx) do { *(mtx) = PTHREAD_MUTEX_INITIALIZER; } while(0)
++#define TDS_MUTEX_FREE(mtx) pthread_mutex_destroy(mtx)
+ 
+ #define TDS_HAVE_MUTEX 1
+ 
+@@ -50,17 +53,23 @@ void tds_win_mutex_lock(tds_win_mutex_t *mutex);
+ /* void tds_win_mutex_unlock(tds_win_mutex_t *mutex); */
+ 
+ #define TDS_MUTEX_DEFINE(name) tds_win_mutex_t name = { NULL, 0 }
+-#define TDS_MUTEX_LOCK(a) \
+-	do { if ((a)->done) EnterCriticalSection(&(a)->crit); else tds_win_mutex_lock(a); } while(0)
+-#define TDS_MUTEX_UNLOCK(a) LeaveCriticalSection(&(a)->crit)
++#define TDS_MUTEX_LOCK(mtx) \
++	do { if ((mtx)->done) EnterCriticalSection(&(mtx)->crit); else tds_win_mutex_lock(mtx); } while(0)
++#define TDS_MUTEX_UNLOCK(mtx) LeaveCriticalSection(&(mtx)->crit)
++#define TDS_MUTEX_DECLARE(name) tds_win_mutex_t name
++#define TDS_MUTEX_INIT(mtx) do { (mtx)->lock = NULL; (mtx)->done = 0; } while(0)
++#define TDS_MUTEX_FREE(mtx) do { if ((mtx)->done) { DeleteCriticalSection(&(mtx)->crit); (mtx)->done = 0; } } while(0)
+ 
+ #define TDS_HAVE_MUTEX 1
+ 
+ #else
+ 
+ #define TDS_MUTEX_DEFINE(name) int name
+-#define TDS_MUTEX_LOCK(a)
+-#define TDS_MUTEX_UNLOCK(a)
++#define TDS_MUTEX_LOCK(mtx)
++#define TDS_MUTEX_UNLOCK(mtx)
++#define TDS_MUTEX_DECLARE(name) int name
++#define TDS_MUTEX_INIT(mtx)
++#define TDS_MUTEX_FREE(mtx)
+ 
+ #endif
+ 
+
+commit bbfe973c526bf8e42a018f9d360a5ff7414d862f
+Author: freddy77 <freddy77>
+Date:   Sat Jul 31 11:31:15 2010 +0000
+
+    fix bcp_bind with vartype == 0
+
+diff --git a/ChangeLog b/ChangeLog
+index dd56276..ac2f660 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Sat Jul 31 13:31:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/dblib/bcp.c: fix bcp_bind with vartype == 0
++
+ Sat Jul 31 13:20:26 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/tdsthread.h: allow mutex declaration inside structures
+ 
+@@ -2799,4 +2802,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3104 2010/07/31 11:20:34 freddy77 Exp $
++$Id: ChangeLog,v 1.3105 2010/07/31 11:31:15 freddy77 Exp $
+diff --git a/src/dblib/bcp.c b/src/dblib/bcp.c
+index c0c4a30..6c2dbaa 100644
+--- a/src/dblib/bcp.c
++++ b/src/dblib/bcp.c
+@@ -62,7 +62,7 @@
+ #define MAX(a,b) ( (a) > (b) ? (a) : (b) )
+ #endif
+ 
+-TDS_RCSID(var, "$Id: bcp.c,v 1.194 2010/02/12 10:16:17 freddy77 Exp $");
++TDS_RCSID(var, "$Id: bcp.c,v 1.195 2010/07/31 11:31:16 freddy77 Exp $");
+ 
+ #ifdef HAVE_FSEEKO
+ typedef off_t offset_type;
+@@ -2386,7 +2386,7 @@ _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset)
+ 	TDS_SMALLINT si;
+ 	TDS_INT li;
+ 	TDS_INT desttype;
+-	int collen;
++	int collen, coltype;
+ 	int data_is_null;
+ 	int bytes_read;
+ 	int converted_data_size;
+@@ -2442,10 +2442,12 @@ _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset)
+ 		}
+ 	}
+ 
+-	/* Fixed Length data - this overrides anything else specified */
++	desttype = tds_get_conversion_type(bindcol->column_type, bindcol->column_size);
+ 
+-	if (is_fixed_type(bindcol->column_bindtype)) {
+-		collen = tds_get_size_by_type(bindcol->column_bindtype);
++	/* Fixed Length data - this overrides anything else specified */
++	coltype = bindcol->column_bindtype == 0 ? desttype : bindcol->column_bindtype;
++	if (is_fixed_type(coltype)) {
++		collen = tds_get_size_by_type(coltype);
+ 	}
+ 
+ 	/* read the data, finally */
+@@ -2466,10 +2468,8 @@ _bcp_get_col_data(TDSBCPINFO *bcpinfo, TDSCOLUMN *bindcol, int offset)
+ 		bindcol->bcp_column_data->datalen = 0;
+ 		bindcol->bcp_column_data->is_null = 1;
+ 	} else {
+-		desttype = tds_get_conversion_type(bindcol->column_type, bindcol->column_size);
+-
+ 		if ((converted_data_size =
+-		     dbconvert(dbproc, bindcol->column_bindtype,
++		     dbconvert(dbproc, coltype,
+ 			       (BYTE *) dataptr, collen,
+ 			       desttype, bindcol->bcp_column_data->data, bindcol->column_size)) == FAIL) {
+ 			return TDS_FAIL;
+
+commit 07b0cdf9b2c3f25ea731704ec04faaa183a14b2f
+Author: freddy77 <freddy77>
+Date:   Wed Aug 4 06:55:45 2010 +0000
+
+    fix problem for pyodbc and money
+
+diff --git a/ChangeLog b/ChangeLog
+index ac2f660..0dbd95f 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,9 @@
++Wed Aug  4 08:55:25 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/odbc_util.c:
++	* src/odbc/unittests/describecol.c:
++	* src/odbc/unittests/describecol.in:
++	- fix problem for pyodbc and money
++
+ Sat Jul 31 13:31:08 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/dblib/bcp.c: fix bcp_bind with vartype == 0
+ 
+@@ -2802,4 +2808,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3105 2010/07/31 11:31:15 freddy77 Exp $
++$Id: ChangeLog,v 1.3106 2010/08/04 06:55:45 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index a9db1be..0359783 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.549 2010/07/30 09:09:36 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.550 2010/08/04 06:55:45 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -3010,10 +3010,7 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		if (!tds_dstr_copyn(&drec->sql_desc_label, col->column_name, col->column_namelen))
+ 			return SQL_ERROR;
+ 
+-		/* TODO other types for date ?? SQL_TYPE_DATE, SQL_TYPE_TIME */
+-		if (drec->sql_desc_concise_type == SQL_TIMESTAMP || drec->sql_desc_concise_type == SQL_TYPE_TIMESTAMP)
+-			drec->sql_desc_length = sizeof("2000-01-01 12:00:00.0000")-1;
+-		else switch (drec->sql_desc_concise_type) {
++		switch (drec->sql_desc_concise_type) {
+ 		case SQL_WCHAR:
+ 		case SQL_WVARCHAR:
+ 		case SQL_WLONGVARCHAR:
+@@ -3085,7 +3082,7 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		drec->sql_desc_unnamed = tds_dstr_isempty(&drec->sql_desc_name) ? SQL_UNNAMED : SQL_NAMED;
+ 		/* TODO use is_nullable_type ?? */
+ 		drec->sql_desc_nullable = col->column_nullable ? SQL_TRUE : SQL_FALSE;
+-		if (drec->sql_desc_concise_type == SQL_NUMERIC || drec->sql_desc_concise_type == SQL_DECIMAL) {
++		if (drec->sql_desc_concise_type == SQL_NUMERIC) {
+ 			drec->sql_desc_num_prec_radix = 10;
+ 			drec->sql_desc_octet_length = col->column_prec + 2;
+ 		} else {
+@@ -3104,10 +3101,26 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		}
+ 
+ 		drec->sql_desc_octet_length_ptr = NULL;
+-		drec->sql_desc_precision = type == SYBDATETIME ? 3 : col->column_prec;
++		switch (type) {
++		case SYBDATETIME:
++			drec->sql_desc_precision = 3;
++			drec->sql_desc_scale     = 3;
++			break;
++		case SYBMONEY:
++			drec->sql_desc_precision = 19;
++			drec->sql_desc_scale     = 4;
++			break;
++		case SYBMONEY4:
++			drec->sql_desc_precision = 10;
++			drec->sql_desc_scale     = 4;
++			break;
++		default:
++			drec->sql_desc_precision = col->column_prec;
++			drec->sql_desc_scale     = col->column_scale;
++			break;
++		}
+ 		/* TODO test timestamp from db, FOR BROWSE query */
+ 		drec->sql_desc_rowver = SQL_FALSE;
+-		drec->sql_desc_scale = type == SYBDATETIME ? 3 : ((type == SYBMONEY || type == SYBMONEY4) ? 4 : col->column_scale);
+ 		/* TODO seem not correct */
+ 		drec->sql_desc_searchable = (drec->sql_desc_unnamed == SQL_NAMED) ? SQL_PRED_SEARCHABLE : SQL_UNSEARCHABLE;
+ 		/* TODO perhaps TINYINY and BIT.. */
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index d98d30e..2f85969 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.121 2010/07/24 08:26:01 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.122 2010/08/04 06:55:45 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -703,7 +703,7 @@ odbc_server_to_sql_type(int col_type, int col_size)
+ 	case SYBMONEY:
+ 	case SYBMONEY4:
+ 	case SYBMONEYN:
+-		return SQL_FLOAT;
++		return SQL_DECIMAL;
+ 	case SYBDATETIME:
+ 	case SYBDATETIME4:
+ 	case SYBDATETIMN:
+@@ -852,11 +852,17 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ 	switch (tds_get_conversion_type(col->column_type, col->column_size)) {
+ 	case XSYBCHAR:
+ 	case SYBCHAR:
++		if (col->column_type == XSYBNCHAR)
++			SET_INFO("nchar", "'", "'");
+ 		SET_INFO("char", "'", "'");
+ 	case XSYBVARCHAR:
+ 	case SYBVARCHAR:
++		if (col->column_type == SYBNVARCHAR || col->column_type == XSYBNVARCHAR)
++			SET_INFO("nvarchar", "'", "'");
+ 		SET_INFO("varchar", "'", "'");
+ 	case SYBTEXT:
++		if (col->column_type == SYBNTEXT)
++			SET_INFO("ntext", "'", "'");
+ 		SET_INFO("text", "'", "'");
+ 	case SYBBIT:
+ 	case SYBBITN:
+@@ -913,7 +919,7 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ 		/* FIXME for Sybase ?? */
+ 		SET_INFO2("uniqueidentifier", "'", "'", 36);
+ 	case SYBVARIANT:
+-		/* SET_INFO("sql_variant", "", ""); */
++		SET_INFO("sql_variant", "", "");
+ 		break;
+ #endif
+ 	case SYBMSXML:
+@@ -963,7 +969,13 @@ odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col)
+ 		break;
+ 	case SQL_DECIMAL:
+ 	case SQL_NUMERIC:
+-		size = col->column_prec + 2;
++		/* TODO check money format returned by propretary ODBC, scale == 4 but we use 2 digits */
++		if (col->column_type == SYBMONEY || (col->column_type == SYBMONEYN && col->column_size == 8))
++			size = 21;
++		else if (col->column_type == SYBMONEY4 || (col->column_type == SYBMONEYN && col->column_size == 4))
++			size = 12;
++		else
++			size = col->column_prec + 2;
+ 		break;
+ 	case SQL_DATE:
+ 	case SQL_TYPE_DATE:
+@@ -989,11 +1001,6 @@ odbc_sql_to_displaysize(int sqltype, TDSCOLUMN *col)
+ 		/* TODO check REAL/FLOAT format */
+ 		if (col->column_type == SYBREAL || (col->column_type == SYBFLTN && col->column_size == 4))
+ 			size = 14;
+-		/* TODO check money format returned by propretary ODBC, scale == 4 but we use 2 digits */
+-		else if (col->column_type == SYBMONEY || (col->column_type == SYBMONEYN && col->column_size == 8))
+-			size = 21;
+-		else if (col->column_type == SYBMONEY4 || (col->column_type == SYBMONEYN && col->column_size == 4))
+-			size = 12;
+ 		else 
+ 			size = 24;	/* FIXME -- what should the correct size be? */
+ 		break;
+diff --git a/src/odbc/unittests/describecol.c b/src/odbc/unittests/describecol.c
+index 502de42..f2ad1e4 100644
+--- a/src/odbc/unittests/describecol.c
++++ b/src/odbc/unittests/describecol.c
+@@ -6,7 +6,7 @@
+  * test what say SQLDescribeCol about precision using some type
+  */
+ 
+-static char software_version[] = "$Id: describecol.c,v 1.18 2010/07/05 09:20:33 freddy77 Exp $";
++static char software_version[] = "$Id: describecol.c,v 1.19 2010/08/04 06:55:45 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ static int g_result = 0;
+@@ -115,6 +115,7 @@ static const struct attribute attributes[] = {
+ 	ATTR(SQL_DESC_PRECISION, SMALLINT),
+ 	ATTR(SQL_DESC_SCALE, SMALLINT),
+ 	ATTR(SQL_DESC_DISPLAY_SIZE, INTEGER),
++	ATTR(SQL_DESC_TYPE_NAME, CHARP),
+ 	ATTR2(SQL_DESC_CONCISE_TYPE, SMALLINT, sql_types),
+ 	ATTR2(SQL_DESC_TYPE, SMALLINT, sql_types)
+ #undef ATTR2
+@@ -137,17 +138,30 @@ lookup_attr(const char *name)
+ 
+ #define SEP " \t\n"
+ 
+-#define ATTR_PARAMS const struct attribute *attr, int expected
+-typedef int (*get_attr_t) (ATTR_PARAMS);
++#define ATTR_PARAMS const struct attribute *attr, const char *expected_value
++typedef void (*check_attr_t) (ATTR_PARAMS);
+ 
+-static int
+-get_attr_ird(ATTR_PARAMS)
++static void
++check_attr_ird(ATTR_PARAMS)
+ {
+ 	SQLLEN i;
+ 	SQLRETURN ret;
+ 
+-	if (attr->type == type_CHARP)
+-		fatal("Line %u: CHAR* check still not supported\n", line_num);
++	if (attr->type == type_CHARP) {
++		char buf[128];
++		SQLSMALLINT len;
++
++		ret = SQLColAttribute(odbc_stmt, 1, attr->value, buf, sizeof(buf), &len, NULL);
++		if (!SQL_SUCCEEDED(ret))
++			fatal("Line %u: failure not expected\n", line_num);
++		buf[sizeof(buf)-1] = 0;
++		if (strcmp(buf, expected_value) != 0) {
++			g_result = 1;
++			fprintf(stderr, "Line %u: invalid %s got %s expected %s\n", line_num, attr->name, buf, expected_value);
++		}
++		return;
++	}
++
+ 	i = 0xdeadbeef;
+ 	ret = SQLColAttribute(odbc_stmt, 1, attr->value, NULL, SQL_IS_INTEGER, NULL, &i);
+ 	if (!SQL_SUCCEEDED(ret))
+@@ -160,17 +174,21 @@ get_attr_ird(ATTR_PARAMS)
+ 		if (i != li)
+ 			fatal("Line %u: attr %s SQLDescribeCol len %ld != SQLColAttribute len %ld\n", line_num, attr->name, (long) li, (long) i);
+ 	}
+-	return i;
++	if (i != lookup(expected_value, attr->lookup)) {
++		g_result = 1;
++		fprintf(stderr, "Line %u: invalid %s got %ld expected %s\n", line_num, attr->name, (long int) i, expected_value);
++	}
+ }
+ 
+-static int
+-get_attr_ard(ATTR_PARAMS)
++static void
++check_attr_ard(ATTR_PARAMS)
+ {
+ 	SQLINTEGER i, ind;
+ 	SQLSMALLINT si;
+ 	SQLLEN li;
+ 	SQLRETURN ret;
+ 	SQLHDESC desc = SQL_NULL_HDESC;
++	char buf[128];
+ 
+ 	/* get ARD */
+ 	SQLGetStmtAttr(odbc_stmt, SQL_ATTR_APP_ROW_DESC, &desc, sizeof(desc), &ind);
+@@ -192,19 +210,27 @@ get_attr_ard(ATTR_PARAMS)
+ 		i = li;
+ 		break;
+ 	case type_CHARP:
+-		fatal("Line %u: CHAR* check still not supported\n", line_num);
+-		break;
++		ret = SQLGetDescField(desc, 1, attr->value, buf, sizeof(buf), &ind);
++		if (!SQL_SUCCEEDED(ret))
++			fatal("Line %u: failure not expected\n", line_num);
++		if (strcmp(buf, expected_value) != 0) {
++			g_result = 1;
++			fprintf(stderr, "Line %u: invalid %s got %s expected %s\n", line_num, attr->name, buf, expected_value);
++		}
++		return;
+ 	}
+ 	if (!SQL_SUCCEEDED(ret))
+ 		fatal("Line %u: failure not expected\n", line_num);
+-	return i;
++	if (i != lookup(expected_value, attr->lookup)) {
++		g_result = 1;
++		fprintf(stderr, "Line %u: invalid %s got %ld expected %s\n", line_num, attr->name, (long int) i, expected_value);
++	}
+ }
+ 
+ /* do not retry any attribute just return expected value so to make caller happy */
+-static int
+-get_attr_none(ATTR_PARAMS)
++static void
++check_attr_none(ATTR_PARAMS)
+ {
+-	return expected;
+ }
+ 
+ int
+@@ -216,7 +242,7 @@ main(int argc, char *argv[])
+ 	char buf[256];
+ 	SQLINTEGER i;
+ 	SQLLEN len;
+-	get_attr_t get_attr_p = get_attr_none;
++	check_attr_t check_attr_p = check_attr_none;
+ 
+ 	odbc_connect();
+ 	odbc_command("SET TEXTSIZE 4096");
+@@ -269,7 +295,7 @@ main(int argc, char *argv[])
+ 			sprintf(sql, "SELECT CONVERT(%s, %s) AS col", type, value);
+ 
+ 			/* ignore error, we only need precision of known types */
+-			get_attr_p = get_attr_none;
++			check_attr_p = check_attr_none;
+ 			if (odbc_command_with_result(odbc_stmt, sql) != SQL_SUCCESS) {
+ 				odbc_reset_statement();
+ 				SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+@@ -278,7 +304,7 @@ main(int argc, char *argv[])
+ 
+ 			CHKFetch("SI");
+ 			SQLBindCol(odbc_stmt, 1, SQL_C_SLONG, &i, sizeof(i), &len);
+-			get_attr_p = get_attr_ird;
++			check_attr_p = check_attr_ird;
+ 		}
+ 
+ 		/* set attribute */
+@@ -315,23 +341,18 @@ main(int argc, char *argv[])
+ 			}
+ 			if (!SQL_SUCCEEDED(ret))
+ 				fatal("Line %u: failure not expected setting ARD attribute\n", line_num);
+-			get_attr_p = get_attr_ard;
++			check_attr_p = check_attr_ard;
+ 		}
+ 
+ 		/* test attribute */
+ 		if (strcmp(cmd, "attr") == 0) {
+ 			const struct attribute *attr = lookup_attr(strtok(NULL, SEP));
+-			char *value = strtok(NULL, SEP);
+-			int i, expected = lookup(value, attr->lookup);
++			char *expected = strtok(NULL, SEP);
+ 
+-			if (!value)
++			if (!expected)
+ 				fatal("Line %u: value not defined\n", line_num);
+ 
+-			i = get_attr_p(attr, expected);
+-			if (i != expected) {
+-				g_result = 1;
+-				fprintf(stderr, "Line %u: invalid %s got %d expected %d\n", line_num, attr->name, i, expected);
+-			}
++			check_attr_p(attr, expected);
+ 		}
+ 	}
+ 
+diff --git a/src/odbc/unittests/describecol.in b/src/odbc/unittests/describecol.in
+index f8217c1..cf941ee 100644
+--- a/src/odbc/unittests/describecol.in
++++ b/src/odbc/unittests/describecol.in
+@@ -9,6 +9,7 @@ attr SQL_DESC_OCTET_LENGTH 1
+ attr SQL_DESC_PRECISION 1
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 1
++attr SQL_DESC_TYPE_NAME bit
+ 
+ select tinyint 0
+ attr SQL_COLUMN_LENGTH 1
+@@ -79,6 +80,7 @@ attr SQL_DESC_OCTET_LENGTH 12
+ attr SQL_DESC_PRECISION 10
+ attr SQL_DESC_SCALE 4
+ attr SQL_DESC_DISPLAY_SIZE 12
++attr SQL_DESC_CONCISE_TYPE SQL_DECIMAL
+ 
+ select money 0
+ attr SQL_COLUMN_LENGTH 21
+@@ -89,6 +91,7 @@ attr SQL_DESC_OCTET_LENGTH 21
+ attr SQL_DESC_PRECISION 19
+ attr SQL_DESC_SCALE 4
+ attr SQL_DESC_DISPLAY_SIZE 21
++attr SQL_DESC_CONCISE_TYPE SQL_DECIMAL
+ 
+ select numeric(10,2) 0
+ attr SQL_COLUMN_LENGTH 12
+@@ -161,6 +164,7 @@ attr SQL_DESC_OCTET_LENGTH 24
+ attr SQL_DESC_PRECISION 12
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 12
++attr SQL_DESC_TYPE_NAME nchar
+ 
+ select nvarchar(13) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 26
+@@ -171,6 +175,7 @@ attr SQL_DESC_OCTET_LENGTH 26
+ attr SQL_DESC_PRECISION 13
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 13
++attr SQL_DESC_TYPE_NAME nvarchar
+ 
+ select text 'hi!'
+ attr SQL_COLUMN_LENGTH 4096
+@@ -191,6 +196,7 @@ attr SQL_DESC_OCTET_LENGTH 4096
+ attr SQL_DESC_PRECISION 2048
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 2048
++attr SQL_DESC_TYPE_NAME ntext
+ 
+ select binary(10) 'hi!'
+ attr SQL_COLUMN_LENGTH 10
+@@ -305,6 +311,7 @@ attr SQL_DESC_OCTET_LENGTH 12
+ attr SQL_DESC_PRECISION 10
+ attr SQL_DESC_SCALE 4
+ attr SQL_DESC_DISPLAY_SIZE 12
++attr SQL_DESC_CONCISE_TYPE SQL_DECIMAL
+ 
+ select money 0
+ attr SQL_COLUMN_LENGTH 21
+@@ -315,6 +322,7 @@ attr SQL_DESC_OCTET_LENGTH 21
+ attr SQL_DESC_PRECISION 19
+ attr SQL_DESC_SCALE 4
+ attr SQL_DESC_DISPLAY_SIZE 21
++attr SQL_DESC_CONCISE_TYPE SQL_DECIMAL
+ 
+ select numeric(10,2) 0
+ attr SQL_COLUMN_LENGTH 12
+@@ -387,6 +395,7 @@ attr SQL_DESC_OCTET_LENGTH 24
+ attr SQL_DESC_PRECISION 12
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 12
++attr SQL_DESC_TYPE_NAME nchar
+ 
+ select nvarchar(13) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 26
+@@ -397,6 +406,7 @@ attr SQL_DESC_OCTET_LENGTH 26
+ attr SQL_DESC_PRECISION 13
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 13
++attr SQL_DESC_TYPE_NAME nvarchar
+ 
+ select text 'hi!'
+ attr SQL_COLUMN_LENGTH 4096
+@@ -417,6 +427,7 @@ attr SQL_DESC_OCTET_LENGTH 4096
+ attr SQL_DESC_PRECISION 2048
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 2048
++attr SQL_DESC_TYPE_NAME ntext
+ 
+ select binary(10) 'hi!'
+ attr SQL_COLUMN_LENGTH 10
+@@ -457,6 +468,31 @@ attr SQL_DESC_OCTET_LENGTH 16
+ attr SQL_DESC_PRECISION 36
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 36
++attr SQL_DESC_TYPE_NAME uniqueidentifier
++
++select sql_variant 'hello'
++#attr SQL_COLUMN_LENGTH 0
++#attr SQL_COLUMN_PRECISION 8000
++attr SQL_COLUMN_SCALE 0
++#attr SQL_DESC_LENGTH 8000
++#attr SQL_DESC_OCTET_LENGTH 0
++#attr SQL_DESC_PRECISION 8000
++attr SQL_DESC_SCALE 0
++#attr SQL_DESC_DISPLAY_SIZE 8000
++attr SQL_DESC_TYPE_NAME sql_variant
++
++select int 654
++
++select sql_variant 123
++#attr SQL_COLUMN_LENGTH 0
++#attr SQL_COLUMN_PRECISION 8000
++attr SQL_COLUMN_SCALE 0
++#attr SQL_DESC_LENGTH 8000
++#attr SQL_DESC_OCTET_LENGTH 0
++#attr SQL_DESC_PRECISION 8000
++attr SQL_DESC_SCALE 0
++#attr SQL_DESC_DISPLAY_SIZE 8000
++attr SQL_DESC_TYPE_NAME sql_variant
+ 
+ 
+ 
+
+commit 88e66634309c29a940a4336d6f1053f4f99fe4f3
+Author: freddy77 <freddy77>
+Date:   Wed Aug 4 07:09:19 2010 +0000
+
+    remove assumption CS_FAIL == TDS_FAIL and CS_SUCCEED == TDS_SUCCEED
+
+diff --git a/ChangeLog b/ChangeLog
+index 0dbd95f..bbd7217 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Wed Aug  4 09:08:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/ctlib/cs.c src/ctlib/ctutil.c:
++	- remove assumption CS_FAIL == TDS_FAIL and CS_SUCCEED ==
++	  TDS_SUCCEED
++
+ Wed Aug  4 08:55:25 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/odbc_util.c:
+ 	* src/odbc/unittests/describecol.c:
+@@ -2808,4 +2813,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3106 2010/08/04 06:55:45 freddy77 Exp $
++$Id: ChangeLog,v 1.3107 2010/08/04 07:09:19 freddy77 Exp $
+diff --git a/src/ctlib/cs.c b/src/ctlib/cs.c
+index 14f126b..7a9a515 100644
+--- a/src/ctlib/cs.c
++++ b/src/ctlib/cs.c
+@@ -50,7 +50,7 @@
+ #include "tdsconvert.h"
+ #include "replacements.h"
+ 
+-TDS_RCSID(var, "$Id: cs.c,v 1.74 2010/04/13 13:19:12 freddy77 Exp $");
++TDS_RCSID(var, "$Id: cs.c,v 1.75 2010/08/04 07:09:19 freddy77 Exp $");
+ 
+ static int _cs_datatype_length(int dtype);
+ static CS_INT cs_diag_storemsg(CS_CONTEXT *context, CS_CLIENTMSG *message);
+@@ -1131,7 +1131,7 @@ cs_strbuild(CS_CONTEXT * ctx, CS_CHAR * buffer, CS_INT buflen, CS_INT * resultle
+ 	    CS_CHAR * formats, CS_INT formatlen, ...)
+ {
+ 	va_list ap;
+-	CS_RETCODE rc;
++	int rc;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "cs_strbuild(%p, %p, %d, %p, %p, %d, %p, %d)\n", 
+ 				ctx, buffer, buflen, resultlen, text, textlen, formats, formatlen);
+@@ -1139,7 +1139,8 @@ cs_strbuild(CS_CONTEXT * ctx, CS_CHAR * buffer, CS_INT buflen, CS_INT * resultle
+ 	va_start(ap, formatlen);
+ 	rc = tds_vstrbuild(buffer, buflen, resultlen, text, textlen, formats, formatlen, ap);
+ 	va_end(ap);
+-	return rc;
++
++	return rc == TDS_SUCCEED ? CS_SUCCEED : CS_FAIL;
+ }
+ 
+ CS_RETCODE
+diff --git a/src/ctlib/ctutil.c b/src/ctlib/ctutil.c
+index 900d55e..ada1778 100644
+--- a/src/ctlib/ctutil.c
++++ b/src/ctlib/ctutil.c
+@@ -32,7 +32,7 @@
+ /* #include "fortify.h" */
+ 
+ 
+-TDS_RCSID(var, "$Id: ctutil.c,v 1.30 2009/05/03 19:32:57 jklowden Exp $");
++TDS_RCSID(var, "$Id: ctutil.c,v 1.31 2010/08/04 07:09:19 freddy77 Exp $");
+ 
+ /*
+  * test include consistency 
+@@ -50,8 +50,6 @@ TDS_RCSID(var, "$Id: ctutil.c,v 1.30 2009/05/03 19:32:57 jklowden Exp $");
+ 
+ #define TEST_EQUAL(t,a,b) COMPILE_CHECK(t,a==b)
+ 
+-TEST_EQUAL(t01,CS_FAIL,TDS_FAIL);
+-TEST_EQUAL(t02,CS_SUCCEED,TDS_SUCCEED);
+ TEST_EQUAL(t03,CS_NULLTERM,TDS_NULLTERM);
+ TEST_EQUAL(t04,CS_CMD_SUCCEED,TDS_CMD_SUCCEED);
+ TEST_EQUAL(t05,CS_CMD_FAIL,TDS_CMD_FAIL);
+@@ -150,7 +148,7 @@ _ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG
+ 	CS_SERVERMSG errmsg;
+ 	CS_CONNECTION *con = NULL;
+ 	CS_CONTEXT *ctx = NULL;
+-	int ret = (int) CS_SUCCEED;
++	CS_RETCODE ret = CS_SUCCEED;
+ 
+ 	tdsdump_log(TDS_DBG_FUNC, "_ct_handle_server_message(%p, %p, %p)\n", ctx_tds, tds, msg);
+ 
+@@ -187,5 +185,5 @@ _ct_handle_server_message(const TDSCONTEXT * ctx_tds, TDSSOCKET * tds, TDSMESSAG
+ 	} else if (con->ctx->_servermsg_cb) {
+ 		ret = con->ctx->_servermsg_cb(con->ctx, con, &errmsg);
+ 	}
+-	return ret;
++	return ret == CS_SUCCEED ? TDS_SUCCEED : TDS_FAIL;
+ }
+
+commit 09462375fbc19a2a71efee40dea16836f2d8295b
+Author: freddy77 <freddy77>
+Date:   Wed Aug 4 08:04:48 2010 +0000
+
+    fix macro for odbc_set_sql_type_info
+
+diff --git a/ChangeLog b/ChangeLog
+index bbd7217..74ce2cd 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,7 @@
++Wed Aug  4 10:04:33 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc_util.c src/odbc/unittests/describecol.in:
++	- fix macro for odbc_set_sql_type_info
++
+ Wed Aug  4 09:08:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/ctlib/cs.c src/ctlib/ctutil.c:
+ 	- remove assumption CS_FAIL == TDS_FAIL and CS_SUCCEED ==
+@@ -2813,4 +2817,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3107 2010/08/04 07:09:19 freddy77 Exp $
++$Id: ChangeLog,v 1.3108 2010/08/04 08:04:48 freddy77 Exp $
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 2f85969..440d5df 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.122 2010/08/04 06:55:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.123 2010/08/04 08:04:48 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -839,29 +839,31 @@ odbc_c_to_server_type(int c_type)
+ void
+ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_ver)
+ {
+-#define SET_INFO(type, prefix, suffix) \
++#define SET_INFO(type, prefix, suffix) do { \
+ 	drec->sql_desc_literal_prefix = prefix; \
+ 	drec->sql_desc_literal_suffix = suffix; \
+ 	drec->sql_desc_type_name = type; \
+-	return;
+-#define SET_INFO2(type, prefix, suffix, len) \
++	return; \
++	} while(0)
++#define SET_INFO2(type, prefix, suffix, len) do { \
+ 	drec->sql_desc_length = len; \
+-	SET_INFO(type, prefix, suffix)
++	SET_INFO(type, prefix, suffix); \
++	} while(0)
+ 
+ 	/* FIXME finish, support for N type (nvarchar) */
+ 	switch (tds_get_conversion_type(col->column_type, col->column_size)) {
+ 	case XSYBCHAR:
+ 	case SYBCHAR:
+-		if (col->column_type == XSYBNCHAR)
++		if (col->on_server.column_type == XSYBNCHAR)
+ 			SET_INFO("nchar", "'", "'");
+ 		SET_INFO("char", "'", "'");
+ 	case XSYBVARCHAR:
+ 	case SYBVARCHAR:
+-		if (col->column_type == SYBNVARCHAR || col->column_type == XSYBNVARCHAR)
++		if (col->on_server.column_type == SYBNVARCHAR || col->on_server.column_type == XSYBNVARCHAR)
+ 			SET_INFO("nvarchar", "'", "'");
+ 		SET_INFO("varchar", "'", "'");
+ 	case SYBTEXT:
+-		if (col->column_type == SYBNTEXT)
++		if (col->on_server.column_type == SYBNTEXT)
+ 			SET_INFO("ntext", "'", "'");
+ 		SET_INFO("text", "'", "'");
+ 	case SYBBIT:
+diff --git a/src/odbc/unittests/describecol.in b/src/odbc/unittests/describecol.in
+index cf941ee..3d2ce37 100644
+--- a/src/odbc/unittests/describecol.in
++++ b/src/odbc/unittests/describecol.in
+@@ -144,6 +144,7 @@ attr SQL_DESC_OCTET_LENGTH 10
+ attr SQL_DESC_PRECISION 10
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 10
++attr SQL_DESC_TYPE_NAME char
+ 
+ select varchar(11) 'hi!'
+ attr SQL_COLUMN_LENGTH 11
+@@ -154,6 +155,7 @@ attr SQL_DESC_OCTET_LENGTH 11
+ attr SQL_DESC_PRECISION 11
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 11
++attr SQL_DESC_TYPE_NAME varchar
+ 
+ select nchar(12) 'hi!'+nchar(10)
+ attr SQL_COLUMN_LENGTH 24
+@@ -186,6 +188,7 @@ attr SQL_DESC_OCTET_LENGTH 4096
+ attr SQL_DESC_PRECISION 4096
+ attr SQL_DESC_SCALE 0
+ attr SQL_DESC_DISPLAY_SIZE 4096
++attr SQL_DESC_TYPE_NAME text
+ 
+ select ntext 'hi!'
+ attr SQL_COLUMN_LENGTH 4096
+
+commit cce32afc7a36c42542cf4df0e140fffed22878bf
+Author: freddy77 <freddy77>
+Date:   Wed Aug 4 11:01:34 2010 +0000
+
+    simplify odbc_populate_ird
+
+diff --git a/ChangeLog b/ChangeLog
+index 74ce2cd..3672189 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Wed Aug  4 13:01:18 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/odbc/odbc.c src/odbc/odbc_util.c: simplify odbc_populate_ird
++
+ Wed Aug  4 10:04:33 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc_util.c src/odbc/unittests/describecol.in:
+ 	- fix macro for odbc_set_sql_type_info
+@@ -2817,4 +2820,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3108 2010/08/04 08:04:48 freddy77 Exp $
++$Id: ChangeLog,v 1.3109 2010/08/04 11:01:34 freddy77 Exp $
+diff --git a/src/odbc/odbc.c b/src/odbc/odbc.c
+index 0359783..9c0fb75 100644
+--- a/src/odbc/odbc.c
++++ b/src/odbc/odbc.c
+@@ -61,7 +61,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc.c,v 1.550 2010/08/04 06:55:45 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc.c,v 1.551 2010/08/04 11:01:34 freddy77 Exp $");
+ 
+ static SQLRETURN _SQLAllocConnect(SQLHENV henv, SQLHDBC FAR * phdbc);
+ static SQLRETURN _SQLAllocEnv(SQLHENV FAR * phenv, SQLINTEGER odbc_version);
+@@ -3010,16 +3010,6 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		if (!tds_dstr_copyn(&drec->sql_desc_label, col->column_name, col->column_namelen))
+ 			return SQL_ERROR;
+ 
+-		switch (drec->sql_desc_concise_type) {
+-		case SQL_WCHAR:
+-		case SQL_WVARCHAR:
+-		case SQL_WLONGVARCHAR:
+-			drec->sql_desc_length = col->on_server.column_size / 2;
+-			break;
+-		default:
+-			drec->sql_desc_length = col->on_server.column_size;
+-			break;
+-		}
+ 		odbc_set_sql_type_info(col, drec, stmt->dbc->env->attr.odbc_version);
+ 
+ 		if (!col->table_column_name) {
+@@ -3082,23 +3072,10 @@ odbc_populate_ird(TDS_STMT * stmt)
+ 		drec->sql_desc_unnamed = tds_dstr_isempty(&drec->sql_desc_name) ? SQL_UNNAMED : SQL_NAMED;
+ 		/* TODO use is_nullable_type ?? */
+ 		drec->sql_desc_nullable = col->column_nullable ? SQL_TRUE : SQL_FALSE;
+-		if (drec->sql_desc_concise_type == SQL_NUMERIC) {
++		if (drec->sql_desc_concise_type == SQL_NUMERIC)
+ 			drec->sql_desc_num_prec_radix = 10;
+-			drec->sql_desc_octet_length = col->column_prec + 2;
+-		} else {
+-			SQLLEN len; 
+-
++		else
+ 			drec->sql_desc_num_prec_radix = 0;
+-			if (type == SYBMONEY)
+-				len = 21;
+-			else if (type == SYBMONEY4)
+-				len = 12;
+-			else if (drec->sql_desc_type == SQL_DATETIME)
+-				len = sizeof(TIMESTAMP_STRUCT);
+-			else
+-				len = col->on_server.column_size;
+-			drec->sql_desc_octet_length = len;
+-		}
+ 
+ 		drec->sql_desc_octet_length_ptr = NULL;
+ 		switch (type) {
+diff --git a/src/odbc/odbc_util.c b/src/odbc/odbc_util.c
+index 440d5df..0056785 100644
+--- a/src/odbc/odbc_util.c
++++ b/src/odbc/odbc_util.c
+@@ -41,7 +41,7 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: odbc_util.c,v 1.123 2010/08/04 08:04:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: odbc_util.c,v 1.124 2010/08/04 11:01:34 freddy77 Exp $");
+ 
+ /**
+  * \ingroup odbc_api
+@@ -846,25 +846,26 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ 	return; \
+ 	} while(0)
+ #define SET_INFO2(type, prefix, suffix, len) do { \
+-	drec->sql_desc_length = len; \
++	drec->sql_desc_length = (len); \
+ 	SET_INFO(type, prefix, suffix); \
+ 	} while(0)
+ 
+-	/* FIXME finish, support for N type (nvarchar) */
++	drec->sql_desc_octet_length = drec->sql_desc_length = col->on_server.column_size;
++
+ 	switch (tds_get_conversion_type(col->column_type, col->column_size)) {
+ 	case XSYBCHAR:
+ 	case SYBCHAR:
+ 		if (col->on_server.column_type == XSYBNCHAR)
+-			SET_INFO("nchar", "'", "'");
++			SET_INFO2("nchar", "'", "'", col->on_server.column_size / 2);
+ 		SET_INFO("char", "'", "'");
+ 	case XSYBVARCHAR:
+ 	case SYBVARCHAR:
+ 		if (col->on_server.column_type == SYBNVARCHAR || col->on_server.column_type == XSYBNVARCHAR)
+-			SET_INFO("nvarchar", "'", "'");
++			SET_INFO2("nvarchar", "'", "'", col->on_server.column_size / 2);
+ 		SET_INFO("varchar", "'", "'");
+ 	case SYBTEXT:
+ 		if (col->on_server.column_type == SYBNTEXT)
+-			SET_INFO("ntext", "'", "'");
++			SET_INFO2("ntext", "'", "'", col->on_server.column_size / 2);
+ 		SET_INFO("text", "'", "'");
+ 	case SYBBIT:
+ 	case SYBBITN:
+@@ -885,12 +886,16 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ 	case SYBFLT8:
+ 		SET_INFO2("float", "", "", odbc_ver == SQL_OV_ODBC3 ? 53 : 15);
+ 	case SYBMONEY:
++		drec->sql_desc_octet_length = 21;
+ 		SET_INFO2("money", "$", "", 19);
+ 	case SYBMONEY4:
++		drec->sql_desc_octet_length = 12;
+ 		SET_INFO2("money", "$", "", 10);
+ 	case SYBDATETIME:
++		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
+ 		SET_INFO2("datetime", "'", "'", 23);
+ 	case SYBDATETIME4:
++		drec->sql_desc_octet_length = sizeof(TIMESTAMP_STRUCT);
+ 		SET_INFO2("datetime", "'", "'", 16);
+ 	case SYBBINARY:
+ 		/* handle TIMESTAMP using usertype */
+@@ -902,8 +907,10 @@ odbc_set_sql_type_info(TDSCOLUMN * col, struct _drecord *drec, SQLINTEGER odbc_v
+ 	case SYBVARBINARY:
+ 		SET_INFO("varbinary", "0x", "");
+ 	case SYBNUMERIC:
++		drec->sql_desc_octet_length = col->column_prec + 2;
+ 		SET_INFO2("numeric", "", "", col->column_prec);
+ 	case SYBDECIMAL:
++		drec->sql_desc_octet_length = col->column_prec + 2;
+ 		SET_INFO2("decimal", "", "", col->column_prec);
+ 	case SYBINTN:
+ 	case SYBDATETIMN:
+
+commit 8a1fc237b1854b4d5f7f1ee1d22633009bd20df2
+Author: freddy77 <freddy77>
+Date:   Thu Aug 5 08:58:36 2010 +0000
+
+    fix fakepoll
+
+diff --git a/ChangeLog b/ChangeLog
+index 3672189..99b2510 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug  5 10:58:27 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/replacements.h src/replacements/fakepoll.c: fix fakepoll
++
+ Wed Aug  4 13:01:18 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/odbc/odbc.c src/odbc/odbc_util.c: simplify odbc_populate_ird
+ 
+@@ -2820,4 +2823,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3109 2010/08/04 11:01:34 freddy77 Exp $
++$Id: ChangeLog,v 1.3110 2010/08/05 08:58:36 freddy77 Exp $
+diff --git a/include/replacements.h b/include/replacements.h
+index 9ae9f9f..175e3e4 100644
+--- a/include/replacements.h
++++ b/include/replacements.h
+@@ -20,7 +20,7 @@
+ #ifndef _replacements_h_
+ #define _replacements_h_
+ 
+-/* $Id: replacements.h,v 1.26 2010/01/25 23:05:58 freddy77 Exp $ */
++/* $Id: replacements.h,v 1.27 2010/08/05 08:58:36 freddy77 Exp $ */
+ 
+ #include <stdarg.h>
+ #include "tds_sysdep_public.h"
+@@ -39,6 +39,11 @@
+ # include <libgen.h>
+ #endif
+ 
++#if !HAVE_POLL
++#include <fakepoll.h>
++#define poll(fds, nfds, timeout) fakepoll((fds), (nfds), (timeout))
++#endif /* !HAVE_POLL */
++
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+ #endif
+@@ -48,11 +53,6 @@ extern "C"
+ {
+ #endif
+ 
+-#if !HAVE_POLL
+-#include <fakepoll.h>
+-#define poll(fds, nfds, timeout) fakepoll((fds), (nfds), (timeout))
+-#endif /* !HAVE_POLL */
+-
+ #if !HAVE_VSNPRINTF
+ #if  HAVE__VSNPRINTF
+ #undef vsnprintf
+diff --git a/src/replacements/fakepoll.c b/src/replacements/fakepoll.c
+index b6ad165..6dbaa04 100644
+--- a/src/replacements/fakepoll.c
++++ b/src/replacements/fakepoll.c
+@@ -23,7 +23,7 @@
+ 
+ #ifndef HAVE_POLL
+ 
+-static char software_version[] = "$Id: fakepoll.c,v 1.10 2010/05/12 11:19:16 freddy77 Exp $";
++static char software_version[] = "$Id: fakepoll.c,v 1.11 2010/08/05 08:58:36 freddy77 Exp $";
+ static void *no_unused_var_warn[] = { software_version, no_unused_var_warn };
+ 
+ #include <stdarg.h>
+@@ -129,11 +129,13 @@ fakepoll(struct pollfd fds[], int nfds, int timeout)
+ 	 * select(2) returns EINVAL, and so do we.  
+ 	 * EFAULT might be better.
+ 	 */ 
++#if !defined(_WIN32)
+ 	if (maxfd > FD_SETSIZE) {
+ 		assert(FD_SETSIZE > 0);
+ 		errno = EINVAL;
+ 		return -1;
+ 	}
++#endif
+ 
+ 	/*
+ 	 * poll timeout is in milliseconds. Convert to struct timeval.
+
+commit 1aab62c58cb64030333710df178064940f9a6c1c
+Author: freddy77 <freddy77>
+Date:   Thu Aug 5 09:25:00 2010 +0000
+
+    use fakepoll
+
+diff --git a/ChangeLog b/ChangeLog
+index 99b2510..8deca54 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Thu Aug  5 11:24:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* src/tds/net.c: use fakepoll
++
+ Thu Aug  5 10:58:27 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* include/replacements.h src/replacements/fakepoll.c: fix fakepoll
+ 
+@@ -2823,4 +2826,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3110 2010/08/05 08:58:36 freddy77 Exp $
++$Id: ChangeLog,v 1.3111 2010/08/05 09:25:00 freddy77 Exp $
+diff --git a/src/tds/net.c b/src/tds/net.c
+index eb11d27..76de351 100644
+--- a/src/tds/net.c
++++ b/src/tds/net.c
+@@ -107,21 +107,12 @@
+ #include <dmalloc.h>
+ #endif
+ 
+-TDS_RCSID(var, "$Id: net.c,v 1.105 2010/07/30 07:29:48 freddy77 Exp $");
++TDS_RCSID(var, "$Id: net.c,v 1.106 2010/08/05 09:25:00 freddy77 Exp $");
+ 
+-#undef USE_POLL
+-#if defined(HAVE_POLL_H) && defined(HAVE_POLL) && !defined(C_INTERIX)
+-# define USE_POLL 1
+-# define TDSSELREAD  POLLIN
+-# define TDSSELWRITE POLLOUT
++#define TDSSELREAD  POLLIN
++#define TDSSELWRITE POLLOUT
+ /* error is always returned */
+-# define TDSSELERR   0
+-#else
+-# define USE_POLL 0
+-# define TDSSELREAD  1
+-# define TDSSELWRITE 2
+-# define TDSSELERR   4
+-#endif
++#define TDSSELERR   0
+ 
+ static int      tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
+ 
+@@ -344,37 +335,11 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ {
+ 	int rc, seconds;
+ 	unsigned int poll_seconds;
+-#if USE_POLL
+ 	static const char method[] = "poll(2)";
+-#else
+-	static const char method[] = "select(2)";
+-	fd_set fds[3];
+-	fd_set *readfds = NULL, *writefds = NULL, *exceptfds = NULL;
+-#endif
+ 
+ 	assert(tds != NULL);
+ 	assert(timeout_seconds >= 0);
+ 
+-#if !USE_POLL
+-#if !defined(_WIN32) && defined(FD_SETSIZE)
+-	if (tds->s >= FD_SETSIZE) {
+-		sock_errno = EINVAL;
+-		return -1;
+-	}
+-#endif
+-	if ((tds_sel & TDSSELREAD) != 0) {
+-		FD_ZERO(&fds[0]);
+-		readfds = &fds[0];
+-	}
+-	if ((tds_sel & TDSSELWRITE) != 0) {
+-		FD_ZERO(&fds[1]);
+-		writefds = &fds[1];
+-	}
+-	if ((tds_sel & TDSSELERR) != 0) {
+-		FD_ZERO(&fds[2]);
+-		exceptfds = &fds[2];
+-	}
+-#endif
+ 
+ 	/* 
+ 	 * The select loop.  
+@@ -393,7 +358,6 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 	 */
+ 	poll_seconds = (tds->tds_ctx && tds->tds_ctx->int_handler)? 1 : timeout_seconds;
+ 	for (seconds = timeout_seconds; timeout_seconds == 0 || seconds > 0; seconds -= poll_seconds) {
+-#if USE_POLL
+ 		struct pollfd fd;
+ 		int timeout = poll_seconds ? poll_seconds * 1000 : -1;
+ 
+@@ -401,21 +365,6 @@ tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds)
+ 		fd.events = tds_sel;
+ 		fd.revents = 0;
+ 		rc = poll(&fd, 1, timeout);
+-#else
+-		struct timeval tv, *ptv = poll_seconds? &tv : NULL;
+-
+-		tv.tv_sec = poll_seconds;
+-		tv.tv_usec = 0; 
+-
+-		if (readfds)
+-			FD_SET(tds->s, readfds);
+-		if (writefds)
+-			FD_SET(tds->s, writefds);
+-		if (exceptfds)
+-			FD_SET(tds->s, exceptfds);
+-
+-		rc = select((int)tds->s + 1, readfds, writefds, exceptfds, ptv); 
+-#endif /* USE_POLL */
+ 
+ 		if (rc > 0 ) {
+ 			return rc;
+@@ -824,12 +773,7 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 	int num_try;
+ 	struct sockaddr_in sin;
+ 	ioctl_nonblocking_t ioctl_nonblocking;
+-#if USE_POLL
+ 	struct pollfd fd;
+-#else
+-	struct timeval selecttimeout;
+-	fd_set fds;
+-#endif
+ 	int retval;
+ 	TDS_SYS_SOCKET s;
+ 	char msg[16*1024];
+@@ -853,15 +797,6 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 		return 0;
+ 	}
+ 
+-#if !USE_POLL
+-#if !defined(_WIN32) && defined(FD_SETSIZE)
+-	if (s >= FD_SETSIZE) {
+-		sock_errno = EINVAL;
+-		return 0;
+-	}
+-#endif
+-#endif
+-
+ 	/*
+ 	 * on cluster environment is possible that reply packet came from
+ 	 * different IP so do not filter by ip with connect
+@@ -883,20 +818,11 @@ tds7_get_instance_ports(FILE *output, const char *ip_addr)
+ 		msg[0] = 3;
+ 		sendto(s, msg, 1, 0, (struct sockaddr *) &sin, sizeof(sin));
+ 
+-#if USE_POLL
+ 		fd.fd = s;
+ 		fd.events = POLLIN;
+ 		fd.revents = 0;
+ 
+ 		retval = poll(&fd, 1, 1000);
+-#else
+-		FD_ZERO(&fds);
+-		FD_SET(s, &fds);
+-		selecttimeout.tv_sec = 1;
+-		selecttimeout.tv_usec = 0;
+-		
+-		retval = select((int)s + 1, &fds, NULL, NULL, &selecttimeout);
+-#endif
+ 		
+ 		/* on interrupt ignore */
+ 		if (retval < 0 && sock_errno == TDSSOCK_EINTR)
+@@ -987,12 +913,7 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 	int num_try;
+ 	struct sockaddr_in sin;
+ 	ioctl_nonblocking_t ioctl_nonblocking;
+-#if USE_POLL
+ 	struct pollfd fd;
+-#else
+-	struct timeval selecttimeout;
+-	fd_set fds;
+-#endif
+ 	int retval;
+ 	TDS_SYS_SOCKET s;
+ 	char msg[1024];
+@@ -1016,15 +937,6 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		return 0;
+ 	}
+ 
+-#if !USE_POLL
+-#if !defined(_WIN32) && defined(FD_SETSIZE)
+-	if (s >= FD_SETSIZE) {
+-		sock_errno = EINVAL;
+-		return 0;
+-	}
+-#endif
+-#endif
+-
+ 	/*
+ 	 * on cluster environment is possible that reply packet came from
+ 	 * different IP so do not filter by ip with connect
+@@ -1047,20 +959,11 @@ tds7_get_instance_port(const char *ip_addr, const char *instance)
+ 		tds_strlcpy(msg + 1, instance, sizeof(msg) - 1);
+ 		sendto(s, msg, (int)strlen(msg) + 1, 0, (struct sockaddr *) &sin, sizeof(sin));
+ 
+-#if USE_POLL
+ 		fd.fd = s;
+ 		fd.events = POLLIN;
+ 		fd.revents = 0;
+ 
+ 		retval = poll(&fd, 1, 1000);
+-#else
+-		FD_ZERO(&fds);
+-		FD_SET(s, &fds);
+-		selecttimeout.tv_sec = 1;
+-		selecttimeout.tv_usec = 0;
+-		
+-		retval = select((int)s + 1, &fds, NULL, NULL, &selecttimeout);
+-#endif
+ 		
+ 		/* on interrupt ignore */
+ 		if (retval < 0 && sock_errno == TDSSOCK_EINTR)
+
+commit 4c4d816ca4ec1ed06a5db691d09ead777deff1b8
+Author: freddy77 <freddy77>
+Date:   Tue Aug 10 07:40:09 2010 +0000
+
+    fix compile with HP-UX compiler
+
+diff --git a/ChangeLog b/ChangeLog
+index 8deca54..cb0c75c 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,6 @@
++Tue Aug 10 09:40:00 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* configure.ac m4/acx_pthread.m4: fix compile with HP-UX compiler
++
+ Thu Aug  5 11:24:51 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* src/tds/net.c: use fakepoll
+ 
+@@ -2826,4 +2829,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3111 2010/08/05 09:25:00 freddy77 Exp $
++$Id: ChangeLog,v 1.3112 2010/08/10 07:40:09 freddy77 Exp $
+diff --git a/configure.ac b/configure.ac
+index 386f776..eae3aa0 100644
+--- a/configure.ac
++++ b/configure.ac
+@@ -1,7 +1,7 @@
+ dnl Process this file with autoconf to produce a configure script.
+ 
+ dnl ------------------------------------------------------------
+-dnl $Id: configure.ac,v 1.54 2010/07/30 09:09:36 freddy77 Exp $
++dnl $Id: configure.ac,v 1.55 2010/08/10 07:40:09 freddy77 Exp $
+ dnl If you're trying to create a new configure test, try
+ dnl
+ dnl 	http://autogen.sourceforge.net/conftest.html
+@@ -15,7 +15,7 @@ dnl ------------------------------------------------------------
+ AC_INIT(FreeTDS, 0.83.dev.esyscmd(echo -n $(date +"%Y%m%d")))
+ AC_CONFIG_SRCDIR(src/dblib/dblib.c)
+ AC_PREREQ(2.53)
+-AC_REVISION($Revision: 1.54 $)
++AC_REVISION($Revision: 1.55 $)
+ 
+ AM_INIT_AUTOMAKE([dist-bzip2])
+ AC_CONFIG_HEADERS(include/config.h)
+@@ -81,6 +81,7 @@ CPPFLAGS="$CPPFLAGS -D_FREETDS_LIBRARY_SOURCE"
+ AC_PROG_CC
+ AC_PROG_CPP
+ AM_PROG_CC_C_O
++AC_C_INLINE
+ 
+ dnl Disable libtool 1.5 support for languages we don't use
+ dnl (cfr http://lists.gnu.org/archive/html/libtool/2005-08/msg00137.html)
+diff --git a/m4/acx_pthread.m4 b/m4/acx_pthread.m4
+index e4e91d3..8fff157 100644
+--- a/m4/acx_pthread.m4
++++ b/m4/acx_pthread.m4
+@@ -120,6 +120,12 @@ case "${host_cpu}-${host_os}" in
+ 
+         acx_pthread_flags="-pthreads pthread -mt -pthread $acx_pthread_flags"
+         ;;
++
++        # The HP-UX compiler just warns about options it does not understand
++        # but it needs -mt.
++        *-hpux*)
++        acx_pthread_flags="-mt $acx_pthread_flags"
++        ;;
+ esac
+ 
+ if test x"$acx_pthread_ok" = xno; then
+
+commit 29d911aba4a3d83d2825673bb58ff8a6c152d8b0
+Author: freddy77 <freddy77>
+Date:   Tue Aug 17 13:16:05 2010 +0000
+
+    fix compile problem with msvc6
+
+diff --git a/ChangeLog b/ChangeLog
+index cb0c75c..00f64f4 100644
+--- a/ChangeLog
++++ b/ChangeLog
+@@ -1,3 +1,8 @@
++Tue Aug 17 15:15:57 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
++	* include/tdsodbc.h win32/FreeTDS_w.def win32/Makefile.am:
++	* win32/msvc6/FreeTDS.dsp win32/msvc6/libTDS.dsp:
++	- fix compile problem with msvc6
++
+ Tue Aug 10 09:40:00 CEST 2010    Frediano Ziglio <freddy77_A_gmail_D_com>
+ 	* configure.ac m4/acx_pthread.m4: fix compile with HP-UX compiler
+ 
+@@ -2829,4 +2834,4 @@ Wed Jan  9 19:54:43 EST 2008	JK Lowden <jklowden@freetds.org>
+ 	* ChangeLog-0.82 added because of release
+ 	
+ $FreeTDS$
+-$Id: ChangeLog,v 1.3112 2010/08/10 07:40:09 freddy77 Exp $
++$Id: ChangeLog,v 1.3113 2010/08/17 13:16:05 freddy77 Exp $
+diff --git a/include/tdsodbc.h b/include/tdsodbc.h
+index 4d80815..305323b 100644
+--- a/include/tdsodbc.h
++++ b/include/tdsodbc.h
+@@ -66,7 +66,7 @@ extern "C"
+ #endif
+ #endif
+ 
+-/* $Id: tdsodbc.h,v 1.125 2010/07/30 09:09:36 freddy77 Exp $ */
++/* $Id: tdsodbc.h,v 1.126 2010/08/17 13:16:05 freddy77 Exp $ */
+ 
+ #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
+ #pragma GCC visibility push(hidden)
+@@ -75,12 +75,8 @@ extern "C"
+ #define ODBC_API SQL_API
+ #endif
+ 
+-#if defined(_WIN32) || defined(__CYGWIN__)
+-#  ifdef __GNUC__
+-#    define ODBC_PUBLIC __attribute__((dllexport))
+-#  else
+-#    define ODBC_PUBLIC __declspec(dllexport)
+-#  endif
++#if (defined(_WIN32) || defined(__CYGWIN__)) && defined(__GNUC__)
++#  define ODBC_PUBLIC __attribute__((dllexport))
+ #else
+ #  define ODBC_PUBLIC
+ #endif
+diff --git a/win32/FreeTDS_w.def b/win32/FreeTDS_w.def
+new file mode 100644
+index 0000000..0a61e01
+--- /dev/null
++++ b/win32/FreeTDS_w.def
+@@ -0,0 +1,110 @@
++EXPORTS
++	SQLAllocConnect
++	SQLAllocEnv
++	SQLAllocHandle
++	SQLAllocStmt
++	SQLBindCol
++	SQLBindParam
++	SQLBindParameter
++;	SQLBrowseConnect
++	SQLCancel
++	SQLCloseCursor
++	SQLColAttribute
++	SQLColAttributes
++	SQLColumnPrivileges
++	SQLColumns
++	SQLConnect
++	SQLCopyDesc
++	SQLDescribeCol
++;	SQLDescribeParam
++	SQLDisconnect
++	SQLDriverConnect
++	SQLEndTran
++	SQLError
++	SQLExecDirect
++	SQLExecute
++	SQLExtendedFetch
++	SQLFetch
++	SQLFetchScroll
++	SQLForeignKeys
++	SQLFreeConnect
++	SQLFreeEnv
++	SQLFreeHandle
++	SQLFreeStmt
++	SQLGetConnectAttr
++	SQLGetConnectOption
++	SQLGetCursorName
++	SQLGetData
++	SQLGetDescField
++	SQLGetDescRec
++	SQLGetDiagField
++	SQLGetDiagRec
++	SQLGetEnvAttr
++	SQLGetFunctions
++	SQLGetInfo
++	SQLGetStmtAttr
++	SQLGetStmtOption
++	SQLGetTypeInfo
++	SQLMoreResults
++	SQLNativeSql
++	SQLNumParams
++	SQLNumResultCols
++	SQLParamData
++	SQLParamOptions
++	SQLPrepare
++	SQLPrimaryKeys
++	SQLProcedureColumns
++	SQLProcedures
++	SQLPutData
++	SQLRowCount
++	SQLSetConnectAttr
++	SQLSetConnectOption
++	SQLSetCursorName
++	SQLSetDescField
++	SQLSetDescRec
++	SQLSetEnvAttr
++	SQLSetParam
++	SQLSetPos
++	SQLSetScrollOptions
++	SQLSetStmtAttr
++	SQLSetStmtOption
++	SQLSpecialColumns
++	SQLStatistics
++	SQLTablePrivileges
++	SQLTables
++	SQLTransact
++	ConfigDSN
++	ConfigDriver
++	ConfigTranslator
++	DllRegisterServer
++	DllUnregisterServer
++	SQLGetTypeInfoW = SQLGetTypeInfo
++	SQLColAttributeW
++	SQLColumnPrivilegesW
++	SQLColumnsW
++	SQLConnectW
++	SQLDescribeColW
++	SQLDriverConnectW
++	SQLErrorW
++	SQLExecDirectW
++	SQLForeignKeysW
++	SQLGetConnectAttrW
++	SQLGetCursorNameW
++	SQLGetDescFieldW
++	SQLGetDescRecW
++	SQLGetDiagFieldW
++	SQLGetDiagRecW
++	SQLGetInfoW
++	SQLNativeSqlW
++	SQLPrepareW
++	SQLPrimaryKeysW
++	SQLProcedureColumnsW
++	SQLProceduresW
++	SQLSetConnectAttrW
++	SQLSetCursorNameW
++	SQLSetDescFieldW
++	SQLSpecialColumnsW
++	SQLStatisticsW
++	SQLTablePrivilegesW
++	SQLTablesW
++
+diff --git a/win32/Makefile.am b/win32/Makefile.am
+index 78190d0..3febb6c 100644
+--- a/win32/Makefile.am
++++ b/win32/Makefile.am
+@@ -1,5 +1,5 @@
+ SUBDIRS	= msvc6
+-EXTRA_DIST      = config.h FreeTDS.def initnet.c \
++EXTRA_DIST      = config.h FreeTDS.def FreeTDS_w.def initnet.c \
+ 		tds_sysdep_public.h freetds_sysconfdir.h \
+ 		winsetup.c winlogin.c \
+ 		setup.rc resource.h \
+diff --git a/win32/msvc6/FreeTDS.dsp b/win32/msvc6/FreeTDS.dsp
+index d14b1b8..76c22bf 100644
+--- a/win32/msvc6/FreeTDS.dsp
++++ b/win32/msvc6/FreeTDS.dsp
+@@ -109,7 +109,7 @@ SOURCE=..\..\src\odbc\error.c
+ # End Source File
+ # Begin Source File
+ 
+-SOURCE=..\FreeTDS.def
++SOURCE=..\FreeTDS_w.def
+ # End Source File
+ # Begin Source File
+ 
+diff --git a/win32/msvc6/libTDS.dsp b/win32/msvc6/libTDS.dsp
+index 1db1154..c2fe121 100644
+--- a/win32/msvc6/libTDS.dsp
++++ b/win32/msvc6/libTDS.dsp
+@@ -273,6 +273,10 @@ SOURCE=.\iconv_replacement.c
+ # End Source File
+ # Begin Source File
+ 
++SOURCE=..\..\src\replacements\fakepoll.c
++# End Source File
++# Begin Source File
++
+ SOURCE=..\..\src\replacements\strlcpy.c
+ # End Source File
+ # Begin Source File
--- a/src/freetds.mk	Thu Aug 19 22:16:26 2010 +0200
+++ b/src/freetds.mk	Tue Aug 17 20:55:16 2010 +0200
@@ -21,6 +21,9 @@
 endef
 
 define $(PKG)_BUILD
+    cd '$(1)' && ./autogen.sh
+    cd '$(1)' &&  libtoolize
+
     # package uses winsock2.h, so it should link to ws2_32 instead of wsock32
     $(SED) -i 's,wsock32,ws2_32,g' '$(1)'/configure
 
@@ -37,7 +40,9 @@
         --enable-static \
         --enable-libiconv \
         --enable-msdblib \
+        --enable-sspi \
         --disable-threadsafe \
         --with-tdsver=8.0
+    cd '$(1)' && chmod +x doc/txt2man
     $(MAKE) -C '$(1)' -j '$(JOBS)' install
 endef