1 /*********************************************************************
2  *
3  * This is based on code created by Peter Harvey,
4  * (pharvey@codebydesign.com).
5  *
6  * Modified and extended by Nick Gorham
7  * (nick@lurcher.org).
8  *
9  * Any bugs or problems should be considered the fault of Nick and not
10  * Peter.
11  *
12  * copyright (c) 1999 Nick Gorham
13  *
14  * This library is free software; you can redistribute it and/or
15  * modify it under the terms of the GNU Lesser General Public
16  * License as published by the Free Software Foundation; either
17  * version 2 of the License, or (at your option) any later version.
18  *
19  * This library is distributed in the hope that it will be useful,
20  * but WITHOUT ANY WARRANTY; without even the implied warranty of
21  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
22  * Lesser General Public License for more details.
23  *
24  * You should have received a copy of the GNU Lesser General Public
25  * License along with this library; if not, write to the Free Software
26  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
27  *
28  **********************************************************************
29  *
30  * $Id: __info.c,v 1.50 2009/02/18 17:59:08 lurcher Exp $
31  *
32  * $Log: __info.c,v $
33  * Revision 1.50  2009/02/18 17:59:08  lurcher
34  * Shift to using config.h, the compile lines were making it hard to spot warnings
35  *
36  * Revision 1.49  2009/02/17 09:47:44  lurcher
37  * Clear up a number of bugs
38  *
39  * Revision 1.48  2008/09/29 14:02:45  lurcher
40  * Fix missing dlfcn group option
41  *
42  * Revision 1.47  2008/01/02 15:10:33  lurcher
43  * Fix problems trying to use the cursor lib on a non select statement
44  *
45  * Revision 1.46  2007/11/26 11:37:23  lurcher
46  * Sync up before tag
47  *
48  * Revision 1.45  2007/09/28 13:20:22  lurcher
49  * Add timestamp to logging
50  *
51  * Revision 1.44  2007/04/02 10:50:19  lurcher
52  * Fix some 64bit problems (only when sizeof(SQLLEN) == 8 )
53  *
54  * Revision 1.43  2007/03/05 09:49:24  lurcher
55  * Get it to build on VMS again
56  *
57  * Revision 1.42  2006/11/27 14:08:34  lurcher
58  * Sync up dirs
59  *
60  * Revision 1.41  2006/03/08 11:22:13  lurcher
61  * Add check for valid C_TYPE
62  *
63  * Revision 1.40  2005/12/19 18:43:26  lurcher
64  * Add new parts to contrib and alter how the errors are returned from the driver
65  *
66  * Revision 1.39  2005/11/08 09:37:10  lurcher
67  * Allow the driver and application to have different length handles
68  *
69  * Revision 1.38  2005/02/07 11:46:45  lurcher
70  * Add missing ODBC2 installer stubs
71  *
72  * Revision 1.37  2004/07/24 17:55:37  lurcher
73  * Sync up CVS
74  *
75  * Revision 1.36  2004/05/17 08:25:00  lurcher
76  * Update the way the libltso is used, and fix a problem with gODBCConfig
77  * not closeing correctly.
78  *
79  * Revision 1.35  2004/03/30 13:20:11  lurcher
80  *
81  *
82  * Fix problem with SQLCopyDesc
83  * Add additional target for iconv
84  *
85  * Revision 1.34  2003/12/01 16:37:17  lurcher
86  *
87  * Fix a bug in SQLWritePrivateProfileString
88  *
89  * Revision 1.33  2003/10/30 18:20:46  lurcher
90  *
91  * Fix broken thread protection
92  * Remove SQLNumResultCols after execute, lease S4/S% to driver
93  * Fix string overrun in SQLDriverConnect
94  * Add initial support for Interix
95  *
96  * Revision 1.32  2003/09/08 15:34:29  lurcher
97  *
98  * A couple of small but perfectly formed fixes
99  *
100  * Revision 1.31  2003/07/21 11:12:59  lurcher
101  *
102  * Fix corruption in Postgre7.1 driver
103  * Tidy up gODBCconfig
104  *
105  * Revision 1.30  2003/06/24 09:40:58  lurcher
106  *
107  * Extra UNICODE stuff
108  *
109  * Revision 1.29  2003/06/04 12:49:45  lurcher
110  *
111  * Further PID logging tweeks
112  *
113  * Revision 1.28  2003/06/03 13:52:13  lurcher
114  *
115  * Change the mode of PID logfiles to allow the process to change to another
116  * user
117  *
118  * Revision 1.27  2003/06/02 16:51:36  lurcher
119  *
120  * Add TracePid option
121  *
122  * Revision 1.26  2003/02/25 13:28:31  lurcher
123  *
124  * Allow errors on the drivers AllocHandle to be reported
125  * Fix a problem that caused errors to not be reported in the log
126  * Remove a redundant line from the spec file
127  *
128  * Revision 1.25  2003/02/06 12:58:25  lurcher
129  *
130  * Fix a speeling problem :-)
131  *
132  * Revision 1.24  2002/12/05 17:44:31  lurcher
133  *
134  * Display unknown return values in return logging
135  *
136  * Revision 1.23  2002/11/11 17:10:20  lurcher
137  *
138  * VMS changes
139  *
140  * Revision 1.22  2002/11/06 16:08:01  lurcher
141  *
142  * Update missing
143  *
144  * Revision 1.21  2002/08/23 09:42:37  lurcher
145  *
146  * Fix some build warnings with casts, and a AIX linker mod, to include
147  * deplib's on the link line, but not the libtool generated ones
148  *
149  * Revision 1.20  2002/08/20 12:41:07  lurcher
150  *
151  * Fix incorrect return state from SQLEndTran/SQLTransact
152  *
153  * Revision 1.19  2002/08/19 09:11:49  lurcher
154  *
155  * Fix Maxor ineffiecny in Postgres Drivers, and fix a return state
156  *
157  * Revision 1.18  2002/08/15 08:10:33  lurcher
158  *
159  * Couple of small fixes from John L Miller
160  *
161  * Revision 1.17  2002/08/12 16:20:44  lurcher
162  *
163  * Make it try and find a working iconv set of encodings
164  *
165  * Revision 1.16  2002/08/12 13:17:52  lurcher
166  *
167  * Replicate the way the MS DM handles loading of driver libs, and allocating
168  * handles in the driver. usage counting in the driver means that dlopen is
169  * only called for the first use, and dlclose for the last. AllocHandle for
170  * the driver environment is only called for the first time per driver
171  * per application environment.
172  *
173  * Revision 1.15  2002/07/25 09:30:26  lurcher
174  *
175  * Additional unicode and iconv changes
176  *
177  * Revision 1.14  2002/07/24 08:49:52  lurcher
178  *
179  * Alter UNICODE support to use iconv for UNICODE-ANSI conversion
180  *
181  * Revision 1.13  2002/07/10 15:05:57  lurcher
182  *
183  * Alter the return code in the Postgres driver, for a warning, it should be
184  * 01000 it was 00000
185  * Fix a problem in DriverManagerII with the postgres driver as the driver
186  * doesn't return a propper list of schemas
187  * Allow the delimiter to be set in isql to a hex/octal char not just a
188  * printable one
189  *
190  * Revision 1.12  2002/07/08 16:37:35  lurcher
191  *
192  * Fix bug in unicode_to_ansi_copy
193  *
194  * Revision 1.11  2002/07/04 17:27:56  lurcher
195  *
196  * Small bug fixes
197  *
198  * Revision 1.9  2002/05/28 13:30:34  lurcher
199  *
200  * Tidy up for AIX
201  *
202  * Revision 1.8  2002/05/21 14:19:44  lurcher
203  *
204  * * Update libtool to escape from AIX build problem
205  * * Add fix to avoid file handle limitations
206  * * Add more UNICODE changes, it looks like it is native 16 representation
207  *   the old way can be reproduced by defining UCS16BE
208  * * Add iusql, its just the same as isql but uses the wide functions
209  *
210  * Revision 1.7  2002/04/10 11:04:36  lurcher
211  *
212  * Fix endian issue with 4 byte unicode support
213  *
214  * Revision 1.6  2002/02/27 11:27:14  lurcher
215  *
216  * Fix bug in error reporting
217  *
218  * Revision 1.5  2002/01/21 18:00:51  lurcher
219  *
220  * Assorted fixed and changes, mainly UNICODE/bug fixes
221  *
222  * Revision 1.4  2001/12/13 13:56:31  lurcher
223  *
224  * init a global for Peter
225  *
226  * Revision 1.3  2001/12/13 13:00:32  lurcher
227  *
228  * Remove most if not all warnings on 64 bit platforms
229  * Add support for new MS 3.52 64 bit changes
230  * Add override to disable the stopping of tracing
231  * Add MAX_ROWS support in postgres driver
232  *
233  * Revision 1.2  2001/11/15 18:38:21  lurcher
234  *
235  * Make the errors returned from SQLError reset after each API call
236  * if the app is expecting ODBC 3 operation
237  *
238  * Revision 1.1.1.1  2001/10/17 16:40:09  lurcher
239  *
240  * First upload to SourceForge
241  *
242  * Revision 1.23  2001/09/27 17:05:48  nick
243  *
244  * Assorted fixes and tweeks
245  *
246  * Revision 1.22  2001/07/03 09:30:41  nick
247  *
248  * Add ability to alter size of displayed message in the log
249  *
250  * Revision 1.21  2001/07/02 17:09:37  nick
251  *
252  * Add some portability changes
253  *
254  * Revision 1.20  2001/06/20 17:25:32  pat
255  * Correct msg1 length in 4 extract diag functions
256  *
257  * Revision 1.19  2001/06/20 08:19:25  nick
258  *
259  * Fix buffer overflow in error handling
260  *
261  * Revision 1.18  2001/04/23 13:58:43  nick
262  *
263  * Assorted tweeks to text driver to get it to work with StarOffice
264  *
265  * Revision 1.17  2001/04/20 16:57:25  nick
266  *
267  * Add extra mapping of data types
268  *
269  * Revision 1.16  2001/04/18 15:03:37  nick
270  *
271  * Fix problem when going to DB2 unicode driver
272  *
273  * Revision 1.15  2001/04/16 22:35:10  nick
274  *
275  * More tweeks to the AutoTest code
276  *
277  * Revision 1.14  2001/04/14 10:42:03  nick
278  *
279  * Extra work on the autotest feature of odbctest
280  *
281  * Revision 1.13  2001/04/12 17:43:36  nick
282  *
283  * Change logging and added autotest to odbctest
284  *
285  * Revision 1.12  2001/04/03 16:34:12  nick
286  *
287  * Add support for strangly broken unicode drivers
288  *
289  * Revision 1.11  2001/01/09 23:15:18  nick
290  *
291  * More unicode error fixes
292  *
293  * Revision 1.10  2001/01/09 22:33:13  nick
294  *
295  * Stop passing NULL into SQLExtendedFetch
296  * Further fixes to unicode to ansi conversions
297  *
298  * Revision 1.9  2001/01/09 11:03:32  nick
299  *
300  * Fixed overrun bug
301  *
302  * Revision 1.8  2001/01/06 15:00:12  nick
303  *
304  * Fix bug in SQLError introduced with UNICODE
305  *
306  * Revision 1.7  2000/12/31 20:30:54  nick
307  *
308  * Add UNICODE support
309  *
310  * Revision 1.6  2000/10/25 12:45:51  nick
311  *
312  * Add mapping for both ODBC 2 - 3 and ODBC 3 - 2 error states
313  *
314  * Revision 1.5  2000/10/25 12:32:41  nick
315  *
316  * The mapping was the wrong way around for errors, ODBC3 error are mapped
317  * to ODBC 2 not the other way around
318  *
319  * Revision 1.4  2000/10/25 09:13:26  nick
320  *
321  * Remove some invalid ODBC2-ODBC3 error mappings
322  *
323  * Revision 1.3  2000/10/13 15:18:49  nick
324  *
325  * Change string length parameter from SQLINTEGER to SQLSMALLINT
326  *
327  * Revision 1.2  2000/09/19 13:13:13  nick
328  *
329  * Add display of returned error text in log file
330  *
331  * Revision 1.1.1.1  2000/09/04 16:42:52  nick
332  * Imported Sources
333  *
334  * Revision 1.28  2000/07/31 08:46:11  ngorham
335  *
336  * Avoid potential buffer overrun
337  *
338  * Revision 1.27  2000/06/23 16:11:38  ngorham
339  *
340  * Map ODBC 2 SQLSTATE values to ODBC 3
341  *
342  * Revision 1.25  2000/06/21 11:07:36  ngorham
343  *
344  * Stop Errors from SQLAllocHandle being lost
345  *
346  * Revision 1.24  2000/06/20 12:44:01  ngorham
347  *
348  * Fix bug that caused a success with info message from SQLExecute or
349  * SQLExecDirect to be lost if used with a ODBC 3 driver and the application
350  * called SQLGetDiagRec
351  *
352  * Revision 1.23  2000/06/01 11:00:51  ngorham
353  *
354  * return errors from descriptor functions
355  *
356  * Revision 1.22  2001/05/31 23:24:20  ngorham
357  *
358  * Update timestamps
359  *
360  * Revision 1.21  2000/05/21 21:49:19  ngorham
361  *
362  * Assorted fixes
363  *
364  * Revision 1.20  2001/04/11 09:00:05  ngorham
365  *
366  * remove stray printf
367  *
368  * Revision 1.19  2001/04/01 00:06:50  ngorham
369  *
370  * Dont use stderr, if the log file fails to open.
371  *
372  * Revision 1.18  2000/03/14 07:45:35  ngorham
373  *
374  * Fix bug that discarded connection errors
375  *
376  * Revision 1.17  2000/01/18 17:24:50  ngorham
377  *
378  * Add missing [unixODBC] prefix in front of error messages.
379  *
380  * Revision 1.16  1999/12/14 19:02:25  ngorham
381  *
382  * Mask out the password fields in the logging
383  *
384  * Revision 1.15  1999/12/04 17:01:23  ngorham
385  *
386  * Remove C++ comments from the Postgres code
387  *
388  * Revision 1.14  1999/12/01 09:20:07  ngorham
389  *
390  * Fix some threading problems
391  *
392  * Revision 1.13  1999/11/17 21:08:58  ngorham
393  *
394  * Fix Bug with the ODBC 3 error handling
395  *
396  * Revision 1.12  1999/11/13 23:41:01  ngorham
397  *
398  * Alter the way DM logging works
399  * Upgrade the Postgres driver to 6.4.6
400  *
401  * Revision 1.11  1999/11/10 22:15:48  ngorham
402  *
403  * Fix some bugs with the DM and error reporting.
404  *
405  * Revision 1.10  1999/11/10 03:51:34  ngorham
406  *
407  * Update the error reporting in the DM to enable ODBC 3 and 2 calls to
408  * work at the same time
409  *
410  * Revision 1.9  1999/10/24 23:54:19  ngorham
411  *
412  * First part of the changes to the error reporting
413  *
414  * Revision 1.8  1999/10/03 23:05:16  ngorham
415  *
416  * First public outing of the cursor lib
417  *
418  * Revision 1.7  1999/09/19 22:24:34  ngorham
419  *
420  * Added support for the cursor library
421  *
422  * Revision 1.6  1999/08/03 21:47:39  shandyb
423  * Moving to automake: changed files in DriverManager
424  *
425  * Revision 1.5  1999/07/10 21:10:17  ngorham
426  *
427  * Adjust error sqlstate from driver manager, depending on requested
428  * version (ODBC2/3)
429  *
430  * Revision 1.4  1999/07/05 19:54:05  ngorham
431  *
432  * Fix a problem where a long string could crash the DM
433  *
434  * Revision 1.3  1999/07/04 21:05:08  ngorham
435  *
436  * Add LGPL Headers to code
437  *
438  * Revision 1.2  1999/06/19 17:51:41  ngorham
439  *
440  * Applied assorted minor bug fixes
441  *
442  * Revision 1.1.1.1  1999/05/29 13:41:09  sShandyb
443  * first go at it
444  *
445  * Revision 1.2  1999/06/03 22:20:25  ngorham
446  *
447  * Finished off the ODBC3-2 mapping
448  *
449  * Revision 1.1.1.1  1999/05/27 18:23:18  pharvey
450  * Imported sources
451  *
452  *
453  *
454  **********************************************************************/
455 
456 #include <config.h>
457 #include <sys/types.h>
458 #include <sys/stat.h>
459 #include <unistd.h>
460 
461 #if defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_SYS_TIME_H )
462 #include <sys/time.h>
463 #elif defined( HAVE_FTIME ) && defined( HAVE_SYS_TIMEB_H )
464 #include <sys/timeb.h>
465 #elif defined( DHAVE_TIME ) && defined( HAVE_TIME_H )
466 #include <time.h>
467 #endif
468 
469 #ifdef HAVE_LANGINFO_H
470 #include <langinfo.h>
471 #endif
472 
473 #include "drivermanager.h"
474 
475 static char const rcsid[]= "$RCSfile: __info.c,v $ $Revision: 1.50 $";
476 
477 struct log_structure log_info = { NULL, NULL, 0, 0 };
478 
479 SQLINTEGER ODBCSharedTraceFlag = 0;
480 
481 /*
482  * unicode setup functions, do them on a connection basis.
483  */
484 
unicode_setup(DMHDBC connection)485 int unicode_setup( DMHDBC connection )
486 {
487 #ifdef HAVE_ICONV
488     char ascii[ 256 ], unicode[ 256 ];
489     char *be_ucode[] = { "UCS-2-INTERNAL", "UCS-2BE", "UCS-2", "ucs2", NULL };
490     char *le_ucode[] = { "UCS-2-INTERNAL", "UCS-2LE", NULL };
491     char *asc[] = { "char", "char", "ISO8859-1", "ISO-8859-1", "8859-1", "iso8859_1", "ASCII", NULL };
492     union { long l; char c[sizeof (long)]; } u;
493     int be;
494 
495     if ( connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1) &&
496          connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1))
497     {
498         return 1;
499     }
500 
501     /*
502      * is this a bigendian machine ?
503      */
504 
505     u.l = 1;
506     be = (u.c[sizeof (long) - 1] == 1);
507 
508     mutex_iconv_entry();
509 
510 #if defined( HAVE_NL_LANGINFO ) && defined(HAVE_LANGINFO_CODESET)
511     /*
512      * Try with current locale settings first
513      */
514     asc[ 0 ] = nl_langinfo(CODESET);
515 #endif
516 
517     /*
518      * if required find a match
519      */
520 
521     if ( strcmp( ASCII_ENCODING, "auto-search" ) == 0 && strcmp( connection -> unicode_string, "auto-search" ) == 0 )
522     {
523         /*
524          * look for both
525          */
526         int i, j, found;
527         iconv_t icvt;
528 
529         ascii[ 0 ] = '\0';
530         unicode[ 0 ] = '\0';
531 
532         for ( i = found = 0; ( be ? be_ucode[ i ] : le_ucode[ i ] ) != NULL && !found; i ++ )
533         {
534             for ( j = 0; asc[ j ] && !found; j ++ )
535             {
536                 if (( icvt = iconv_open( asc[ j ], be ? be_ucode[ i ] : le_ucode[ i ] )) != ((iconv_t) -1 ) )
537                 {
538                     strcpy( ascii, asc[ j ] );
539                     strcpy( unicode, be ? be_ucode[ i ] : le_ucode[ i ] );
540                     iconv_close( icvt );
541                     found = 1;
542                 }
543             }
544         }
545     }
546     else if ( strcmp( ASCII_ENCODING, "auto-search" ) == 0 )
547     {
548         /*
549          * look for ascii
550          */
551         int j;
552         iconv_t icvt;
553 
554         strcpy( unicode, connection -> unicode_string );
555 
556         for ( j = 0; asc[ j ]; j ++ )
557         {
558             if (( icvt = iconv_open( asc[ j ], unicode )) != ((iconv_t) -1 ) )
559             {
560                 strcpy( ascii, asc[ j ] );
561                 iconv_close( icvt );
562                 break;
563             }
564         }
565     }
566     else if ( strcmp( connection -> unicode_string, "auto-search" ) == 0 )
567     {
568         /*
569          * look for unicode
570          */
571         int i;
572         iconv_t icvt;
573 
574         strcpy( ascii, ASCII_ENCODING );
575 
576         for ( i = 0; be ? be_ucode[ i ] : le_ucode[ i ]; i ++ )
577         {
578             if (( icvt = iconv_open( ascii, be ? be_ucode[ i ] : le_ucode[ i ] )) != ((iconv_t) -1 ) )
579             {
580                 strcpy( unicode, be ? be_ucode[ i ] : le_ucode[ i ] );
581                 iconv_close( icvt );
582                 break;
583             }
584         }
585     }
586     else
587     {
588         strcpy( ascii, ASCII_ENCODING );
589         strcpy( unicode, connection -> unicode_string );
590     }
591 
592     if ( log_info.log_flag )
593     {
594         sprintf( connection -> msg, "\t\tUNICODE Using encoding ASCII '%s' and UNICODE '%s'",
595                         ascii, unicode );
596 
597         dm_log_write_diag( connection -> msg );
598     }
599 
600     connection -> iconv_cd_uc_to_ascii = iconv_open( ascii, unicode );
601     connection -> iconv_cd_ascii_to_uc = iconv_open( unicode, ascii );
602 
603     mutex_iconv_exit();
604 
605     if ( connection -> iconv_cd_uc_to_ascii == (iconv_t)(-1) ||
606             connection -> iconv_cd_ascii_to_uc ==  (iconv_t)(-1))
607     {
608         return 0;
609     }
610     else
611     {
612         return 1;
613     }
614 
615 #else
616     return 1;
617 #endif
618 }
619 
unicode_shutdown(DMHDBC connection)620 void unicode_shutdown( DMHDBC connection )
621 {
622 #ifdef HAVE_ICONV
623     mutex_iconv_entry();
624 
625     if ( connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1) )
626     {
627         iconv_close( connection -> iconv_cd_ascii_to_uc );
628     }
629 
630     if ( connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1))
631     {
632         iconv_close( connection -> iconv_cd_uc_to_ascii );
633     }
634 
635     connection -> iconv_cd_uc_to_ascii = (iconv_t)(-1);
636     connection -> iconv_cd_ascii_to_uc = (iconv_t)(-1);
637 
638     mutex_iconv_exit();
639 #endif
640 }
641 
642 /*
643  * returned a malloc'd buffer in unicode converted from the ansi buffer
644  */
645 
ansi_to_unicode_alloc(SQLCHAR * str,SQLINTEGER len,DMHDBC connection,int * wlen)646 SQLWCHAR *ansi_to_unicode_alloc( SQLCHAR *str, SQLINTEGER len, DMHDBC connection, int *wlen )
647 {
648     SQLWCHAR *ustr;
649 
650     if ( wlen )
651     {
652         *wlen = len;
653     }
654 
655     if( !str )
656     {
657         return NULL;
658     }
659 
660     if ( len == SQL_NTS )
661     {
662         len = strlen((char*) str );
663     }
664 
665     ustr = malloc( sizeof( SQLWCHAR ) * ( len + 1 ));
666     if ( !ustr )
667     {
668         return NULL;
669     }
670 
671     return ansi_to_unicode_copy( ustr, (char*) str, len, connection, wlen );
672 }
673 
674 /*
675  * return a ansi representation of a unicode buffer, according to
676  * the chosen conversion method
677  */
678 
unicode_to_ansi_alloc(SQLWCHAR * str,SQLINTEGER len,DMHDBC connection,int * clen)679 char *unicode_to_ansi_alloc( SQLWCHAR *str, SQLINTEGER len, DMHDBC connection, int *clen )
680 {
681     char *aptr;
682 
683     if ( clen )
684     {
685         *clen = len;
686     }
687 
688     if ( !str )
689     {
690         return NULL;
691     }
692 
693     if ( len == SQL_NTS )
694     {
695         len = wide_strlen( str );
696     }
697 
698     aptr = malloc(( len * 4 ) + 1 );       /* There may be UTF8 */
699     if ( !aptr )
700     {
701         return NULL;
702     }
703 
704     return unicode_to_ansi_copy( aptr, len * 4, str, len, connection, clen );
705 }
706 
707 /*
708  * copy from a unicode buffer to a ansi buffer using the chosen conversion
709  */
710 
unicode_to_ansi_copy(char * dest,int dest_len,SQLWCHAR * src,SQLINTEGER buffer_len,DMHDBC connection,int * clen)711 char *unicode_to_ansi_copy( char * dest, int dest_len, SQLWCHAR *src, SQLINTEGER buffer_len, DMHDBC connection, int *clen )
712 {
713     int i;
714 
715     if ( !src || !dest )
716     {
717         return NULL;
718     }
719 
720     if ( buffer_len == SQL_NTS )
721     {
722         buffer_len = wide_strlen( src );
723     }
724 #ifdef HAVE_ICONV
725 
726     mutex_iconv_entry();
727 
728     if ( connection && connection -> iconv_cd_uc_to_ascii != (iconv_t)(-1))
729     {
730         size_t ret;
731         size_t inbl = buffer_len * sizeof( SQLWCHAR );
732         size_t obl = dest_len;
733         char *ipt = (char*)src;
734         char *opt = (char*)dest;
735 
736         if (( ret = iconv( connection -> iconv_cd_uc_to_ascii,
737                     (ICONV_CONST char**)&ipt, &inbl,
738                     &opt, &obl )) != (size_t)(-1))
739         {
740    		mutex_iconv_exit();
741 
742             if ( clen )
743             {
744                 *clen = opt - dest;
745             }
746 	        /* Null terminate outside of iconv, so that the length returned does not include the null terminator. */
747             if ( obl )
748             {
749 	            *opt = '\0';
750             }
751             return dest;
752         }
753     }
754 
755    	mutex_iconv_exit();
756 
757 #endif
758 
759     for ( i = 0; i < buffer_len && i < dest_len && src[ i ] != 0; i ++ )
760     {
761 #ifdef SQL_WCHART_CONVERT
762         dest[ i ] = (char)(src[ i ] & 0x000000ff);
763 #else
764         dest[ i ] = src[ i ] & 0x00FF;
765 #endif
766     }
767 
768     if ( clen )
769     {
770         *clen = i;
771     }
772 
773     if (dest_len)
774     {
775         dest[ i < dest_len ? i : i-1 ] = '\0';
776     }
777 
778     return dest;
779 }
780 
781 /*
782  * copy from a ansi buffer to a unicode buffer using the chosen conversion
783  */
784 
ansi_to_unicode_copy(SQLWCHAR * dest,char * src,SQLINTEGER buffer_len,DMHDBC connection,int * wlen)785 SQLWCHAR *ansi_to_unicode_copy( SQLWCHAR * dest, char *src, SQLINTEGER buffer_len, DMHDBC connection, int *wlen )
786 {
787     int i;
788 
789     if ( !src || !dest )
790     {
791         return NULL;
792     }
793 
794     if ( buffer_len == SQL_NTS )
795     {
796         buffer_len = strlen( src );
797     }
798 
799 #ifdef HAVE_ICONV
800 
801     if ( connection && connection -> iconv_cd_ascii_to_uc != (iconv_t)(-1))
802     {
803         size_t inbl = buffer_len;
804         size_t obl = buffer_len * sizeof( SQLWCHAR );
805         char *ipt = (char*)src;
806         char *opt = (char*)dest;
807 
808 		mutex_iconv_entry();
809 
810         if ( iconv( connection -> iconv_cd_ascii_to_uc,
811                     (ICONV_CONST char**)&ipt, &inbl,
812                     &opt, &obl ) != (size_t)(-1))
813         {
814 			mutex_iconv_exit();
815 
816             if ( wlen )
817             {
818                 *wlen = ( opt - ((char*)dest)) / sizeof( SQLWCHAR );
819             }
820 	        /* Null terminate outside of iconv, so that the length returned does not include the null terminator. */
821 	        dest[( opt - ((char*)dest)) / sizeof( SQLWCHAR )] = 0;
822             return dest;
823         }
824 
825 		mutex_iconv_exit();
826     }
827 
828 #endif
829 
830     for ( i = 0; i < buffer_len && src[ i ] != 0; i ++ )
831     {
832 #ifdef SQL_WCHART_CONVERT
833         dest[ i ] = src[ i ] & 0x000000ff;
834 #else
835         dest[ i ] = src[ i ] & 0x00FF;
836 #endif
837     }
838 
839     if ( wlen )
840     {
841         *wlen = i;
842     }
843 
844     dest[ i ] = 0;
845 
846 
847     return dest;
848 }
849 
850 
851 /*
852  * display a SQLGetTypeInfo type as a astring
853  */
854 
__type_as_string(SQLCHAR * s,SQLSMALLINT type)855 char * __type_as_string( SQLCHAR *s, SQLSMALLINT type )
856 {
857     switch( type )
858     {
859       case SQL_DOUBLE:
860         sprintf((char*) s, "SQL_DOUBLE" );
861         break;
862 
863       case SQL_FLOAT:
864         sprintf((char*) s, "SQL_FLOAT" );
865         break;
866 
867       case SQL_REAL:
868         sprintf((char*) s, "SQL_REAL" );
869         break;
870 
871       case SQL_BIT:
872         sprintf((char*) s, "SQL_BIT" );
873         break;
874 
875       case SQL_CHAR:
876         sprintf((char*) s, "SQL_CHAR" );
877         break;
878 
879       case SQL_VARCHAR:
880         sprintf((char*) s, "SQL_VARCHAR" );
881         break;
882 
883       case SQL_LONGVARCHAR:
884         sprintf((char*) s, "SQL_LONGVARCHAR" );
885         break;
886 
887       case SQL_BINARY:
888         sprintf((char*) s, "SQL_BINARY" );
889         break;
890 
891       case SQL_VARBINARY:
892         sprintf((char*) s, "SQL_VARBINARY" );
893         break;
894 
895       case SQL_LONGVARBINARY:
896         sprintf((char*) s, "SQL_LONGVARBINARY" );
897         break;
898 
899       case SQL_DECIMAL:
900         sprintf((char*) s, "SQL_DECIMAL" );
901         break;
902 
903       case SQL_NUMERIC:
904         sprintf((char*) s, "SQL_NUMERIC" );
905         break;
906 
907       case SQL_BIGINT:
908         sprintf((char*) s, "SQL_BIGINT" );
909         break;
910 
911       case SQL_INTEGER:
912         sprintf((char*) s, "SQL_INTEGER" );
913         break;
914 
915       case SQL_SMALLINT:
916         sprintf((char*) s, "SQL_SMALLINT" );
917         break;
918 
919       case SQL_TINYINT:
920         sprintf((char*) s, "SQL_TINYINT" );
921         break;
922 
923       case SQL_TYPE_DATE:
924         sprintf((char*) s, "SQL_TYPE_DATE" );
925         break;
926 
927       case SQL_TYPE_TIME:
928         sprintf((char*) s, "SQL_TYPE_TIME" );
929         break;
930 
931       case SQL_TYPE_TIMESTAMP:
932         sprintf((char*) s, "SQL_TYPE_TIMESTAMP" );
933         break;
934 
935       case SQL_DATE:
936         sprintf((char*) s, "SQL_DATE" );
937         break;
938 
939       case SQL_TIME:
940         sprintf((char*) s, "SQL_TIME" );
941         break;
942 
943       case SQL_TIMESTAMP:
944         sprintf((char*) s, "SQL_TIMESTAMP" );
945         break;
946 
947       case SQL_INTERVAL_YEAR:
948         sprintf((char*) s, "SQL_INTERVAL_YEAR" );
949         break;
950 
951       case SQL_INTERVAL_YEAR_TO_MONTH:
952         sprintf((char*) s, "SQL_INTERVAL_YEAR_TO_MONTH" );
953         break;
954 
955       case SQL_INTERVAL_MONTH:
956         sprintf((char*) s, "SQL_INTERVAL_MONTH" );
957         break;
958 
959       case SQL_INTERVAL_DAY_TO_SECOND:
960         sprintf((char*) s, "SQL_INTERVAL_DAY_TO_SECOND" );
961         break;
962 
963       case SQL_INTERVAL_DAY_TO_MINUTE:
964         sprintf((char*) s, "SQL_INTERVAL_DAY_TO_MINUTE" );
965         break;
966 
967       case SQL_INTERVAL_DAY:
968         sprintf((char*) s, "SQL_INTERVAL_DAY" );
969         break;
970 
971       case SQL_INTERVAL_HOUR_TO_SECOND:
972         sprintf((char*) s, "SQL_INTERVAL_HOUR_TO_SECOND" );
973         break;
974 
975       case SQL_INTERVAL_HOUR_TO_MINUTE:
976         sprintf((char*) s, "SQL_INTERVAL_HOUR_TO_MINUTE" );
977         break;
978 
979       case SQL_INTERVAL_HOUR:
980         sprintf((char*) s, "SQL_INTERVAL_HOUR" );
981         break;
982 
983       case SQL_INTERVAL_MINUTE_TO_SECOND:
984         sprintf((char*) s, "SQL_INTERVAL_MINUTE_TO_SECOND" );
985         break;
986 
987       case SQL_INTERVAL_MINUTE:
988         sprintf((char*) s, "SQL_INTERVAL_MINUTE" );
989         break;
990 
991       case SQL_INTERVAL_SECOND:
992         sprintf((char*) s, "SQL_INTERVAL_SECOND" );
993         break;
994 
995       case SQL_ALL_TYPES:
996         sprintf((char*) s, "SQL_ALL_TYPES" );
997         break;
998 
999       default:
1000         sprintf((char*) s, "Unknown(%d)", (int)type );
1001         break;
1002     }
1003 
1004     return (char*) s;
1005 }
1006 
1007 /*
1008  * display a data field as a string
1009  */
1010 
__sdata_as_string(SQLCHAR * s,SQLINTEGER type,SQLSMALLINT * ptr,SQLPOINTER buf)1011 char * __sdata_as_string( SQLCHAR *s, SQLINTEGER type,
1012         SQLSMALLINT *ptr, SQLPOINTER buf )
1013 {
1014     SQLLEN iptr;
1015 
1016     if ( ptr )
1017     {
1018         iptr = *ptr;
1019         return __data_as_string( s, type, &iptr, buf );
1020     }
1021     else
1022     {
1023         return __data_as_string( s, type, NULL, buf );
1024     }
1025 
1026     return (char*) s;
1027 }
1028 
__idata_as_string(SQLCHAR * s,SQLINTEGER type,SQLINTEGER * ptr,SQLPOINTER buf)1029 char * __idata_as_string( SQLCHAR *s, SQLINTEGER type,
1030         SQLINTEGER *ptr, SQLPOINTER buf )
1031 {
1032     SQLLEN iptr;
1033 
1034     if ( ptr )
1035     {
1036         iptr = *ptr;
1037         return __data_as_string( s, type, &iptr, buf );
1038     }
1039     else
1040     {
1041         return __data_as_string( s, type, NULL, buf );
1042     }
1043 
1044     return (char*) s;
1045 }
1046 
__data_as_string(SQLCHAR * s,SQLINTEGER type,SQLLEN * ptr,SQLPOINTER buf)1047 char * __data_as_string( SQLCHAR *s, SQLINTEGER type,
1048         SQLLEN *ptr, SQLPOINTER buf )
1049 {
1050     if ( ptr && *ptr == SQL_NULL_DATA )
1051     {
1052         sprintf((char*) s, "SQL_NULL_DATA" );
1053     }
1054     else if ( ptr && *ptr < 0 )
1055     {
1056         sprintf((char*) s, "Indicator = %d", (int)*ptr );
1057     }
1058     else if ( !buf )
1059     {
1060         sprintf((char*) s, "[NULLPTR]" );
1061     }
1062     else
1063     {
1064         switch ( type )
1065         {
1066           case SQL_INTEGER:
1067             {
1068                 SQLINTEGER val;
1069 
1070                 memcpy( &val, buf, sizeof( SQLINTEGER ));
1071                 sprintf((char*) s, "[%d]", (int)val );
1072             }
1073             break;
1074 
1075           case SQL_CHAR:
1076           case SQL_VARCHAR:
1077             sprintf((char*) s, "[%.*s]", LOG_MESSAGE_LEN, (char*)buf );
1078             break;
1079 
1080           case SQL_WCHAR:
1081           case SQL_WVARCHAR:
1082             {
1083                 int len = LOG_MESSAGE_LEN;
1084                 signed short *ptr = (signed short*)buf;
1085                 char *optr;
1086 
1087                 optr = (char*) s;
1088                 sprintf((char*)  s, "[" );
1089 
1090                 optr ++;
1091 
1092                 while( len > 0 )
1093                 {
1094                     if ( *ptr == 0x0000 )
1095                         break;
1096                     sprintf( optr, "%c", *ptr & 0x00FF );
1097                     optr ++;
1098                     len --;
1099                     ptr ++;
1100                 }
1101                 sprintf( optr, "](unicode)" );
1102             }
1103             break;
1104 
1105           case SQL_DOUBLE:
1106             {
1107                 double val;
1108 
1109                 memcpy( &val, buf, sizeof( double ));
1110                 sprintf((char*) s, "[%g]", val );
1111             }
1112             break;
1113 
1114           case SQL_FLOAT:
1115           case SQL_REAL:
1116             {
1117                 float val;
1118 
1119                 memcpy( &val, buf, sizeof( float ));
1120                 sprintf((char*) s, "[%g]", val );
1121             }
1122             break;
1123 
1124           case SQL_BIT:
1125             {
1126                 SQLCHAR val;
1127 
1128                 memcpy( &val, buf, sizeof( SQLCHAR ));
1129                 sprintf((char*) s, "[%d]", (int)val );
1130             }
1131             break;
1132 
1133           case SQL_LONGVARCHAR:
1134             sprintf((char*) s, "[LONGVARCHARDATA...]" );
1135             break;
1136 
1137           case SQL_BINARY:
1138             sprintf((char*) s, "[BINARYDATA...]" );
1139             break;
1140 
1141           case SQL_VARBINARY:
1142             sprintf((char*) s, "[VARBINARYDATA...]" );
1143             break;
1144 
1145           case SQL_LONGVARBINARY:
1146             sprintf((char*) s, "[LONGVARBINARYDATA...]" );
1147             break;
1148 
1149           case SQL_DECIMAL:
1150             sprintf((char*) s, "[DECIMAL...]" );
1151             break;
1152 
1153           case SQL_NUMERIC:
1154             sprintf((char*) s, "[NUMERIC...]" );
1155             break;
1156 
1157           case SQL_BIGINT:
1158             sprintf((char*) s, "[BIGINT...]" );
1159             break;
1160 
1161           case SQL_SMALLINT:
1162             {
1163                 short val;
1164 
1165                 memcpy( &val, buf, sizeof( short ));
1166                 sprintf((char*) s, "[%d]", (int)val );
1167             }
1168             break;
1169 
1170           case SQL_TINYINT:
1171             {
1172                 char val;
1173 
1174                 memcpy( &val, buf, sizeof( char ));
1175                 sprintf((char*) s, "[%d]", (int)val );
1176             }
1177             break;
1178 
1179           case SQL_TYPE_DATE:
1180           case SQL_DATE:
1181             sprintf((char*) s, "[DATE...]" );
1182             break;
1183 
1184           case SQL_TYPE_TIME:
1185           case SQL_TIME:
1186             sprintf((char*) s, "[TIME...]" );
1187             break;
1188 
1189           case SQL_TYPE_TIMESTAMP:
1190           case SQL_TIMESTAMP:
1191             sprintf((char*) s, "[TIMESTAMP...]" );
1192             break;
1193 
1194           case SQL_INTERVAL_YEAR:
1195           case SQL_INTERVAL_YEAR_TO_MONTH:
1196           case SQL_INTERVAL_MONTH:
1197           case SQL_INTERVAL_DAY_TO_SECOND:
1198           case SQL_INTERVAL_DAY_TO_MINUTE:
1199           case SQL_INTERVAL_DAY:
1200           case SQL_INTERVAL_HOUR_TO_SECOND:
1201           case SQL_INTERVAL_HOUR_TO_MINUTE:
1202           case SQL_INTERVAL_HOUR:
1203           case SQL_INTERVAL_MINUTE_TO_SECOND:
1204           case SQL_INTERVAL_MINUTE:
1205           case SQL_INTERVAL_SECOND:
1206             sprintf((char*) s, "[INTERVAL...]" );
1207             break;
1208 
1209           default:
1210             sprintf((char*) s, "[Data...]" );
1211             break;
1212         }
1213     }
1214 
1215     return (char*) s;
1216 }
1217 
1218 /*
1219  * display a pointer to a int
1220  */
1221 
__iptr_as_string(SQLCHAR * s,SQLINTEGER * ptr)1222 char * __iptr_as_string( SQLCHAR *s, SQLINTEGER *ptr )
1223 {
1224     if ( ptr )
1225     {
1226         sprintf((char*) s, "%p -> %ld (%d bits)", (void*)ptr, (long)*ptr, (int)sizeof( SQLINTEGER ) * 8 );
1227     }
1228     else
1229     {
1230         sprintf((char*) s, "NULLPTR" );
1231     }
1232 
1233     return (char*) s;
1234 }
1235 
__ptr_as_string(SQLCHAR * s,SQLLEN * ptr)1236 char * __ptr_as_string( SQLCHAR *s, SQLLEN *ptr )
1237 {
1238     if ( ptr )
1239     {
1240         sprintf((char*) s, "%p -> %ld (%d bits)", (void*)ptr, (long)*ptr, (int)sizeof( SQLLEN ) * 8 );
1241     }
1242     else
1243     {
1244         sprintf((char*) s, "NULLPTR" );
1245     }
1246 
1247     return (char*) s;
1248 }
1249 
1250 /*
1251  * display a pointer to a int
1252  */
1253 
__sptr_as_string(SQLCHAR * s,SQLSMALLINT * ptr)1254 char * __sptr_as_string( SQLCHAR *s, SQLSMALLINT *ptr )
1255 {
1256     if ( ptr )
1257     {
1258         sprintf((char*) s, "%p -> %d", (void*)ptr, (int)*ptr );
1259     }
1260     else
1261     {
1262         sprintf((char*) s, "NULLPTR" );
1263     }
1264 
1265     return (char*) s;
1266 }
1267 
1268 /*
1269  * convert a function id to a string
1270  */
1271 
__fid_as_string(SQLCHAR * s,SQLINTEGER type)1272 char * __fid_as_string( SQLCHAR *s, SQLINTEGER type )
1273 {
1274     switch( type )
1275     {
1276       case SQL_API_SQLALLOCCONNECT:
1277         sprintf((char*) s, "SQLAllocConnect" );
1278         break;
1279 
1280      case SQL_API_SQLALLOCENV:
1281         sprintf((char*) s, "SQLAllocEnv" );
1282         break;
1283 
1284       case SQL_API_SQLALLOCHANDLE:
1285         sprintf((char*) s, "SQLAllocHandle" );
1286         break;
1287 
1288       case SQL_API_SQLALLOCSTMT:
1289         sprintf((char*) s, "SQLAllocStmt" );
1290         break;
1291 
1292       case SQL_API_SQLALLOCHANDLESTD:
1293         sprintf((char*) s, "SQLAllochandleStd" );
1294         break;
1295 
1296       case SQL_API_SQLBINDCOL:
1297         sprintf((char*) s, "SQLBindCol" );
1298         break;
1299 
1300       case SQL_API_SQLBINDPARAM:
1301         sprintf((char*) s, "SQLBindParam" );
1302         break;
1303 
1304       case SQL_API_SQLBINDPARAMETER:
1305         sprintf((char*) s, "SQLBindParameter" );
1306         break;
1307 
1308       case SQL_API_SQLBROWSECONNECT:
1309         sprintf((char*) s, "SQLBrowseConnect" );
1310         break;
1311 
1312       case SQL_API_SQLBULKOPERATIONS:
1313         sprintf((char*) s, "SQLBulkOperations" );
1314         break;
1315 
1316       case SQL_API_SQLCANCEL:
1317         sprintf((char*) s, "SQLCancel" );
1318         break;
1319 
1320       case SQL_API_SQLCLOSECURSOR:
1321         sprintf((char*) s, "SQLCloseCursor" );
1322         break;
1323 
1324       case SQL_API_SQLCOLATTRIBUTES:
1325         sprintf((char*) s, "SQLColAttribute(s)" );
1326         break;
1327 
1328       case SQL_API_SQLCOLUMNPRIVILEGES:
1329         sprintf((char*) s, "SQLColumnPrivileges" );
1330         break;
1331 
1332       case SQL_API_SQLCOLUMNS:
1333         sprintf((char*) s, "SQLColumns" );
1334         break;
1335 
1336       case SQL_API_SQLCONNECT:
1337         sprintf((char*) s, "SQLConnect" );
1338         break;
1339 
1340       case SQL_API_SQLCOPYDESC:
1341         sprintf((char*) s, "SQLCopyDesc" );
1342         break;
1343 
1344       case SQL_API_SQLDATASOURCES:
1345         sprintf((char*) s, "SQLDataSources" );
1346         break;
1347 
1348       case SQL_API_SQLDESCRIBECOL:
1349         sprintf((char*) s, "SQLDescribeCol" );
1350         break;
1351 
1352       case SQL_API_SQLDESCRIBEPARAM:
1353         sprintf((char*) s, "SQLDescribeParam" );
1354         break;
1355 
1356       case SQL_API_SQLDISCONNECT:
1357         sprintf((char*) s, "SQLDisconnect" );
1358         break;
1359 
1360       case SQL_API_SQLDRIVERCONNECT:
1361         sprintf((char*) s, "SQLDriverConnect" );
1362         break;
1363 
1364       case SQL_API_SQLDRIVERS:
1365         sprintf((char*) s, "SQLDrivers" );
1366         break;
1367 
1368       case SQL_API_SQLENDTRAN:
1369         sprintf((char*) s, "SQLEndTran" );
1370         break;
1371 
1372       case SQL_API_SQLERROR:
1373         sprintf((char*) s, "SQLError" );
1374         break;
1375 
1376       case SQL_API_SQLEXECDIRECT:
1377         sprintf((char*) s, "SQLExecDirect" );
1378         break;
1379 
1380       case SQL_API_SQLEXECUTE:
1381         sprintf((char*) s, "SQLExecute" );
1382         break;
1383 
1384       case SQL_API_SQLEXTENDEDFETCH:
1385         sprintf((char*) s, "SQLExtendedFetch" );
1386         break;
1387 
1388       case SQL_API_SQLFETCH:
1389         sprintf((char*) s, "SQLFetch" );
1390         break;
1391 
1392       case SQL_API_SQLFETCHSCROLL:
1393         sprintf((char*) s, "SQLFetchScroll" );
1394         break;
1395 
1396       case SQL_API_SQLFOREIGNKEYS:
1397         sprintf((char*) s, "SQLForeignKeys" );
1398         break;
1399 
1400       case SQL_API_SQLFREEENV:
1401         sprintf((char*) s, "SQLFreeEnv" );
1402         break;
1403 
1404       case SQL_API_SQLFREEHANDLE:
1405         sprintf((char*) s, "SQLFreeHandle" );
1406         break;
1407 
1408       case SQL_API_SQLFREESTMT:
1409         sprintf((char*) s, "SQLFreeStmt" );
1410         break;
1411 
1412       case SQL_API_SQLFREECONNECT:
1413         sprintf((char*) s, "SQLFreeConnect" );
1414         break;
1415 
1416        case SQL_API_SQLGETCONNECTATTR:
1417         sprintf((char*) s, "SQLGetConnectAttr" );
1418         break;
1419 
1420       case SQL_API_SQLGETCONNECTOPTION:
1421         sprintf((char*) s, "SQLGetConnectOption" );
1422         break;
1423 
1424       case SQL_API_SQLGETCURSORNAME:
1425         sprintf((char*) s, "SQLGetCursorName" );
1426         break;
1427 
1428       case SQL_API_SQLGETDATA:
1429         sprintf((char*) s, "SQLGetData" );
1430         break;
1431 
1432       case SQL_API_SQLGETDESCFIELD:
1433         sprintf((char*) s, "SQLGetDescField" );
1434         break;
1435 
1436       case SQL_API_SQLGETDESCREC:
1437         sprintf((char*) s, "SQLGetDescRec" );
1438         break;
1439 
1440       case SQL_API_SQLGETDIAGFIELD:
1441         sprintf((char*) s, "SQLGetDiagField" );
1442         break;
1443 
1444       case SQL_API_SQLGETENVATTR:
1445         sprintf((char*) s, "SQLGetEnvAttr" );
1446         break;
1447 
1448       case SQL_API_SQLGETFUNCTIONS:
1449         sprintf((char*) s, "SQLGetFunctions" );
1450         break;
1451 
1452       case SQL_API_SQLGETINFO:
1453         sprintf((char*) s, "SQLGetInfo" );
1454         break;
1455 
1456       case SQL_API_SQLGETSTMTATTR:
1457         sprintf((char*) s, "SQLGetStmtAttr" );
1458         break;
1459 
1460       case SQL_API_SQLGETSTMTOPTION:
1461         sprintf((char*) s, "SQLGetStmtOption" );
1462         break;
1463 
1464       case SQL_API_SQLGETTYPEINFO:
1465         sprintf((char*) s, "SQLGetTypeInfo" );
1466         break;
1467 
1468       case SQL_API_SQLMORERESULTS:
1469         sprintf((char*) s, "SQLMoreResults" );
1470         break;
1471 
1472       case SQL_API_SQLNATIVESQL:
1473         sprintf((char*) s, "SQLNativeSql" );
1474         break;
1475 
1476       case SQL_API_SQLNUMPARAMS:
1477         sprintf((char*) s, "SQLNumParams" );
1478         break;
1479 
1480       case SQL_API_SQLNUMRESULTCOLS:
1481         sprintf((char*) s, "SQLNumResultCols" );
1482         break;
1483 
1484       case SQL_API_SQLPARAMDATA:
1485         sprintf((char*) s, "SQLParamData" );
1486         break;
1487 
1488       case SQL_API_SQLPARAMOPTIONS:
1489         sprintf((char*) s, "SQLParamOptions" );
1490         break;
1491 
1492       case SQL_API_SQLPREPARE:
1493         sprintf((char*) s, "SQLPrepare" );
1494         break;
1495 
1496       case SQL_API_SQLPRIMARYKEYS:
1497         sprintf((char*) s, "SQLPrimaryKeys" );
1498         break;
1499 
1500       case SQL_API_SQLPROCEDURECOLUMNS:
1501         sprintf((char*) s, "SQLProcedureColumns" );
1502         break;
1503 
1504       case SQL_API_SQLPROCEDURES:
1505         sprintf((char*) s, "SQLProcedures" );
1506         break;
1507 
1508       case SQL_API_SQLPUTDATA:
1509         sprintf((char*) s, "SQLPutData" );
1510         break;
1511 
1512       case SQL_API_SQLROWCOUNT:
1513         sprintf((char*) s, "SQLRowCount" );
1514         break;
1515 
1516       case SQL_API_SQLSETCONNECTATTR:
1517         sprintf((char*) s, "SQLSetConnectAttr" );
1518         break;
1519 
1520       case SQL_API_SQLSETCONNECTOPTION:
1521         sprintf((char*) s, "SQLSetConnectOption" );
1522         break;
1523 
1524       case SQL_API_SQLSETCURSORNAME:
1525         sprintf((char*) s, "SQLSetCursorName" );
1526         break;
1527 
1528       case SQL_API_SQLSETDESCFIELD:
1529         sprintf((char*) s, "SQLSetDescField" );
1530         break;
1531 
1532       case SQL_API_SQLSETDESCREC:
1533         sprintf((char*) s, "SQLSetDescRec" );
1534         break;
1535 
1536       case SQL_API_SQLSETENVATTR:
1537         sprintf((char*) s, "SQLSetEnvAttr" );
1538         break;
1539 
1540       case SQL_API_SQLSETPARAM:
1541         sprintf((char*) s, "SQLSetParam" );
1542         break;
1543 
1544       case SQL_API_SQLSETPOS:
1545         sprintf((char*) s, "SQLSetPos" );
1546         break;
1547 
1548       case SQL_API_SQLSETSCROLLOPTIONS:
1549         sprintf((char*) s, "SQLSetScrollOptions" );
1550         break;
1551 
1552       case SQL_API_SQLSETSTMTATTR:
1553         sprintf((char*) s, "SQLSetStmtAttr" );
1554         break;
1555 
1556       case SQL_API_SQLSETSTMTOPTION:
1557         sprintf((char*) s, "SQLSetStmtOption" );
1558         break;
1559 
1560       case SQL_API_SQLSPECIALCOLUMNS:
1561         sprintf((char*) s, "SQLSpecialColumns" );
1562         break;
1563 
1564       case SQL_API_SQLSTATISTICS:
1565         sprintf((char*) s, "SQLStatistics" );
1566         break;
1567 
1568       case SQL_API_SQLTABLEPRIVILEGES:
1569         sprintf((char*) s, "SQLTablePrivileges" );
1570         break;
1571 
1572       case SQL_API_SQLTABLES:
1573         sprintf((char*) s, "SQLTables" );
1574         break;
1575 
1576       case SQL_API_SQLTRANSACT:
1577         sprintf((char*) s, "SQLTransact" );
1578         break;
1579 
1580       case SQL_API_SQLGETDIAGREC:
1581         sprintf((char*) s, "SQLGetDiagRec" );
1582         break;
1583 
1584       default:
1585         sprintf((char*) s, "%d", (int)type );
1586     }
1587 
1588     return (char*) s;
1589 }
1590 
1591 /*
1592  * convert a column attribute to a string
1593  */
1594 
__col_attr_as_string(SQLCHAR * s,SQLINTEGER type)1595 char * __col_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1596 {
1597     switch( type )
1598     {
1599       case SQL_DESC_AUTO_UNIQUE_VALUE:
1600         sprintf((char*) s, "SQL_DESC_AUTO_UNIQUE_VALUE" );
1601         break;
1602 
1603       case SQL_DESC_BASE_COLUMN_NAME:
1604         sprintf((char*) s, "SQL_DESC_BASE_COLUMN_NAME" );
1605         break;
1606 
1607       case SQL_DESC_BASE_TABLE_NAME:
1608         sprintf((char*) s, "SQL_DESC_BASE_TABLE_NAME" );
1609         break;
1610 
1611       case SQL_DESC_CASE_SENSITIVE:
1612         sprintf((char*) s, "SQL_DESC_CASE_SENSITIVE" );
1613         break;
1614 
1615       case SQL_DESC_CATALOG_NAME:
1616         sprintf((char*)  s, "SQL_DESC_CATALOG_NAME" );
1617         break;
1618 
1619       case SQL_DESC_CONCISE_TYPE:
1620         sprintf((char*)  s, "SQL_DESC_CONCISE_TYPE" );
1621         break;
1622 
1623       case SQL_DESC_DISPLAY_SIZE:
1624         sprintf((char*)  s, "SQL_DESC_DISPLAY_SIZE" );
1625         break;
1626 
1627       case SQL_DESC_FIXED_PREC_SCALE:
1628         sprintf((char*)  s, "SQL_DESC_FIXED_PREC_SCALE" );
1629         break;
1630 
1631       case SQL_DESC_LABEL:
1632         sprintf((char*) s, "SQL_DESC_LABEL" );
1633         break;
1634 
1635       case SQL_COLUMN_NAME:
1636         sprintf((char*) s, "SQL_COLUMN_NAME" );
1637         break;
1638 
1639       case SQL_DESC_LENGTH:
1640         sprintf((char*) s, "SQL_DESC_LENGTH" );
1641         break;
1642 
1643       case SQL_COLUMN_LENGTH:
1644         sprintf((char*) s, "SQL_COLUMN_LENGTH" );
1645         break;
1646 
1647       case SQL_DESC_LITERAL_PREFIX:
1648         sprintf((char*) s, "SQL_DESC_LITERAL_PREFIX" );
1649         break;
1650 
1651       case SQL_DESC_LITERAL_SUFFIX:
1652         sprintf((char*) s, "SQL_DESC_LITERAL_SUFFIX" );
1653         break;
1654 
1655       case SQL_DESC_LOCAL_TYPE_NAME:
1656         sprintf((char*) s, "SQL_DESC_LOCAL_TYPE_NAME" );
1657         break;
1658 
1659       case SQL_DESC_NAME:
1660         sprintf((char*) s, "SQL_DESC_NAME" );
1661         break;
1662 
1663       case SQL_DESC_NULLABLE:
1664         sprintf((char*) s, "SQL_DESC_NULLABLE" );
1665         break;
1666 
1667       case SQL_COLUMN_NULLABLE:
1668         sprintf((char*) s, "SQL_COLUMN_NULLABLE" );
1669         break;
1670 
1671       case SQL_DESC_NUM_PREC_RADIX:
1672         sprintf((char*) s, "SQL_DESC_NUM_PREC_RADIX" );
1673         break;
1674 
1675       case SQL_DESC_OCTET_LENGTH:
1676         sprintf((char*) s, "SQL_DESC_OCTET_LENGTH" );
1677         break;
1678 
1679       case SQL_DESC_PRECISION:
1680         sprintf((char*) s, "SQL_DESC_PRECISION" );
1681         break;
1682 
1683       case SQL_COLUMN_PRECISION:
1684         sprintf((char*) s, "SQL_COLUMN_PRECISION" );
1685         break;
1686 
1687       case SQL_DESC_SCALE:
1688         sprintf((char*) s, "SQL_DESC_SCALE" );
1689         break;
1690 
1691       case SQL_COLUMN_SCALE:
1692         sprintf((char*) s, "SQL_COLUMN_SCALE" );
1693         break;
1694 
1695       case SQL_DESC_SCHEMA_NAME:
1696         sprintf((char*) s, "SQL_DESC_SCHEMA_NAME" );
1697         break;
1698 
1699       case SQL_DESC_SEARCHABLE:
1700         sprintf((char*) s, "SQL_DESC_SEARCHABLE" );
1701         break;
1702 
1703       case SQL_DESC_TABLE_NAME:
1704         sprintf((char*) s, "SQL_DESC_TABLE_NAME" );
1705         break;
1706 
1707       case SQL_DESC_TYPE:
1708         sprintf((char*) s, "SQL_DESC_TYPE" );
1709         break;
1710 
1711       case SQL_DESC_TYPE_NAME:
1712         sprintf((char*) s, "SQL_DESC_TYPE_NAME" );
1713         break;
1714 
1715       case SQL_DESC_UNNAMED:
1716         sprintf((char*) s, "SQL_DESC_UNNAMED" );
1717         break;
1718 
1719       case SQL_DESC_UNSIGNED:
1720         sprintf((char*) s, "SQL_DESC_UNSIGNED" );
1721         break;
1722 
1723       case SQL_DESC_UPDATABLE:
1724         sprintf((char*) s, "SQL_DESC_UPDATABLE" );
1725         break;
1726 
1727       default:
1728         sprintf((char*) s, "%d", (int)type );
1729     }
1730 
1731     return (char*) s;
1732 }
1733 
1734 /*
1735  * convert a connect attribute to a string
1736  */
1737 
__env_attr_as_string(SQLCHAR * s,SQLINTEGER type)1738 char * __env_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1739 {
1740     switch( type )
1741     {
1742       case SQL_ATTR_CONNECTION_POOLING:
1743         sprintf((char*) s, "SQL_ATTR_CONNECTION_POOLING" );
1744         break;
1745 
1746       case SQL_ATTR_CP_MATCH:
1747         sprintf((char*) s, "SQL_ATTR_CP_MATCH" );
1748         break;
1749 
1750       case SQL_ATTR_ODBC_VERSION:
1751         sprintf((char*) s, "SQL_ATTR_ODBC_VERSION" );
1752         break;
1753 
1754       case SQL_ATTR_OUTPUT_NTS:
1755         sprintf((char*) s, "SQL_ATTR_OUTPUT_NTS" );
1756         break;
1757 
1758       default:
1759         sprintf((char*) s, "%d", (int)type );
1760     }
1761 
1762     return (char*) s;
1763 }
1764 
1765 /*
1766  * convert a connect attribute to a string
1767  */
1768 
__con_attr_as_string(SQLCHAR * s,SQLINTEGER type)1769 char * __con_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1770 {
1771     switch( type )
1772     {
1773       case SQL_ATTR_ACCESS_MODE:
1774         sprintf((char*) s, "SQL_ATTR_ACCESS_MODE" );
1775         break;
1776 
1777       case SQL_ATTR_ASYNC_ENABLE:
1778         sprintf((char*) s, "SQL_ATTR_ASYNC_ENABLE" );
1779         break;
1780 
1781       case SQL_ATTR_AUTO_IPD:
1782         sprintf((char*) s, "SQL_ATTR_AUTO_IPD" );
1783         break;
1784 
1785       case SQL_ATTR_AUTOCOMMIT:
1786         sprintf((char*) s, "SQL_ATTR_AUTOCOMMIT" );
1787         break;
1788 
1789       case SQL_ATTR_CONNECTION_TIMEOUT:
1790         sprintf((char*) s, "SQL_ATTR_CONNECTION_TIMEOUT" );
1791         break;
1792 
1793       case SQL_ATTR_CURRENT_CATALOG:
1794         sprintf((char*) s, "SQL_ATTR_CURRENT_CATALOG" );
1795         break;
1796 
1797       case SQL_ATTR_LOGIN_TIMEOUT:
1798         sprintf((char*) s, "SQL_ATTR_LOGIN_TIMEOUT" );
1799         break;
1800 
1801       case SQL_ATTR_METADATA_ID:
1802         sprintf((char*) s, "SQL_ATTR_METADATA_ID" );
1803         break;
1804 
1805       case SQL_ATTR_ODBC_CURSORS:
1806         sprintf((char*) s, "SQL_ATTR_ODBC_CURSORS" );
1807         break;
1808 
1809       case SQL_ATTR_PACKET_SIZE:
1810         sprintf((char*) s, "SQL_ATTR_PACKET_SIZE" );
1811         break;
1812 
1813       case SQL_ATTR_QUIET_MODE:
1814         sprintf((char*) s, "SQL_ATTR_QUIET_MODE" );
1815         break;
1816 
1817       case SQL_ATTR_TRACE:
1818         sprintf((char*) s, "SQL_ATTR_TRACE" );
1819         break;
1820 
1821       case SQL_ATTR_TRACEFILE:
1822         sprintf((char*) s, "SQL_ATTR_TRACEFILE" );
1823         break;
1824 
1825       case SQL_ATTR_TRANSLATE_LIB:
1826         sprintf((char*) s, "SQL_ATTR_TRANSLATE_LIB" );
1827         break;
1828 
1829       case SQL_ATTR_TRANSLATE_OPTION:
1830         sprintf((char*) s, "SQL_ATTR_TRANSLATE_OPTION" );
1831         break;
1832 
1833       case SQL_ATTR_TXN_ISOLATION:
1834         sprintf((char*) s, "SQL_ATTR_TXN_ISOLATION" );
1835         break;
1836 
1837       default:
1838         sprintf((char*)  s, "%d", (int)type );
1839     }
1840 
1841     return (char*) s;
1842 }
1843 
1844 /*
1845  * convert a diagnostic attribute to a string
1846  */
1847 
__diag_attr_as_string(SQLCHAR * s,SQLINTEGER type)1848 char * __diag_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1849 {
1850     switch( type )
1851     {
1852       case SQL_DIAG_CURSOR_ROW_COUNT:
1853         sprintf((char*) s, "SQL_DIAG_CURSOR_ROW_COUNT" );
1854         break;
1855 
1856       case SQL_DIAG_DYNAMIC_FUNCTION:
1857         sprintf((char*) s, "SQL_DIAG_DYNAMIC_FUNCTION" );
1858         break;
1859 
1860       case SQL_DIAG_DYNAMIC_FUNCTION_CODE:
1861         sprintf((char*) s, "SQL_DIAG_DYNAMIC_FUNCTION_CODE" );
1862         break;
1863 
1864       case SQL_DIAG_NUMBER:
1865         sprintf((char*) s, "SQL_DIAG_NUMBER" );
1866         break;
1867 
1868       case SQL_DIAG_RETURNCODE:
1869         sprintf((char*) s, "SQL_DIAG_RETURNCODE" );
1870         break;
1871 
1872       case SQL_DIAG_ROW_COUNT:
1873         sprintf((char*) s, "SQL_DIAG_ROW_COUNT" );
1874         break;
1875 
1876       case SQL_DIAG_CLASS_ORIGIN:
1877         sprintf((char*) s, "SQL_DIAG_CLASS_ORIGIN" );
1878         break;
1879 
1880       case SQL_DIAG_COLUMN_NUMBER:
1881         sprintf((char*) s, "SQL_DIAG_COLUMN_NUMBER" );
1882         break;
1883 
1884       case SQL_DIAG_CONNECTION_NAME:
1885         sprintf((char*) s, "SQL_DIAG_CONNECTION_NAME" );
1886         break;
1887 
1888       case SQL_DIAG_MESSAGE_TEXT:
1889         sprintf((char*) s, "SQL_DIAG_MESSAGE_TEXT" );
1890         break;
1891 
1892       case SQL_DIAG_NATIVE:
1893         sprintf((char*) s, "SQL_DIAG_NATIVE" );
1894         break;
1895 
1896       case SQL_DIAG_ROW_NUMBER:
1897         sprintf((char*) s, "SQL_DIAG_ROW_NUMBER" );
1898         break;
1899 
1900       case SQL_DIAG_SERVER_NAME:
1901         sprintf((char*) s, "SQL_DIAG_SERVER_NAME" );
1902         break;
1903 
1904       case SQL_DIAG_SQLSTATE:
1905         sprintf((char*) s, "SQL_DIAG_SQLSTATE" );
1906         break;
1907 
1908       case SQL_DIAG_SUBCLASS_ORIGIN:
1909         sprintf((char*) s, "SQL_DIAG_SUBCLASS_ORIGIN" );
1910         break;
1911 
1912       default:
1913         sprintf((char*)  s, "%d", (int)type );
1914     }
1915 
1916     return (char*) s;
1917 }
1918 
1919 /*
1920  * convert a descriptor attribute to a string
1921  */
1922 
__desc_attr_as_string(SQLCHAR * s,SQLINTEGER type)1923 char * __desc_attr_as_string( SQLCHAR *s, SQLINTEGER type )
1924 {
1925     switch( type )
1926     {
1927       case SQL_DESC_ALLOC_TYPE:
1928         sprintf((char*)  s, "SQL_DESC_ALLOC_TYPE" );
1929         break;
1930 
1931       case SQL_DESC_ARRAY_SIZE:
1932         sprintf((char*)  s, "SQL_DESC_ARRAY_SIZE" );
1933         break;
1934 
1935       case SQL_DESC_ARRAY_STATUS_PTR:
1936         sprintf((char*)  s, "SQL_DESC_ARRAY_STATUS_PTR" );
1937         break;
1938 
1939       case SQL_DESC_BIND_OFFSET_PTR:
1940         sprintf((char*)  s, "SQL_DESC_BIND_OFFSET_PTR" );
1941         break;
1942 
1943       case SQL_DESC_BIND_TYPE:
1944         sprintf((char*)  s, "SQL_DESC_BIND_TYPE" );
1945         break;
1946 
1947       case SQL_DESC_COUNT:
1948         sprintf((char*)  s, "SQL_DESC_COUNT" );
1949         break;
1950 
1951       case SQL_DESC_ROWS_PROCESSED_PTR:
1952         sprintf((char*)  s, "SQL_DESC_ROWS_PROCESSED_PTR" );
1953         break;
1954 
1955       case SQL_DESC_AUTO_UNIQUE_VALUE:
1956         sprintf((char*)  s, "SQL_DESC_AUTO_UNIQUE_VALUE" );
1957         break;
1958 
1959       case SQL_DESC_BASE_COLUMN_NAME:
1960         sprintf((char*)  s, "SQL_DESC_BASE_COLUMN_NAME" );
1961         break;
1962 
1963       case SQL_DESC_BASE_TABLE_NAME:
1964         sprintf((char*)  s, "SQL_DESC_BASE_TABLE_NAME" );
1965         break;
1966 
1967       case SQL_DESC_CASE_SENSITIVE:
1968         sprintf((char*)  s, "SQL_DESC_CASE_SENSITIVE" );
1969         break;
1970 
1971       case SQL_DESC_CATALOG_NAME:
1972         sprintf((char*)  s, "SQL_DESC_CATALOG_NAME" );
1973         break;
1974 
1975       case SQL_DESC_CONCISE_TYPE:
1976         sprintf((char*)  s, "SQL_DESC_CONCISE_TYPE" );
1977         break;
1978 
1979       case SQL_DESC_DATA_PTR:
1980         sprintf((char*)  s, "SQL_DESC_DATA_PTR" );
1981         break;
1982 
1983       case SQL_DESC_DATETIME_INTERVAL_CODE:
1984         sprintf((char*)  s, "SQL_DESC_DATETIME_INTERVAL_CODE" );
1985         break;
1986 
1987       case SQL_DESC_DATETIME_INTERVAL_PRECISION:
1988         sprintf((char*)  s, "SQL_DESC_DATETIME_INTERVAL_PRECISION" );
1989         break;
1990 
1991       case SQL_DESC_DISPLAY_SIZE:
1992         sprintf((char*)  s, "SQL_DESC_DISPLAY_SIZE" );
1993         break;
1994 
1995       case SQL_DESC_FIXED_PREC_SCALE:
1996         sprintf((char*)  s, "SQL_DESC_FIXED_PREC_SCALE" );
1997         break;
1998 
1999       case SQL_DESC_INDICATOR_PTR:
2000         sprintf((char*)  s, "SQL_DESC_INDICATOR_PTR" );
2001         break;
2002 
2003       case SQL_DESC_LABEL:
2004         sprintf((char*)  s, "SQL_DESC_LABEL" );
2005         break;
2006 
2007       case SQL_DESC_LENGTH:
2008         sprintf((char*)  s, "SQL_DESC_LENGTH" );
2009         break;
2010 
2011       case SQL_DESC_LITERAL_PREFIX:
2012         sprintf((char*)  s, "SQL_DESC_LITERAL_PREFIX" );
2013         break;
2014 
2015       case SQL_DESC_LITERAL_SUFFIX:
2016         sprintf((char*)  s, "SQL_DESC_LITERAL_SUFFIX" );
2017         break;
2018 
2019       case SQL_DESC_LOCAL_TYPE_NAME:
2020         sprintf((char*)  s, "SQL_DESC_LOCAL_TYPE_NAME" );
2021         break;
2022 
2023       case SQL_DESC_NAME:
2024         sprintf((char*)  s, "SQL_DESC_NAME" );
2025         break;
2026 
2027       case SQL_DESC_NULLABLE:
2028         sprintf((char*)  s, "SQL_DESC_NULLABLE" );
2029         break;
2030 
2031       case SQL_DESC_NUM_PREC_RADIX:
2032         sprintf((char*)  s, "SQL_DESC_NUM_PREC_RADIX" );
2033         break;
2034 
2035       case SQL_DESC_OCTET_LENGTH:
2036         sprintf((char*)  s, "SQL_DESC_OCTET_LENGTH" );
2037         break;
2038 
2039       case SQL_DESC_OCTET_LENGTH_PTR:
2040         sprintf((char*)  s, "SQL_DESC_OCTET_LENGTH_PTR" );
2041         break;
2042 
2043       case SQL_DESC_PARAMETER_TYPE:
2044         sprintf((char*)  s, "SQL_DESC_PARAMETER_TYPE" );
2045         break;
2046 
2047       case SQL_DESC_PRECISION:
2048         sprintf((char*)  s, "SQL_DESC_PRECISION" );
2049         break;
2050 
2051       case SQL_DESC_SCALE:
2052         sprintf((char*)  s, "SQL_DESC_SCALE" );
2053         break;
2054 
2055       case SQL_DESC_SCHEMA_NAME:
2056         sprintf((char*)  s, "SQL_DESC_SCHEMA_NAME" );
2057         break;
2058 
2059       case SQL_DESC_SEARCHABLE:
2060         sprintf((char*)  s, "SQL_DESC_SEARCHABLE" );
2061         break;
2062 
2063       case SQL_DESC_TABLE_NAME:
2064         sprintf((char*)  s, "SQL_DESC_TABLE_NAME" );
2065         break;
2066 
2067       case SQL_DESC_TYPE:
2068         sprintf((char*)  s, "SQL_DESC_TYPE" );
2069         break;
2070 
2071       case SQL_DESC_TYPE_NAME:
2072         sprintf((char*)  s, "SQL_DESC_TYPE_NAME" );
2073         break;
2074 
2075       case SQL_DESC_UNNAMED:
2076         sprintf((char*)  s, "SQL_DESC_UNNAMED" );
2077         break;
2078 
2079       case SQL_DESC_UNSIGNED:
2080         sprintf((char*)  s, "SQL_DESC_UNSIGNED" );
2081         break;
2082 
2083       case SQL_DESC_UPDATABLE:
2084         sprintf((char*)  s, "SQL_DESC_UPDATABLE" );
2085         break;
2086 
2087       default:
2088         sprintf((char*)  s, "%d", (int)type );
2089     }
2090 
2091     return (char*) s;
2092 }
2093 
2094 /*
2095  * convert a statement attribute to a string
2096  */
2097 
__stmt_attr_as_string(SQLCHAR * s,SQLINTEGER type)2098 char * __stmt_attr_as_string( SQLCHAR *s, SQLINTEGER type )
2099 {
2100     switch( type )
2101     {
2102       case SQL_ATTR_APP_PARAM_DESC:
2103         sprintf((char*)  s, "SQL_ATTR_APP_PARAM_DESC" );
2104         break;
2105 
2106       case SQL_ATTR_APP_ROW_DESC:
2107         sprintf((char*)  s, "SQL_ATTR_APP_ROW_DESC" );
2108         break;
2109 
2110       case SQL_ATTR_ASYNC_ENABLE:
2111         sprintf((char*)  s, "SQL_ATTR_ASYNC_ENABLE" );
2112         break;
2113 
2114       case SQL_ATTR_CONCURRENCY:
2115         sprintf((char*)  s, "SQL_ATTR_CONCURRENCY" );
2116         break;
2117 
2118       case SQL_ATTR_CURSOR_SCROLLABLE:
2119         sprintf((char*)  s, "SQL_ATTR_CURSOR_SCROLLABLE" );
2120         break;
2121 
2122       case SQL_ATTR_CURSOR_SENSITIVITY:
2123         sprintf((char*)  s, "SQL_ATTR_CURSOR_SENSITIVITY" );
2124         break;
2125 
2126       case SQL_ATTR_CURSOR_TYPE:
2127         sprintf((char*)  s, "SQL_ATTR_CURSOR_TYPE" );
2128         break;
2129 
2130       case SQL_ATTR_ENABLE_AUTO_IPD:
2131         sprintf((char*)  s, "SQL_ATTR_ENABLE_AUTO_IPD" );
2132         break;
2133 
2134       case SQL_ATTR_FETCH_BOOKMARK_PTR:
2135         sprintf((char*)  s, "SQL_ATTR_FETCH_BOOKMARK_PTR" );
2136         break;
2137 
2138       case SQL_ATTR_IMP_PARAM_DESC:
2139         sprintf((char*)  s, "SQL_ATTR_IMP_PARAM_DESC" );
2140         break;
2141 
2142       case SQL_ATTR_IMP_ROW_DESC:
2143         sprintf((char*)  s, "SQL_ATTR_IMP_ROW_DESC" );
2144         break;
2145 
2146       case SQL_ATTR_KEYSET_SIZE:
2147         sprintf((char*)  s, "SQL_ATTR_KEYSET_SIZE" );
2148         break;
2149 
2150       case SQL_ATTR_MAX_LENGTH:
2151         sprintf((char*)  s, "SQL_ATTR_MAX_LENGTH" );
2152         break;
2153 
2154       case SQL_ATTR_MAX_ROWS:
2155         sprintf((char*)  s, "SQL_ATTR_MAX_ROWS" );
2156         break;
2157 
2158       case SQL_ATTR_METADATA_ID:
2159         sprintf((char*)  s, "SQL_ATTR_METADATA_ID" );
2160         break;
2161 
2162       case SQL_ATTR_NOSCAN:
2163         sprintf((char*)  s, "SQL_ATTR_NOSCAN" );
2164         break;
2165 
2166       case SQL_ATTR_PARAM_BIND_OFFSET_PTR:
2167         sprintf((char*)  s, "SQL_ATTR_PARAM_BIND_OFFSET_PTR" );
2168         break;
2169 
2170       case SQL_ATTR_PARAM_BIND_TYPE:
2171         sprintf((char*)  s, "SQL_ATTR_PARAM_BIND_TYPE" );
2172         break;
2173 
2174       case SQL_ATTR_PARAM_OPERATION_PTR:
2175         sprintf((char*)  s, "SQL_ATTR_PARAM_OPERATION_PTR" );
2176         break;
2177 
2178       case SQL_ATTR_PARAM_STATUS_PTR:
2179         sprintf((char*)  s, "SQL_ATTR_PARAM_STATUS_PTR" );
2180         break;
2181 
2182       case SQL_ATTR_PARAMS_PROCESSED_PTR:
2183         sprintf((char*)  s, "SQL_ATTR_PARAMS_PROCESSED_PTR" );
2184         break;
2185 
2186       case SQL_ATTR_PARAMSET_SIZE:
2187         sprintf((char*)  s, "SQL_ATTR_PARAMSET_SIZE" );
2188         break;
2189 
2190       case SQL_ATTR_QUERY_TIMEOUT:
2191         sprintf((char*)  s, "SQL_ATTR_QUERY_TIMEOUT" );
2192         break;
2193 
2194       case SQL_ATTR_RETRIEVE_DATA:
2195         sprintf((char*)  s, "SQL_ATTR_RETRIEVE_DATA" );
2196         break;
2197 
2198       case SQL_ROWSET_SIZE:
2199         sprintf((char*)  s, "SQL_ROWSET_SIZE" );
2200         break;
2201 
2202       case SQL_ATTR_ROW_ARRAY_SIZE:
2203         sprintf((char*)  s, "SQL_ATTR_ROW_ARRAY_SIZE" );
2204         break;
2205 
2206       case SQL_ATTR_ROW_BIND_OFFSET_PTR:
2207         sprintf((char*)  s, "SQL_ATTR_ROW_BIND_OFFSET_PTR" );
2208         break;
2209 
2210       case SQL_ATTR_ROW_BIND_TYPE:
2211         sprintf((char*)  s, "SQL_ATTR_ROW_BIND_TYPE" );
2212         break;
2213 
2214       case SQL_ATTR_ROW_NUMBER:
2215         sprintf((char*)  s, "SQL_ATTR_ROW_NUMBER" );
2216         break;
2217 
2218       case SQL_ATTR_ROW_OPERATION_PTR:
2219         sprintf((char*)  s, "SQL_ATTR_ROW_OPERATION_PTR" );
2220         break;
2221 
2222       case SQL_ATTR_ROW_STATUS_PTR:
2223         sprintf((char*)  s, "SQL_ATTR_ROW_STATUS_PTR" );
2224         break;
2225 
2226       case SQL_ATTR_ROWS_FETCHED_PTR:
2227         sprintf((char*)  s, "SQL_ATTR_ROWS_FETCHED_PTR" );
2228         break;
2229 
2230       case SQL_ATTR_SIMULATE_CURSOR:
2231         sprintf((char*)  s, "SQL_ATTR_SIMULATE_CURSOR" );
2232         break;
2233 
2234       case SQL_ATTR_USE_BOOKMARKS:
2235         sprintf((char*)  s, "SQL_ATTR_USE_BOOKMARKS" );
2236         break;
2237 
2238       default:
2239         sprintf((char*)  s, "%d", (int)type );
2240     }
2241 
2242     return (char*) s;
2243 }
2244 
2245 /*
2246  * return a SQLGetInfo type as a string
2247  */
2248 
__info_as_string(SQLCHAR * s,SQLINTEGER type)2249 char * __info_as_string( SQLCHAR *s, SQLINTEGER type )
2250 {
2251     switch( type )
2252     {
2253       case SQL_ACCESSIBLE_PROCEDURES:
2254         sprintf((char*)  s, "SQL_ACCESSIBLE_PROCEDURES" );
2255         break;
2256 
2257       case SQL_ACCESSIBLE_TABLES:
2258         sprintf((char*)  s, "SQL_ACCESSIBLE_TABLES" );
2259         break;
2260 
2261       case SQL_ACTIVE_ENVIRONMENTS:
2262         sprintf((char*)  s, "SQL_ACTIVE_ENVIRONMENTS" );
2263         break;
2264 
2265       case SQL_AGGREGATE_FUNCTIONS:
2266         sprintf((char*)  s, "SQL_AGGREGATE_FUNCTIONS" );
2267         break;
2268 
2269       case SQL_ALTER_DOMAIN:
2270         sprintf((char*)  s, "SQL_ALTER_DOMAIN" );
2271         break;
2272 
2273       case SQL_ALTER_TABLE:
2274         sprintf((char*)  s, "SQL_ALTER_TABLE" );
2275         break;
2276 
2277       case SQL_ASYNC_MODE:
2278         sprintf((char*)  s, "SQL_ASYNC_MODE" );
2279         break;
2280 
2281       case SQL_BATCH_ROW_COUNT:
2282         sprintf((char*)  s, "SQL_BATCH_ROW_COUNT" );
2283         break;
2284 
2285       case SQL_BATCH_SUPPORT:
2286         sprintf((char*)  s, "SQL_BATCH_SUPPORT" );
2287         break;
2288 
2289       case SQL_BOOKMARK_PERSISTENCE:
2290         sprintf((char*)  s, "SQL_BOOKMARK_PERSISTENCE" );
2291         break;
2292 
2293       case SQL_CATALOG_LOCATION:
2294         sprintf((char*)  s, "SQL_CATALOG_LOCATION" );
2295         break;
2296 
2297       case SQL_CATALOG_NAME:
2298         sprintf((char*)  s, "SQL_CATALOG_NAME" );
2299         break;
2300 
2301       case SQL_CATALOG_NAME_SEPARATOR:
2302         sprintf((char*)  s, "SQL_CATALOG_NAME_SEPARATOR" );
2303         break;
2304 
2305       case SQL_CATALOG_TERM:
2306         sprintf((char*)  s, "SQL_CATALOG_TERM" );
2307         break;
2308 
2309       case SQL_CATALOG_USAGE:
2310         sprintf((char*)  s, "SQL_CATALOG_USAGE" );
2311         break;
2312 
2313       case SQL_COLLATION_SEQ:
2314         sprintf((char*)  s, "SQL_COLLATION_SEQ" );
2315         break;
2316 
2317       case SQL_COLUMN_ALIAS:
2318         sprintf((char*)  s, "SQL_COLUMN_ALIAS" );
2319         break;
2320 
2321       case SQL_CONCAT_NULL_BEHAVIOR:
2322         sprintf((char*)  s, "SQL_CONCAT_NULL_BEHAVIOR" );
2323         break;
2324 
2325       case SQL_CONVERT_BIGINT:
2326         sprintf((char*)  s, "SQL_CONVERT_BIGINT" );
2327         break;
2328 
2329       case SQL_CONVERT_BINARY:
2330         sprintf((char*)  s, "SQL_CONVERT_BINARY" );
2331         break;
2332 
2333       case SQL_CONVERT_BIT:
2334         sprintf((char*)  s, "SQL_CONVERT_BIT" );
2335         break;
2336 
2337       case SQL_CONVERT_CHAR:
2338         sprintf((char*)  s, "SQL_CONVERT_CHAR" );
2339         break;
2340 
2341       case SQL_CONVERT_DATE:
2342         sprintf((char*)  s, "SQL_CONVERT_DATE" );
2343         break;
2344 
2345       case SQL_CONVERT_DECIMAL:
2346         sprintf((char*)  s, "SQL_CONVERT_DECIMAL" );
2347         break;
2348 
2349       case SQL_CONVERT_DOUBLE:
2350         sprintf((char*)  s, "SQL_CONVERT_DOUBLE" );
2351         break;
2352 
2353       case SQL_CONVERT_FLOAT:
2354         sprintf((char*)  s, "SQL_CONVERT_FLOAT" );
2355         break;
2356 
2357       case SQL_CONVERT_INTEGER:
2358         sprintf((char*)  s, "SQL_CONVERT_INTEGER" );
2359         break;
2360 
2361       case SQL_CONVERT_INTERVAL_YEAR_MONTH:
2362         sprintf((char*)  s, "SQL_CONVERT_INTERVAL_YEAR_MONTH" );
2363         break;
2364 
2365       case SQL_CONVERT_INTERVAL_DAY_TIME:
2366         sprintf((char*)  s, "SQL_CONVERT_INTERVAL_DAY_TIME" );
2367         break;
2368 
2369       case SQL_CONVERT_LONGVARBINARY:
2370         sprintf((char*)  s, "SQL_CONVERT_LONGVARBINARY" );
2371         break;
2372 
2373       case SQL_CONVERT_LONGVARCHAR:
2374         sprintf((char*)  s, "SQL_CONVERT_LONGVARCHAR" );
2375         break;
2376 
2377       case SQL_CONVERT_NUMERIC:
2378         sprintf((char*)  s, "SQL_CONVERT_NUMERIC" );
2379         break;
2380 
2381       case SQL_CONVERT_REAL:
2382         sprintf((char*)  s, "SQL_CONVERT_REAL" );
2383         break;
2384 
2385       case SQL_CONVERT_SMALLINT:
2386         sprintf((char*)  s, "SQL_CONVERT_SMALLINT" );
2387         break;
2388 
2389       case SQL_CONVERT_TIME:
2390         sprintf((char*)  s, "SQL_CONVERT_TIME" );
2391         break;
2392 
2393       case SQL_CONVERT_TIMESTAMP:
2394         sprintf((char*)  s, "SQL_CONVERT_TIMESTAMP" );
2395         break;
2396 
2397       case SQL_CONVERT_TINYINT:
2398         sprintf((char*)  s, "SQL_CONVERT_TINYINT" );
2399         break;
2400 
2401       case SQL_CONVERT_VARBINARY:
2402         sprintf((char*)  s, "SQL_CONVERT_VARBINARY" );
2403         break;
2404 
2405       case SQL_CONVERT_VARCHAR:
2406         sprintf((char*)  s, "SQL_CONVERT_VARCHAR" );
2407         break;
2408 
2409       case SQL_CONVERT_FUNCTIONS:
2410         sprintf((char*)  s, "SQL_CONVERT_FUNCTIONS" );
2411         break;
2412 
2413       case SQL_CORRELATION_NAME:
2414         sprintf((char*)  s, "SQL_CORRELATION_NAME" );
2415         break;
2416 
2417       case SQL_CREATE_ASSERTION:
2418         sprintf((char*)  s, "SQL_CREATE_ASSERTION" );
2419         break;
2420 
2421       case SQL_CREATE_CHARACTER_SET:
2422         sprintf((char*)  s, "SQL_CREATE_CHARACTER_SET" );
2423         break;
2424 
2425       case SQL_CREATE_COLLATION:
2426         sprintf((char*)  s, "SQL_CREATE_COLLATION" );
2427         break;
2428 
2429       case SQL_CREATE_DOMAIN:
2430         sprintf((char*)  s, "SQL_CREATE_DOMAIN" );
2431         break;
2432 
2433       case SQL_CREATE_SCHEMA:
2434         sprintf((char*)  s, "SQL_CREATE_SCHEMA" );
2435         break;
2436 
2437       case SQL_CREATE_TABLE:
2438         sprintf((char*)  s, "SQL_CREATE_TABLE" );
2439         break;
2440 
2441       case SQL_CREATE_TRANSLATION:
2442         sprintf((char*)  s, "SQL_CREATE_TRANSLATION" );
2443         break;
2444 
2445       case SQL_CREATE_VIEW:
2446         sprintf((char*)  s, "SQL_CREATE_VIEW" );
2447         break;
2448 
2449       case SQL_CURSOR_COMMIT_BEHAVIOR:
2450         sprintf((char*)  s, "SQL_CURSOR_COMMIT_BEHAVIOR" );
2451         break;
2452 
2453       case SQL_CURSOR_ROLLBACK_BEHAVIOR:
2454         sprintf((char*)  s, "SQL_CURSOR_ROLLBACK_BEHAVIOR" );
2455         break;
2456 
2457       case SQL_CURSOR_SENSITIVITY:
2458         sprintf((char*)  s, "SQL_CURSOR_SENSITIVITY" );
2459         break;
2460 
2461       case SQL_DATA_SOURCE_NAME:
2462         sprintf((char*)  s, "SQL_DATA_SOURCE_NAME" );
2463         break;
2464 
2465       case SQL_DATA_SOURCE_READ_ONLY:
2466         sprintf((char*)  s, "SQL_DATA_SOURCE_READ_ONLY" );
2467         break;
2468 
2469       case SQL_DATABASE_NAME:
2470         sprintf((char*)  s, "SQL_DATABASE_NAME" );
2471         break;
2472 
2473       case SQL_DATETIME_LITERALS:
2474         sprintf((char*)  s, "SQL_DATETIME_LITERALS" );
2475         break;
2476 
2477       case SQL_DBMS_NAME:
2478         sprintf((char*)  s, "SQL_DBMS_NAME" );
2479         break;
2480 
2481       case SQL_DBMS_VER:
2482         sprintf((char*)  s, "SQL_DBMS_VER" );
2483         break;
2484 
2485       case SQL_DDL_INDEX:
2486         sprintf((char*)  s, "SQL_DDL_INDEX" );
2487         break;
2488 
2489       case SQL_DEFAULT_TXN_ISOLATION:
2490         sprintf((char*)  s, "SQL_DEFAULT_TXN_ISOLATION" );
2491         break;
2492 
2493       case SQL_DESCRIBE_PARAMETER:
2494         sprintf((char*)  s, "SQL_DESCRIBE_PARAMETER" );
2495         break;
2496 
2497       case SQL_DRIVER_NAME:
2498         sprintf((char*)  s, "SQL_DRIVER_NAME" );
2499         break;
2500 
2501       case SQL_DRIVER_HLIB:
2502         sprintf((char*)  s, "SQL_DRIVER_HLIB" );
2503         break;
2504 
2505       case SQL_DRIVER_HSTMT:
2506         sprintf((char*)  s, "SQL_DRIVER_HSTMT" );
2507         break;
2508 
2509       case SQL_DRIVER_ODBC_VER:
2510         sprintf((char*)  s, "SQL_DRIVER_ODBC_VER" );
2511         break;
2512 
2513       case SQL_DRIVER_VER:
2514         sprintf((char*)  s, "SQL_DRIVER_VER" );
2515         break;
2516 
2517       case SQL_ODBC_VER:
2518         sprintf((char*)  s, "SQL_ODBC_VER" );
2519         break;
2520 
2521       case SQL_DROP_ASSERTION:
2522         sprintf((char*)  s, "SQL_DROP_ASSERTION" );
2523         break;
2524 
2525       case SQL_DROP_CHARACTER_SET:
2526         sprintf((char*)  s, "SQL_DROP_CHARACTER_SET" );
2527         break;
2528 
2529       case SQL_DROP_COLLATION:
2530         sprintf((char*)  s, "SQL_DROP_COLLATION" );
2531         break;
2532 
2533       case SQL_DROP_DOMAIN:
2534         sprintf((char*)  s, "SQL_DROP_DOMAIN" );
2535         break;
2536 
2537       case SQL_DROP_SCHEMA:
2538         sprintf((char*)  s, "SQL_DROP_SCHEMA" );
2539         break;
2540 
2541       case SQL_DROP_TABLE:
2542         sprintf((char*)  s, "SQL_DROP_TABLE" );
2543         break;
2544 
2545       case SQL_DROP_TRANSLATION:
2546         sprintf((char*)  s, "SQL_DROP_TRANSLATION" );
2547         break;
2548 
2549       case SQL_DROP_VIEW:
2550         sprintf((char*)  s, "SQL_DROP_VIEW" );
2551         break;
2552 
2553       case SQL_DYNAMIC_CURSOR_ATTRIBUTES1:
2554         sprintf((char*)  s, "SQL_DYNAMIC_CURSOR_ATTRIBUTES1" );
2555         break;
2556 
2557       case SQL_DYNAMIC_CURSOR_ATTRIBUTES2:
2558         sprintf((char*)  s, "SQL_EXPRESSIONS_IN_ORDERBY" );
2559         break;
2560 
2561       case SQL_EXPRESSIONS_IN_ORDERBY:
2562         sprintf((char*)  s, "SQL_EXPRESSIONS_IN_ORDERBY" );
2563         break;
2564 
2565       case SQL_FILE_USAGE:
2566         sprintf((char*)  s, "SQL_FILE_USAGE" );
2567         break;
2568 
2569       case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1:
2570         sprintf((char*)  s, "SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES1" );
2571         break;
2572 
2573       case SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2:
2574         sprintf((char*)  s, "SQL_FORWARD_ONLY_CURSOR_ATTRIBUTES2" );
2575         break;
2576 
2577       case SQL_GETDATA_EXTENSIONS:
2578         sprintf((char*)  s, "SQL_GETDATA_EXTENSIONS" );
2579         break;
2580 
2581       case SQL_GROUP_BY:
2582         sprintf((char*)  s, "SQL_GROUP_BY" );
2583         break;
2584 
2585       case SQL_IDENTIFIER_CASE:
2586         sprintf((char*)  s, "SQL_IDENTIFIER_CASE" );
2587         break;
2588 
2589       case SQL_IDENTIFIER_QUOTE_CHAR:
2590         sprintf((char*)  s, "SQL_IDENTIFIER_QUOTE_CHAR" );
2591         break;
2592 
2593       case SQL_INDEX_KEYWORDS:
2594         sprintf((char*)  s, "SQL_INDEX_KEYWORDS" );
2595         break;
2596 
2597       case SQL_INFO_SCHEMA_VIEWS:
2598         sprintf((char*)  s, "SQL_INFO_SCHEMA_VIEWS" );
2599         break;
2600 
2601       case SQL_INSERT_STATEMENT:
2602         sprintf((char*)  s, "SQL_INSERT_STATEMENT" );
2603         break;
2604 
2605       case SQL_INTEGRITY:
2606         sprintf((char*)  s, "SQL_INTEGRITY" );
2607         break;
2608 
2609       case SQL_KEYSET_CURSOR_ATTRIBUTES1:
2610         sprintf((char*)  s, "SQL_KEYSET_CURSOR_ATTRIBUTES1" );
2611         break;
2612 
2613       case SQL_KEYSET_CURSOR_ATTRIBUTES2:
2614         sprintf((char*)  s, "SQL_KEYSET_CURSOR_ATTRIBUTES2" );
2615         break;
2616 
2617       case SQL_KEYWORDS:
2618         sprintf((char*)  s, "SQL_KEYWORDS" );
2619         break;
2620 
2621       case SQL_LIKE_ESCAPE_CLAUSE:
2622         sprintf((char*)  s, "SQL_LIKE_ESCAPE_CLAUSE" );
2623         break;
2624 
2625       case SQL_MAX_ASYNC_CONCURRENT_STATEMENTS:
2626         sprintf((char*)  s, "SQL_MAX_ASYNC_CONCURRENT_STATEMENTS" );
2627         break;
2628 
2629       case SQL_MAX_BINARY_LITERAL_LEN:
2630         sprintf((char*)  s, "SQL_MAX_BINARY_LITERAL_LEN" );
2631         break;
2632 
2633       case SQL_MAX_CATALOG_NAME_LEN:
2634         sprintf((char*)  s, "SQL_MAX_CATALOG_NAME_LEN" );
2635         break;
2636 
2637       case SQL_MAX_CHAR_LITERAL_LEN:
2638         sprintf((char*)  s, "SQL_MAX_CHAR_LITERAL_LEN" );
2639         break;
2640 
2641       case SQL_MAX_COLUMN_NAME_LEN:
2642         sprintf((char*)  s, "SQL_MAX_COLUMN_NAME_LEN" );
2643         break;
2644 
2645       case SQL_MAX_COLUMNS_IN_GROUP_BY:
2646         sprintf((char*)  s, "SQL_MAX_COLUMNS_IN_GROUP_BY" );
2647         break;
2648 
2649       case SQL_MAX_COLUMNS_IN_INDEX:
2650         sprintf((char*)  s, "SQL_MAX_COLUMNS_IN_INDEX" );
2651         break;
2652 
2653       case SQL_MAX_COLUMNS_IN_SELECT:
2654         sprintf((char*)  s, "SQL_MAX_COLUMNS_IN_SELECT" );
2655         break;
2656 
2657       case SQL_MAX_COLUMNS_IN_ORDER_BY:
2658         sprintf((char*)  s, "SQL_MAX_COLUMNS_IN_ORDER_BY" );
2659         break;
2660 
2661       case SQL_MAX_COLUMNS_IN_TABLE:
2662         sprintf((char*)  s, "SQL_MAX_COLUMNS_IN_TABLE" );
2663         break;
2664 
2665       case SQL_MAX_CONCURRENT_ACTIVITIES:
2666         sprintf((char*)  s, "SQL_MAX_CONCURRENT_ACTIVITIES" );
2667         break;
2668 
2669       case SQL_MAX_CURSOR_NAME_LEN:
2670         sprintf((char*)  s, "SQL_MAX_CURSOR_NAME_LEN" );
2671         break;
2672 
2673       case SQL_MAX_DRIVER_CONNECTIONS:
2674         sprintf((char*)  s, "SQL_MAX_DRIVER_CONNECTIONS" );
2675         break;
2676 
2677       case SQL_MAX_IDENTIFIER_LEN:
2678         sprintf((char*)  s, "SQL_MAX_IDENTIFIER_LEN" );
2679         break;
2680 
2681       case SQL_MAX_INDEX_SIZE:
2682         sprintf((char*)  s, "SQL_MAX_INDEX_SIZE" );
2683         break;
2684 
2685       case SQL_MAX_PROCEDURE_NAME_LEN:
2686         sprintf((char*)  s, "SQL_MAX_PROCEDURE_NAME_LEN" );
2687         break;
2688 
2689       case SQL_MAX_ROW_SIZE:
2690         sprintf((char*)  s, "SQL_MAX_ROW_SIZE" );
2691         break;
2692 
2693       case SQL_MAX_ROW_SIZE_INCLUDES_LONG:
2694         sprintf((char*)  s, "SQL_MAX_ROW_SIZE_INCLUDES_LONG" );
2695         break;
2696 
2697       case SQL_MAX_SCHEMA_NAME_LEN:
2698         sprintf((char*)  s, "SQL_MAX_SCHEMA_NAME_LEN" );
2699         break;
2700 
2701       case SQL_MAX_STATEMENT_LEN:
2702         sprintf((char*)  s, "SQL_MAX_STATEMENT_LEN" );
2703         break;
2704 
2705       case SQL_MAX_TABLE_NAME_LEN:
2706         sprintf((char*)  s, "SQL_MAX_TABLE_NAME_LEN" );
2707         break;
2708 
2709       case SQL_MAX_TABLES_IN_SELECT:
2710         sprintf((char*)  s, "SQL_MAX_TABLES_IN_SELECT" );
2711         break;
2712 
2713       case SQL_MAX_USER_NAME_LEN:
2714         sprintf((char*)  s, "SQL_MAX_USER_NAME_LEN" );
2715         break;
2716 
2717       case SQL_MULT_RESULT_SETS:
2718         sprintf((char*)  s, "SQL_MULT_RESULT_SETS" );
2719         break;
2720 
2721       case SQL_MULTIPLE_ACTIVE_TXN:
2722         sprintf((char*)  s, "SQL_MULTIPLE_ACTIVE_TXN" );
2723         break;
2724 
2725       case SQL_NEED_LONG_DATA_LEN:
2726         sprintf((char*)  s, "SQL_NEED_LONG_DATA_LEN" );
2727         break;
2728 
2729       case SQL_NON_NULLABLE_COLUMNS:
2730         sprintf((char*)  s, "SQL_NON_NULLABLE_COLUMNS" );
2731         break;
2732 
2733       case SQL_NULL_COLLATION:
2734         sprintf((char*)  s, "SQL_NULL_COLLATION" );
2735         break;
2736 
2737       case SQL_NUMERIC_FUNCTIONS:
2738         sprintf((char*)  s, "SQL_NUMERIC_FUNCTIONS" );
2739         break;
2740 
2741       case SQL_ODBC_INTERFACE_CONFORMANCE:
2742         sprintf((char*)  s, "SQL_ODBC_INTERFACE_CONFORMANCE" );
2743         break;
2744 
2745       case SQL_OJ_CAPABILITIES:
2746         sprintf((char*)  s, "SQL_OJ_CAPABILITIES" );
2747         break;
2748 
2749       case SQL_ORDER_BY_COLUMNS_IN_SELECT:
2750         sprintf((char*)  s, "SQL_ORDER_BY_COLUMNS_IN_SELECT" );
2751         break;
2752 
2753       case SQL_PARAM_ARRAY_ROW_COUNTS:
2754         sprintf((char*)  s, "SQL_PARAM_ARRAY_ROW_COUNTS" );
2755         break;
2756 
2757       case SQL_PARAM_ARRAY_SELECTS:
2758         sprintf((char*)  s, "SQL_PARAM_ARRAY_SELECTS" );
2759         break;
2760 
2761       case SQL_PROCEDURE_TERM:
2762         sprintf((char*)  s, "SQL_PROCEDURE_TERM" );
2763         break;
2764 
2765       case SQL_PROCEDURES:
2766         sprintf((char*)  s, "SQL_PROCEDURES" );
2767         break;
2768 
2769       case SQL_QUOTED_IDENTIFIER_CASE:
2770         sprintf((char*)  s, "SQL_QUOTED_IDENTIFIER_CASE" );
2771         break;
2772 
2773       case SQL_ROW_UPDATES:
2774         sprintf((char*)  s, "SQL_ROW_UPDATES" );
2775         break;
2776 
2777       case SQL_SCHEMA_TERM:
2778         sprintf((char*)  s, "SQL_SCHEMA_TERM" );
2779         break;
2780 
2781       case SQL_SCHEMA_USAGE:
2782         sprintf((char*)  s, "SQL_SCHEMA_USAGE" );
2783         break;
2784 
2785       case SQL_SCROLL_OPTIONS:
2786         sprintf((char*)  s, "SQL_SCROLL_OPTIONS" );
2787         break;
2788 
2789       case SQL_SEARCH_PATTERN_ESCAPE:
2790         sprintf((char*)  s, "SQL_SEARCH_PATTERN_ESCAPE" );
2791         break;
2792 
2793       case SQL_SERVER_NAME:
2794         sprintf((char*)  s, "SQL_SERVER_NAME" );
2795         break;
2796 
2797       case SQL_SPECIAL_CHARACTERS:
2798         sprintf((char*)  s, "SQL_SPECIAL_CHARACTERS" );
2799         break;
2800 
2801       case SQL_SQL_CONFORMANCE:
2802         sprintf((char*)  s, "SQL_SQL_CONFORMANCE" );
2803         break;
2804 
2805       case SQL_SQL92_DATETIME_FUNCTIONS:
2806         sprintf((char*)  s, "SQL_SQL92_DATETIME_FUNCTIONS" );
2807         break;
2808 
2809       case SQL_SQL92_FOREIGN_KEY_DELETE_RULE:
2810         sprintf((char*)  s, "SQL_SQL92_FOREIGN_KEY_DELETE_RULE" );
2811         break;
2812 
2813       case SQL_SQL92_FOREIGN_KEY_UPDATE_RULE:
2814         sprintf((char*)  s, "SQL_SQL92_FOREIGN_KEY_UPDATE_RULE" );
2815         break;
2816 
2817       case SQL_SQL92_GRANT:
2818         sprintf((char*)  s, "SQL_SQL92_GRANT" );
2819         break;
2820 
2821       case SQL_SQL92_NUMERIC_VALUE_FUNCTIONS:
2822         sprintf((char*)  s, "SQL_SQL92_NUMERIC_VALUE_FUNCTIONS" );
2823         break;
2824 
2825       case SQL_SQL92_PREDICATES:
2826         sprintf((char*)  s, "SQL_SQL92_PREDICATES" );
2827         break;
2828 
2829       case SQL_SQL92_RELATIONAL_JOIN_OPERATORS:
2830         sprintf((char*)  s, "SQL_SQL92_RELATIONAL_JOIN_OPERATORS" );
2831         break;
2832 
2833       case SQL_SQL92_REVOKE:
2834         sprintf((char*)  s, "SQL_SQL92_REVOKE" );
2835         break;
2836 
2837       case SQL_SQL92_ROW_VALUE_CONSTRUCTOR:
2838         sprintf((char*)  s, "SQL_SQL92_ROW_VALUE_CONSTRUCTOR" );
2839         break;
2840 
2841       case SQL_SQL92_STRING_FUNCTIONS:
2842         sprintf((char*)  s, "SQL_SQL92_STRING_EXPRESSIONS" );
2843         break;
2844 
2845       case SQL_SQL92_VALUE_EXPRESSIONS:
2846         sprintf((char*)  s, "SQL_SQL92_VALUE_EXPRESSIONS" );
2847         break;
2848 
2849       case SQL_STANDARD_CLI_CONFORMANCE:
2850         sprintf((char*)  s, "SQL_STANDARD_CLI_CONFORMANCE" );
2851         break;
2852 
2853       case SQL_STATIC_CURSOR_ATTRIBUTES1:
2854         sprintf((char*)  s, "SQL_STATIC_CURSOR_ATTRIBUTES1" );
2855         break;
2856 
2857       case SQL_STATIC_CURSOR_ATTRIBUTES2:
2858         sprintf((char*)  s, "SQL_STATIC_CURSOR_ATTRIBUTES2" );
2859         break;
2860 
2861       case SQL_STRING_FUNCTIONS:
2862         sprintf((char*)  s, "SQL_STRING_FUNCTIONS" );
2863         break;
2864 
2865       case SQL_SUBQUERIES:
2866         sprintf((char*)  s, "SQL_SUBQUERIES" );
2867         break;
2868 
2869       case SQL_SYSTEM_FUNCTIONS:
2870         sprintf((char*)  s, "SQL_SYSTEM_FUNCTIONS" );
2871         break;
2872 
2873       case SQL_TABLE_TERM:
2874         sprintf((char*)  s, "SQL_TABLE_TERM" );
2875         break;
2876 
2877       case SQL_TIMEDATE_ADD_INTERVALS:
2878         sprintf((char*)  s, "SQL_TIMEDATE_ADD_INTERVALS" );
2879         break;
2880 
2881       case SQL_TIMEDATE_DIFF_INTERVALS:
2882         sprintf((char*)  s, "SQL_TIMEDATE_DIFF_INTERVALS" );
2883         break;
2884 
2885       case SQL_TIMEDATE_FUNCTIONS:
2886         sprintf((char*)  s, "SQL_TIMEDATE_FUNCTIONS" );
2887         break;
2888 
2889       case SQL_TXN_CAPABLE:
2890         sprintf((char*)  s, "SQL_TXN_CAPABLE" );
2891         break;
2892 
2893       case SQL_TXN_ISOLATION_OPTION:
2894         sprintf((char*)  s, "SQL_TXN_ISOLATION_OPTION" );
2895         break;
2896 
2897       case SQL_UNION:
2898         sprintf((char*)  s, "SQL_UNION" );
2899         break;
2900 
2901       case SQL_USER_NAME:
2902         sprintf((char*)  s, "SQL_USER_NAME" );
2903         break;
2904 
2905       case SQL_XOPEN_CLI_YEAR:
2906         sprintf((char*)  s, "SQL_XOPEN_CLI_YEAR" );
2907         break;
2908 
2909       case SQL_FETCH_DIRECTION:
2910         sprintf((char*)  s, "SQL_FETCH_DIRECTION" );
2911         break;
2912 
2913       case SQL_LOCK_TYPES:
2914         sprintf((char*)  s, "SQL_LOCK_TYPES" );
2915         break;
2916 
2917       case SQL_ODBC_API_CONFORMANCE:
2918         sprintf((char*)  s, "SQL_ODBC_API_CONFORMANCE" );
2919         break;
2920 
2921       case SQL_ODBC_SQL_CONFORMANCE:
2922         sprintf((char*)  s, "SQL_ODBC_SQL_CONFORMANCE" );
2923         break;
2924 
2925       case SQL_POS_OPERATIONS:
2926         sprintf((char*)  s, "SQL_POS_OPERATIONS" );
2927         break;
2928 
2929       case SQL_POSITIONED_STATEMENTS:
2930         sprintf((char*)  s, "SQL_POSITIONED_STATEMENTS" );
2931         break;
2932 
2933       case SQL_SCROLL_CONCURRENCY:
2934         sprintf((char*)  s, "SQL_SCROLL_CONCURRENCY" );
2935         break;
2936 
2937       case SQL_STATIC_SENSITIVITY:
2938         sprintf((char*)  s, "SQL_STATIC_SENSITIVITY" );
2939         break;
2940 
2941       case SQL_OUTER_JOINS:
2942         sprintf((char*)  s, "SQL_OUTER_JOINS" );
2943         break;
2944 
2945       case SQL_DRIVER_AWARE_POOLING_SUPPORTED:
2946         sprintf((char*)  s, "SQL_DRIVER_AWARE_POOLING_SUPPORTED" );
2947         break;
2948 
2949       default:
2950         sprintf((char*)  s, "%d", (int)type );
2951     }
2952 
2953     return (char*) s;
2954 }
2955 
2956 /*
2957  * convert from type 3 error states to type 2
2958  */
2959 
2960 struct state_map
2961 {
2962     char ver2[6];
2963     char ver3[6];
2964 };
2965 
2966 static const struct state_map state_mapping_3_2[] = {
2967     { "01S03", "01001" },
2968     { "01S04", "01001" },
2969     { "22003", "HY019" },
2970     { "22005", "22018" },
2971     { "22008", "22007" },
2972     { "24000", "07005" },
2973     { "37000", "42000" },
2974     { "70100", "HY018" },
2975     { "S0001", "42S01" },
2976     { "S0002", "42S02" },
2977     { "S0011", "42S11" },
2978     { "S0012", "42S12" },
2979     { "S0021", "42S21" },
2980     { "S0022", "42S22" },
2981     { "S0023", "42S23" },
2982     { "S1000", "HY000" },
2983     { "S1001", "HY001" },
2984     { "S1002", "07009" },
2985     { "S1003", "HY003" },
2986     { "S1004", "HY004" },
2987     { "S1007", "HY007" },
2988     { "S1008", "HY008" },
2989     { "S1009", "HY009" },
2990     { "S1010", "HY010" },
2991     { "S1011", "HY011" },
2992     { "S1012", "HY012" },
2993     { "S1090", "HY090" },
2994     { "S1091", "HY091" },
2995     { "S1092", "HY092" },
2996     { "S1093", "07009" },
2997     { "S1096", "HY096" },
2998     { "S1097", "HY097" },
2999     { "S1098", "HY098" },
3000     { "S1099", "HY099" },
3001     { "S1100", "HY100" },
3002     { "S1101", "HY101" },
3003     { "S1103", "HY103" },
3004     { "S1104", "HY104" },
3005     { "S1105", "HY105" },
3006     { "S1106", "HY106" },
3007     { "S1107", "HY107" },
3008     { "S1108", "HY108" },
3009     { "S1109", "HY109" },
3010     { "S1110", "HY110" },
3011     { "S1111", "HY111" },
3012     { "S1C00", "HYC00" },
3013     { "S1T00", "HYT00" },
3014     { "", "" }
3015 };
3016 
3017 /*
3018  * the book doesn't say that it should map ODBC 2 states to ODBC 3
3019  * but the MS Windows DM can be seen to do just that
3020  */
3021 
3022 static const struct state_map state_mapping_2_3[] = {
3023     { "01S03", "01001" },
3024     { "01S04", "01001" },
3025     { "22005", "22018" },
3026     { "37000", "42000" },
3027     { "70100", "HY018" },
3028     { "S0001", "42S01" },
3029     { "S0002", "42S02" },
3030     { "S0011", "42S11" },
3031     { "S0012", "42S12" },
3032     { "S0021", "42S21" },
3033     { "S0022", "42S22" },
3034     { "S0023", "42S23" },
3035     { "S1000", "HY000" },
3036     { "S1001", "HY001" },
3037     { "S1002", "07009" },
3038     { "S1003", "HY003" },
3039     { "S1004", "HY004" },
3040     { "S1007", "HY007" },
3041     { "S1008", "HY008" },
3042     { "S1009", "HY009" },
3043     { "S1010", "HY010" },
3044     { "S1011", "HY011" },
3045     { "S1012", "HY012" },
3046     { "S1090", "HY090" },
3047     { "S1091", "HY091" },
3048     { "S1092", "HY092" },
3049     { "S1093", "07009" },
3050     { "S1096", "HY096" },
3051     { "S1097", "HY097" },
3052     { "S1098", "HY098" },
3053     { "S1099", "HY099" },
3054     { "S1100", "HY100" },
3055     { "S1101", "HY101" },
3056     { "S1103", "HY103" },
3057     { "S1104", "HY104" },
3058     { "S1105", "HY105" },
3059     { "S1106", "HY106" },
3060     { "S1107", "HY107" },
3061     { "S1108", "HY108" },
3062     { "S1109", "HY109" },
3063     { "S1110", "HY110" },
3064     { "S1111", "HY111" },
3065     { "S1C00", "HYC00" },
3066     { "S1T00", "HYT00" },
3067     { "", "" }
3068 };
3069 
3070 /*
3071  * map ODBC3 states to/from ODBC 2
3072  */
3073 
__map_error_state(char * state,int requested_version)3074 void __map_error_state( char * state, int requested_version )
3075 {
3076     const struct state_map *ptr;
3077 
3078     if ( !state )
3079         return;
3080 
3081 
3082     if ( requested_version == SQL_OV_ODBC2 )
3083     {
3084         ptr = state_mapping_3_2;
3085 
3086         while( ptr -> ver3[0] )
3087         {
3088             if ( strcmp( ptr -> ver3, state ) == 0 )
3089             {
3090                 strcpy( state, ptr -> ver2 );
3091                 return;
3092             }
3093             ptr ++;
3094         }
3095     }
3096     else if ( requested_version >= SQL_OV_ODBC3 )
3097     {
3098         ptr = state_mapping_2_3;
3099 
3100         while( ptr -> ver2[0] )
3101         {
3102             if ( strcmp( ptr -> ver2, state ) == 0 )
3103             {
3104                 strcpy( state, ptr -> ver3 );
3105                 return;
3106             }
3107             ptr ++;
3108         }
3109     }
3110 }
3111 
__map_error_state_w(SQLWCHAR * wstate,int requested_version)3112 void __map_error_state_w( SQLWCHAR * wstate, int requested_version )
3113 {
3114     char state[ 6 ];
3115 
3116     unicode_to_ansi_copy( state, 6, wstate, SQL_NTS, NULL, NULL );
3117 
3118     __map_error_state( state, requested_version );
3119 
3120     ansi_to_unicode_copy( wstate, state, SQL_NTS, NULL, NULL );
3121 }
3122 
3123 /*
3124  * return the process id as a string
3125  */
3126 
__get_pid(SQLCHAR * str)3127 char * __get_pid( SQLCHAR * str )
3128 {
3129     sprintf((char *) str, "%d", getpid());
3130 
3131     return (char*)str;
3132 }
3133 
3134 /*
3135  * take a SQL string and its length indicator and format it for
3136  * display
3137  */
3138 
__string_with_length(SQLCHAR * ostr,SQLCHAR * instr,SQLINTEGER len)3139 char * __string_with_length( SQLCHAR *ostr, SQLCHAR *instr, SQLINTEGER len )
3140 {
3141     if ( instr == NULL )
3142     {
3143         sprintf((char*) ostr, "[NULL]" );
3144     }
3145     else if ( len == SQL_NTS )
3146     {
3147         if ( strlen((char*) instr ) > LOG_MESSAGE_LEN )
3148         {
3149             sprintf((char*) ostr, "[%.*s...][length = %ld (SQL_NTS)]",
3150                 LOG_MESSAGE_LEN, instr, (long int)strlen((char*) instr ));
3151         }
3152         else
3153         {
3154             sprintf((char*) ostr, "[%s][length = %ld (SQL_NTS)]",
3155                 instr, (long int)strlen((char*) instr ));
3156         }
3157 
3158     }
3159     else
3160     {
3161         if ( len < LOG_MESSAGE_LEN )
3162             sprintf((char*) ostr, "[%.*s][length = %d]", (int)len, instr, (int)len );
3163         else
3164             sprintf((char*) ostr, "[%.*s...][length = %d]", LOG_MESSAGE_LEN, instr, (int)len );
3165     }
3166 
3167     return (char*)ostr;
3168 }
3169 
__wstring_with_length(SQLCHAR * ostr,SQLWCHAR * instr,SQLINTEGER len)3170 char * __wstring_with_length( SQLCHAR *ostr, SQLWCHAR *instr, SQLINTEGER len )
3171 {
3172     int i = 0;
3173     char tmp[ LOG_MESSAGE_LEN ];
3174 
3175     if ( instr == NULL )
3176     {
3177         sprintf((char*) ostr, "[NULL]" );
3178     }
3179     else if ( len == SQL_NTS )
3180     {
3181         if ( ( i = wide_strlen( instr ) ) < LOG_MESSAGE_LEN )
3182         {
3183             strcpy((char*) ostr, "[" );
3184             unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, i, NULL, NULL );
3185             strcat((char*) ostr, "]" );
3186         }
3187         else
3188         {
3189             strcpy((char*) ostr, "[" );
3190             unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, LOG_MESSAGE_LEN, NULL, NULL );
3191             strcat((char*) ostr, "...]" );
3192         }
3193         sprintf( tmp, "[length = %d (SQL_NTS)]", i );
3194         strcat((char*) ostr, tmp );
3195     }
3196     else
3197     {
3198         if ( len < LOG_MESSAGE_LEN )
3199         {
3200             strcpy((char*) ostr, "[" );
3201             unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, len, NULL, NULL );
3202             strcat((char*) ostr, "]" );
3203         }
3204         else
3205         {
3206             strcpy((char*) ostr, "[" );
3207             unicode_to_ansi_copy((char*) ostr + 1, LOG_MESSAGE_LEN, instr, LOG_MESSAGE_LEN, NULL, NULL );
3208             strcat((char*) ostr, "...]" );
3209         }
3210         sprintf( tmp, "[length = %d]", (int)len );
3211         strcat((char*) ostr, tmp );
3212     }
3213 
3214     return (char*)ostr;
3215 }
3216 
3217 /*
3218  * replace password with ****
3219  */
3220 
__string_with_length_pass(SQLCHAR * out,SQLCHAR * str,SQLINTEGER len)3221 char * __string_with_length_pass( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len )
3222 {
3223     char *p = __string_with_length( out, str, len );
3224 
3225     /*
3226      * the string will be of the form [text]
3227      */
3228 
3229     if ( str )
3230     {
3231         char * ptr = p + 1;
3232 
3233         while ( *ptr && *ptr != ']' )
3234         {
3235             *ptr = '*';
3236             ptr ++;
3237         }
3238     }
3239 
3240     return p;
3241 }
3242 
__wstring_with_length_pass(SQLCHAR * out,SQLWCHAR * str,SQLINTEGER len)3243 char * __wstring_with_length_pass( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len )
3244 {
3245     char *p = __wstring_with_length( out, str, len );
3246 
3247     /*
3248      * the string will be of the form [text]
3249      */
3250 
3251     if ( str )
3252     {
3253         char * ptr = p + 1;
3254 
3255         while ( *ptr && *ptr != ']' )
3256         {
3257             *ptr = '*';
3258             ptr ++;
3259         }
3260     }
3261 
3262     return p;
3263 }
3264 
3265 /*
3266  * mask out PWD=str;
3267  * wont work on lower case pwd but there you go
3268  */
3269 
__string_with_length_hide_pwd(SQLCHAR * out,SQLCHAR * str,SQLINTEGER len)3270 char * __string_with_length_hide_pwd( SQLCHAR *out, SQLCHAR *str, SQLINTEGER len )
3271 {
3272     char *p = __string_with_length( out, str, len );
3273 
3274     if ( str )
3275     {
3276         char *ptr;
3277 
3278         ptr = strstr( p, "PWD=" );
3279         while ( ptr )
3280         {
3281             ptr += 4;
3282             while ( *ptr && *ptr != ';' && *ptr != ']' )
3283             {
3284                 *ptr = '*';
3285                 ptr ++;
3286             }
3287             ptr = strstr( ptr, "PWD=" );
3288         }
3289     }
3290 
3291     return p;
3292 }
3293 
__wstring_with_length_hide_pwd(SQLCHAR * out,SQLWCHAR * str,SQLINTEGER len)3294 char * __wstring_with_length_hide_pwd( SQLCHAR *out, SQLWCHAR *str, SQLINTEGER len )
3295 {
3296     char *p = __wstring_with_length( out, str, len );
3297 
3298     return p;
3299 }
3300 
3301 /*
3302  * display a C type as a string
3303  */
3304 
__c_as_text(SQLINTEGER type)3305 char * __c_as_text( SQLINTEGER type )
3306 {
3307     switch( type )
3308     {
3309       case SQL_C_CHAR:
3310         return "SQL_C_CHAR";
3311 
3312       case SQL_C_LONG:
3313         return "SQL_C_LONG";
3314 
3315       case SQL_C_SHORT:
3316         return "SQL_C_SHORT";
3317 
3318       case SQL_C_FLOAT:
3319         return "SQL_C_FLOAT";
3320 
3321       case SQL_C_DOUBLE:
3322         return "SQL_C_DOUBLE";
3323 
3324       case SQL_C_NUMERIC:
3325         return "SQL_C_NUMERIC";
3326 
3327       case SQL_C_DEFAULT:
3328         return "SQL_C_DEFAULT";
3329 
3330       case SQL_C_DATE:
3331         return "SQL_C_DATE";
3332 
3333       case SQL_C_TIME:
3334         return "SQL_C_TIME";
3335 
3336       case SQL_C_TIMESTAMP:
3337         return "SQL_C_TIMESTAMP";
3338 
3339       case SQL_C_TYPE_DATE:
3340         return "SQL_C_TYPE_DATE";
3341 
3342       case SQL_C_TYPE_TIME:
3343         return "SQL_C_TYPE_TIME";
3344 
3345       case SQL_C_TYPE_TIMESTAMP:
3346         return "SQL_C_TYPE_TIMESTAMP ";
3347 
3348       case SQL_C_INTERVAL_YEAR:
3349         return "SQL_C_INTERVAL_YEAR ";
3350 
3351       case SQL_C_INTERVAL_MONTH:
3352         return "SQL_C_INTERVAL_MONTH";
3353 
3354       case SQL_C_INTERVAL_DAY:
3355         return "SQL_C_INTERVAL_DAY ";
3356 
3357       case SQL_C_INTERVAL_HOUR:
3358         return "SQL_C_INTERVAL_HOUR";
3359 
3360       case SQL_C_INTERVAL_MINUTE:
3361         return "SQL_C_INTERVAL_MINUTE";
3362 
3363       case SQL_C_INTERVAL_SECOND:
3364         return "SQL_C_INTERVAL_SECOND";
3365 
3366       case SQL_C_INTERVAL_YEAR_TO_MONTH:
3367         return "SQL_C_INTERVAL_YEAR_TO_MONTH";
3368 
3369       case SQL_C_INTERVAL_DAY_TO_HOUR:
3370         return "SQL_C_INTERVAL_DAY_TO_HOUR ";
3371 
3372       case SQL_C_INTERVAL_DAY_TO_MINUTE:
3373         return "SQL_C_INTERVAL_DAY_TO_MINUTE";
3374 
3375       case SQL_C_INTERVAL_DAY_TO_SECOND:
3376         return "SQL_C_INTERVAL_DAY_TO_SECOND";
3377 
3378       case SQL_C_INTERVAL_HOUR_TO_MINUTE:
3379         return "SQL_C_INTERVAL_HOUR_TO_MINUTE";
3380 
3381       case SQL_C_INTERVAL_HOUR_TO_SECOND:
3382         return "SQL_C_INTERVAL_HOUR_TO_SECOND";
3383 
3384       case SQL_C_INTERVAL_MINUTE_TO_SECOND:
3385         return "SQL_C_INTERVAL_MINUTE_TO_SECOND";
3386 
3387       case SQL_C_BINARY:
3388         return "SQL_C_BINARY";
3389 
3390       case SQL_C_BIT:
3391         return "SQL_C_BIT";
3392 
3393       case SQL_C_SBIGINT:
3394         return "SQL_C_SBIGINT";
3395 
3396       case SQL_C_UBIGINT:
3397         return "SQL_C_UBIGINT";
3398 
3399       case SQL_C_TINYINT:
3400         return "SQL_C_TINYINT";
3401 
3402       case SQL_C_SLONG:
3403         return "SQL_C_SLONG";
3404 
3405       case SQL_C_SSHORT:
3406         return "SQL_C_SSHORT";
3407 
3408       case SQL_C_STINYINT:
3409         return "SQL_C_STINYINT";
3410 
3411       case SQL_C_ULONG:
3412         return "SQL_C_ULONG";
3413 
3414       case SQL_C_USHORT:
3415         return "SQL_C_USHORT";
3416 
3417       case SQL_C_UTINYINT:
3418         return "SQL_C_UTINYINT";
3419 
3420       case SQL_C_GUID:
3421         return "SQL_C_GUID";
3422 
3423       case SQL_C_WCHAR:
3424         return "SQL_C_WCHAR";
3425 
3426       default:
3427         return "";
3428     }
3429 }
3430 
3431 /*
3432  * display a SQL type as a string
3433  */
3434 
__sql_as_text(SQLINTEGER type)3435 char * __sql_as_text( SQLINTEGER type )
3436 {
3437     switch( type )
3438     {
3439       case SQL_DECIMAL:
3440         return "SQL_DECIMAL";
3441 
3442       case SQL_VARCHAR:
3443         return "SQL_VARCHAR";
3444 
3445       case SQL_LONGVARCHAR:
3446         return "SQL_LONGVARCHAR";
3447 
3448       case SQL_LONGVARBINARY:
3449         return "SQL_LONGVARBINARY";
3450 
3451       case SQL_C_BINARY:
3452         return "SQL_C_BINARY";
3453 
3454       case SQL_VARBINARY:
3455         return "SQL_VARBINARY";
3456 
3457       case SQL_CHAR:
3458         return "SQL_CHAR";
3459 
3460       case SQL_WCHAR:
3461         return "SQL_WCHAR";
3462 
3463       case SQL_WVARCHAR:
3464         return "SQL_WVARCHAR";
3465 
3466       case SQL_INTEGER:
3467         return "SQL_INTEGER";
3468 
3469       case SQL_C_ULONG:
3470         return "SQL_C_ULONG";
3471 
3472       case SQL_C_SLONG:
3473         return "SQL_C_SLONG";
3474 
3475       case SQL_BIGINT:
3476         return "SQL_BIGINT";
3477 
3478       case SQL_C_UBIGINT:
3479         return "SQL_C_SBIGINT";
3480 
3481       case SQL_C_SBIGINT:
3482         return "SQL_C_SBIGINT";
3483 
3484       case SQL_SMALLINT:
3485         return "SQL_SMALLINT";
3486 
3487       case SQL_C_USHORT:
3488         return "SQL_C_USHORT";
3489 
3490       case SQL_C_SSHORT:
3491         return "SQL_C_SSHORT";
3492 
3493       case SQL_TINYINT:
3494         return "SQL_TINYINT";
3495 
3496       case SQL_C_UTINYINT:
3497         return "SQL_C_UTINYINT";
3498 
3499       case SQL_C_STINYINT:
3500         return "SQL_C_STINYINT";
3501 
3502       case SQL_BIT:
3503         return "SQL_BIT";
3504 
3505       case SQL_NUMERIC:
3506         return "SQL_NUMERIC";
3507 
3508       case SQL_REAL:
3509         return "SQL_REAL";
3510 
3511       case SQL_DOUBLE:
3512         return "SQL_DOUBLE";
3513 
3514       case SQL_FLOAT:
3515         return "SQL_FLOAT";
3516 
3517       case SQL_TYPE_DATE:
3518         return "SQL_TYPE_DATE";
3519 
3520       case SQL_DATE:
3521         return "SQL_DATE";
3522 
3523       case SQL_TYPE_TIME:
3524         return "SQL_TYPE_TIME";
3525 
3526       case SQL_TIME:
3527         return "SQL_TIME";
3528 
3529       case SQL_TYPE_TIMESTAMP:
3530         return "SQL_TYPE_TIMESTAMP";
3531 
3532       case SQL_TIMESTAMP:
3533         return "SQL_TIMESTAMP";
3534 
3535       case SQL_INTERVAL_YEAR:
3536         return "SQL_INTERVAL_YEAR ";
3537 
3538       case SQL_INTERVAL_MONTH:
3539         return "SQL_INTERVAL_MONTH";
3540 
3541       case SQL_INTERVAL_DAY:
3542         return "SQL_INTERVAL_DAY ";
3543 
3544       case SQL_INTERVAL_HOUR:
3545         return "SQL_INTERVAL_HOUR";
3546 
3547       case SQL_INTERVAL_MINUTE:
3548         return "SQL_INTERVAL_MINUTE";
3549 
3550       case SQL_INTERVAL_SECOND:
3551         return "SQL_INTERVAL_SECOND";
3552 
3553       case SQL_INTERVAL_YEAR_TO_MONTH:
3554         return "SQL_INTERVAL_YEAR_TO_MONTH";
3555 
3556       case SQL_INTERVAL_DAY_TO_HOUR:
3557         return "SQL_INTERVAL_DAY_TO_HOUR ";
3558 
3559       case SQL_INTERVAL_DAY_TO_MINUTE:
3560         return "SQL_INTERVAL_DAY_TO_MINUTE";
3561 
3562       case SQL_INTERVAL_DAY_TO_SECOND:
3563         return "SQL_INTERVAL_DAY_TO_SECOND";
3564 
3565       case SQL_INTERVAL_HOUR_TO_MINUTE:
3566         return "SQL_INTERVAL_HOUR_TO_MINUTE";
3567 
3568       case SQL_INTERVAL_HOUR_TO_SECOND:
3569         return "SQL_INTERVAL_HOUR_TO_SECOND";
3570 
3571       case SQL_INTERVAL_MINUTE_TO_SECOND:
3572         return "SQL_INTERVAL_MINUTE_TO_SECOND";
3573 
3574       default:
3575         return "";
3576     }
3577 }
3578 
3579 /*
3580  * convert a return type as a string
3581  */
3582 
__get_return_status(SQLRETURN ret,SQLCHAR * buffer)3583 char * __get_return_status( SQLRETURN ret, SQLCHAR *buffer )
3584 {
3585     switch ( ret )
3586     {
3587       case SQL_SUCCESS:
3588         return "SQL_SUCCESS";
3589 
3590       case SQL_ERROR:
3591         return "SQL_ERROR";
3592 
3593       case SQL_SUCCESS_WITH_INFO:
3594         return "SQL_SUCCESS_WITH_INFO";
3595 
3596       case SQL_NO_DATA:
3597         return "SQL_NO_DATA";
3598 
3599       case SQL_STILL_EXECUTING:
3600         return "SQL_STILL_EXECUTING";
3601 
3602       case SQL_INVALID_HANDLE:
3603         return "SQL_INVALID_HANDLE";
3604 
3605       case SQL_NEED_DATA:
3606         return "SQL_NEED_DATA";
3607 
3608       case SQL_PARAM_DATA_AVAILABLE:
3609         return "SQL_PARAM_DATA_AVAILABLE";
3610 
3611       default:
3612         sprintf((char*) buffer, "UNKNOWN(%d)", ret );
3613         return (char*)buffer;
3614     }
3615 }
3616 
wide_ansi_strncmp(SQLWCHAR * str1,char * str2,int len)3617 int wide_ansi_strncmp( SQLWCHAR *str1, char *str2, int len )
3618 {
3619     char c;
3620 
3621     while( len > 0 )
3622     {
3623         if ( *str1 == 0 || *str2 == 0 )
3624             break;
3625 
3626         c = (char) *str1;
3627         if ( c != *str2 )
3628             return *str2 - c;
3629 
3630         str1 ++;
3631         str2 ++;
3632         len --;
3633     }
3634 
3635     c = (char) *str1;
3636 
3637     return *str2 - c;
3638 }
3639 
wide_strcpy(SQLWCHAR * str1,SQLWCHAR * str2)3640 SQLWCHAR *wide_strcpy( SQLWCHAR *str1, SQLWCHAR *str2 )
3641 {
3642     SQLWCHAR *retp = str1;
3643 
3644     if ( !str1 )
3645         return NULL;
3646 
3647     while( *str2 )
3648     {
3649         *str1 = *str2;
3650         str1 ++;
3651         str2 ++;
3652     }
3653     *str1 = 0;
3654 
3655     return retp;
3656 }
3657 
wide_strncpy(SQLWCHAR * str1,SQLWCHAR * str2,int buffer_length)3658 SQLWCHAR *wide_strncpy( SQLWCHAR *str1, SQLWCHAR *str2, int buffer_length )
3659 {
3660     SQLWCHAR *retp = str1;
3661 
3662     if ( !str1 )
3663         return NULL;
3664 
3665     while( *str2 && buffer_length > 0 )
3666     {
3667         *str1 = *str2;
3668         str1 ++;
3669         str2 ++;
3670         buffer_length --;
3671     }
3672     *str1 = 0;
3673 
3674     return retp;
3675 }
3676 
wide_strcat(SQLWCHAR * str1,SQLWCHAR * str2)3677 SQLWCHAR *wide_strcat( SQLWCHAR *str1, SQLWCHAR *str2 )
3678 {
3679     SQLWCHAR *retp = str1;
3680 
3681     while( *str1 )
3682     {
3683         str1 ++;
3684     }
3685 
3686     while( *str2 )
3687     {
3688         *str1 = *str2;
3689         str1 ++;
3690         str2 ++;
3691     }
3692     *str1 = 0;
3693 
3694     return retp;
3695 }
3696 
wide_strdup(SQLWCHAR * str1)3697 SQLWCHAR *wide_strdup( SQLWCHAR *str1 )
3698 {
3699     SQLWCHAR *ptr;
3700     int len = 0;
3701 
3702     while( str1[ len ] )
3703         len ++;
3704 
3705     ptr = malloc( sizeof( SQLWCHAR ) * ( len + 1 ));
3706     if ( !ptr )
3707         return NULL;
3708 
3709     return wide_strcpy( ptr, str1 );
3710 }
3711 
wide_strlen(SQLWCHAR * str1)3712 int wide_strlen( SQLWCHAR *str1 )
3713 {
3714     int len = 0;
3715 
3716     while( str1[ len ] ) {
3717         len ++;
3718     }
3719 
3720     return len;
3721 }
3722 
check_error_order(ERROR * e1,ERROR * e2,EHEAD * head)3723 static int check_error_order( ERROR *e1, ERROR *e2, EHEAD *head )
3724 {
3725     char *s1, *s2;
3726     int ret;
3727 
3728     /*
3729      * as far as I can see, a simple strcmp gives the order we need
3730      */
3731 
3732     s1 = unicode_to_ansi_alloc( e1 -> sqlstate, SQL_NTS, __get_connection( head ), NULL);
3733     s2 = unicode_to_ansi_alloc( e2 -> sqlstate, SQL_NTS, __get_connection( head ), NULL );
3734 
3735     ret = strcmp( s1, s2 );
3736 
3737     free( s1 );
3738     free( s2 );
3739 
3740     return ret;
3741 }
3742 
3743 /*
3744  * insert the error into the list, making sure its in the correct
3745  * order
3746  */
3747 
insert_into_error_list(EHEAD * error_header,ERROR * e1)3748 static void insert_into_error_list( EHEAD *error_header, ERROR *e1 )
3749 {
3750     error_header -> sql_error_head.error_count ++;
3751 
3752     if ( error_header -> sql_error_head.error_list_head )
3753     {
3754         /*
3755          * find where in the list it needs to go
3756          */
3757 
3758         ERROR *curr, *prev;
3759 
3760         prev = NULL;
3761         curr = error_header -> sql_error_head.error_list_head;
3762         while ( curr && check_error_order( curr, e1, error_header ) >= 0 )
3763         {
3764             prev = curr;
3765             curr = curr -> next;
3766         }
3767 
3768         if ( curr )
3769         {
3770             if ( prev )
3771             {
3772                 /*
3773                  * in the middle
3774                  */
3775                 e1 -> next = curr;
3776                 e1 -> prev = curr -> prev;
3777                 curr -> prev -> next = e1;
3778                 curr -> prev = e1;
3779             }
3780             else
3781             {
3782                 /*
3783                  * at the beginning
3784                  */
3785                 e1 -> next = error_header -> sql_error_head.error_list_head;
3786                 e1 -> prev = NULL;
3787                 e1 -> next -> prev = e1;
3788                 error_header -> sql_error_head.error_list_head = e1;
3789             }
3790         }
3791         else
3792         {
3793             /*
3794              * at the end
3795              */
3796 
3797             e1 -> next = NULL;
3798             e1 -> prev = error_header -> sql_error_head.error_list_tail;
3799             e1 -> prev -> next = e1;
3800             error_header -> sql_error_head.error_list_tail = e1;
3801         }
3802     }
3803     else
3804     {
3805         e1 -> next = e1 -> prev = NULL;
3806         error_header -> sql_error_head.error_list_tail = e1;
3807         error_header -> sql_error_head.error_list_head = e1;
3808     }
3809 }
3810 
insert_into_diag_list(EHEAD * error_header,ERROR * e2)3811 static void insert_into_diag_list( EHEAD *error_header, ERROR *e2 )
3812 {
3813     error_header -> sql_diag_head.internal_count ++;
3814 
3815     if ( error_header -> sql_diag_head.internal_list_head )
3816     {
3817         /*
3818          * find where in the list it needs to go
3819          */
3820 
3821         ERROR *curr, *prev;
3822 
3823         prev = NULL;
3824         curr = error_header -> sql_diag_head.internal_list_head;
3825         while ( curr && check_error_order( curr, e2, error_header ) >= 0 )
3826         {
3827             prev = curr;
3828             curr = curr -> next;
3829         }
3830 
3831         if ( curr )
3832         {
3833             if ( prev )
3834             {
3835                 /*
3836                  * in the middle
3837                  */
3838                 e2 -> next = curr;
3839                 e2 -> prev = curr -> prev;
3840                 curr -> prev -> next = e2;
3841                 curr -> prev = e2;
3842             }
3843             else
3844             {
3845                 /*
3846                  * at the beginning
3847                  */
3848                 e2 -> next = error_header -> sql_diag_head.internal_list_head;
3849                 e2 -> prev = NULL;
3850                 e2 -> next -> prev = e2;
3851                 error_header -> sql_diag_head.internal_list_head = e2;
3852             }
3853         }
3854         else
3855         {
3856             /*
3857              * at the end
3858              */
3859 
3860             e2 -> next = NULL;
3861             e2 -> prev = error_header -> sql_diag_head.internal_list_tail;
3862             e2 -> prev -> next = e2;
3863             error_header -> sql_diag_head.internal_list_tail = e2;
3864         }
3865     }
3866     else
3867     {
3868         e2 -> next = e2 -> prev = NULL;
3869         error_header -> sql_diag_head.internal_list_tail = e2;
3870         error_header -> sql_diag_head.internal_list_head = e2;
3871     }
3872 }
3873 
__post_internal_error_ex(EHEAD * error_header,SQLCHAR * sqlstate,SQLINTEGER native_error,SQLCHAR * message_text,int class_origin,int subclass_origin)3874 void __post_internal_error_ex( EHEAD *error_header,
3875         SQLCHAR *sqlstate,
3876         SQLINTEGER native_error,
3877         SQLCHAR *message_text,
3878         int class_origin,
3879         int subclass_origin )
3880 {
3881     SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
3882 
3883     /*
3884      * add our prefix
3885      */
3886 
3887     strcpy((char*) msg, ERROR_PREFIX );
3888     strcat((char*) msg, (char*) message_text );
3889 
3890     __post_internal_error_ex_noprefix(
3891         error_header,
3892         sqlstate,
3893         native_error,
3894         msg,
3895         class_origin,
3896         subclass_origin );
3897 }
3898 
__post_internal_error_ex_noprefix(EHEAD * error_header,SQLCHAR * sqlstate,SQLINTEGER native_error,SQLCHAR * msg,int class_origin,int subclass_origin)3899 void __post_internal_error_ex_noprefix( EHEAD *error_header,
3900         SQLCHAR *sqlstate,
3901         SQLINTEGER native_error,
3902         SQLCHAR *msg,
3903         int class_origin,
3904         int subclass_origin )
3905 {
3906     /*
3907      * create a error block and add to the lists,
3908      * leave space for the error prefix
3909      */
3910 
3911     ERROR *e1, *e2;
3912     DMHDBC conn = __get_connection( error_header );
3913 
3914     e1 = malloc( sizeof( ERROR ));
3915     if (e1 == NULL)
3916         return;
3917     e2 = malloc( sizeof( ERROR ));
3918     if (e2 == NULL)
3919     {
3920         free(e1);
3921         return;
3922     }
3923 
3924     memset( e1, 0, sizeof( *e1 ));
3925     memset( e2, 0, sizeof( *e2 ));
3926 
3927     e1 -> native_error = native_error;
3928     e2 -> native_error = native_error;
3929     ansi_to_unicode_copy(e1 -> sqlstate,
3930                          (char*)sqlstate, SQL_NTS, conn, NULL );
3931     wide_strcpy( e2 -> sqlstate, e1 -> sqlstate );
3932 
3933     e1 -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, conn, NULL );
3934     if ( !e1 -> msg )
3935     {
3936         free( e1 );
3937         free( e2 );
3938         return;
3939     }
3940     e2 -> msg = wide_strdup( e1 -> msg );
3941     if ( !e2 -> msg )
3942     {
3943         free( e1 -> msg);
3944         free( e1 );
3945         free( e2 );
3946         return;
3947     }
3948 
3949     e1 -> return_val = SQL_ERROR;
3950     e2 -> return_val = SQL_ERROR;
3951 
3952     e1 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
3953     e1 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
3954     e1 -> diag_class_origin_ret = SQL_SUCCESS;
3955     e1 -> diag_subclass_origin_ret = SQL_SUCCESS;
3956     e1 -> diag_connection_name_ret = SQL_SUCCESS;
3957     e1 -> diag_server_name_ret = SQL_SUCCESS;
3958     e1 -> diag_column_number = 0;
3959     e1 -> diag_row_number = 0;
3960 
3961     e2 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
3962     e2 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
3963     e2 -> diag_class_origin_ret = SQL_SUCCESS;
3964     e2 -> diag_subclass_origin_ret = SQL_SUCCESS;
3965     e2 -> diag_connection_name_ret = SQL_SUCCESS;
3966     e2 -> diag_server_name_ret = SQL_SUCCESS;
3967     e2 -> diag_column_number = 0;
3968     e2 -> diag_row_number = 0;
3969 
3970     if ( class_origin == SUBCLASS_ODBC )
3971     	ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ODBC 3.0",
3972 			      SQL_NTS, conn, NULL );
3973     else
3974     	ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ISO 9075",
3975 			      SQL_NTS, conn, NULL );
3976     wide_strcpy( e2 -> diag_class_origin, e1 -> diag_class_origin );
3977 
3978     if ( subclass_origin == SUBCLASS_ODBC )
3979     	ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ODBC 3.0",
3980 			      SQL_NTS, conn, NULL );
3981     else
3982     	ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ISO 9075",
3983 			      SQL_NTS, conn, NULL );
3984     wide_strcpy( e2 -> diag_subclass_origin, e1 -> diag_subclass_origin );
3985 
3986     ansi_to_unicode_copy( e1 -> diag_connection_name, (char*) "", SQL_NTS,
3987 			  conn, NULL );
3988     wide_strcpy( e2 -> diag_connection_name, e1 -> diag_connection_name );
3989 
3990     ansi_to_unicode_copy( e1 -> diag_server_name, conn ? conn->dsn : (char*) "", SQL_NTS,
3991 			  conn, NULL );
3992     wide_strcpy( e2 -> diag_server_name, e1 -> diag_server_name );
3993 
3994     /*
3995      * the list for SQLError puts both local and driver
3996      * errors in the same list
3997      */
3998 
3999     insert_into_error_list( error_header, e1 );
4000     insert_into_diag_list( error_header, e2 );
4001 }
4002 
__post_internal_error_ex_w(EHEAD * error_header,SQLWCHAR * sqlstate,SQLINTEGER native_error,SQLWCHAR * message_text,int class_origin,int subclass_origin)4003 void __post_internal_error_ex_w( EHEAD *error_header,
4004         SQLWCHAR *sqlstate,
4005         SQLINTEGER native_error,
4006         SQLWCHAR *message_text,
4007         int class_origin,
4008         int subclass_origin )
4009 {
4010     SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4011 
4012     /*
4013      * add our prefix
4014      */
4015 
4016     ansi_to_unicode_copy(msg, (char*) ERROR_PREFIX, SQL_NTS,
4017 			 __get_connection( error_header ), NULL);
4018     wide_strcat( msg, message_text );
4019 
4020     __post_internal_error_ex_w_noprefix(
4021         error_header,
4022         sqlstate,
4023         native_error,
4024         msg,
4025         class_origin,
4026         subclass_origin );
4027 }
4028 
__post_internal_error_ex_w_noprefix(EHEAD * error_header,SQLWCHAR * sqlstate,SQLINTEGER native_error,SQLWCHAR * msg,int class_origin,int subclass_origin)4029 void __post_internal_error_ex_w_noprefix( EHEAD *error_header,
4030         SQLWCHAR *sqlstate,
4031         SQLINTEGER native_error,
4032         SQLWCHAR *msg,
4033         int class_origin,
4034         int subclass_origin )
4035 {
4036     /*
4037      * create a error block and add to the lists,
4038      * leave space for the error prefix
4039      */
4040 
4041     ERROR *e1, *e2;
4042 
4043     e1 = malloc( sizeof( ERROR ));
4044     if ( !e1 )
4045         return;
4046     e2 = malloc( sizeof( ERROR ));
4047     if ( !e2 )
4048     {
4049         free(e1);
4050         return;
4051     }
4052 
4053     memset( e1, 0, sizeof( *e1 ));
4054     memset( e2, 0, sizeof( *e2 ));
4055 
4056     e1 -> native_error = native_error;
4057     e2 -> native_error = native_error;
4058     wide_strcpy( e1 -> sqlstate, sqlstate );
4059     wide_strcpy( e2 -> sqlstate, sqlstate );
4060     e1 -> msg = wide_strdup( msg );
4061     e2 -> msg = wide_strdup( msg );
4062     e1 -> return_val = SQL_ERROR;
4063     e2 -> return_val = SQL_ERROR;
4064 
4065     e1 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
4066     e1 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
4067     e1 -> diag_class_origin_ret = SQL_SUCCESS;
4068     e1 -> diag_subclass_origin_ret = SQL_SUCCESS;
4069     e1 -> diag_connection_name_ret = SQL_SUCCESS;
4070     e1 -> diag_server_name_ret = SQL_SUCCESS;
4071     e1 -> diag_column_number = 0;
4072     e1 -> diag_row_number = 0;
4073 
4074     e2 -> diag_column_number_ret = SQL_NO_COLUMN_NUMBER;
4075     e2 -> diag_row_number_ret = SQL_NO_ROW_NUMBER;
4076     e2 -> diag_class_origin_ret = SQL_SUCCESS;
4077     e2 -> diag_subclass_origin_ret = SQL_SUCCESS;
4078     e2 -> diag_connection_name_ret = SQL_SUCCESS;
4079     e2 -> diag_server_name_ret = SQL_SUCCESS;
4080     e2 -> diag_column_number = 0;
4081     e2 -> diag_row_number = 0;
4082 
4083     if ( class_origin == SUBCLASS_ODBC )
4084         ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ODBC 3.0",
4085 							  SQL_NTS, __get_connection( error_header ), NULL );
4086     else
4087         ansi_to_unicode_copy( e1 -> diag_class_origin, (char*) "ISO 9075",
4088 							  SQL_NTS, __get_connection( error_header ), NULL );
4089     wide_strcpy( e2 -> diag_class_origin, e1 -> diag_class_origin );
4090 
4091     if ( subclass_origin == SUBCLASS_ODBC )
4092         ansi_to_unicode_copy( e1 -> diag_subclass_origin, (char*) "ODBC 3.0",
4093 							  SQL_NTS, __get_connection( error_header ), NULL );
4094     else
4095         ansi_to_unicode_copy( e1 ->diag_subclass_origin, (char*) "ISO 9075",
4096 							  SQL_NTS, __get_connection( error_header ), NULL );
4097     wide_strcpy( e2 -> diag_subclass_origin, e1 -> diag_subclass_origin );
4098 
4099     e1 -> diag_connection_name[ 0 ] = 0;
4100     e2 -> diag_connection_name[ 0 ] = 0;
4101 
4102     e1 -> diag_server_name[ 0 ] = 0;
4103     e2 -> diag_server_name[ 0 ] = 0;
4104 
4105     error_header -> return_code = SQL_ERROR;
4106 
4107     /*
4108      * the list for SQLError puts both local and driver
4109      * errors in the same list
4110      */
4111 
4112     insert_into_error_list( error_header, e1 );
4113     insert_into_diag_list( error_header, e2 );
4114 }
4115 
4116 /*
4117  * initialise a error header and take note what it belongs to
4118  */
4119 
setup_error_head(EHEAD * error_header,void * handle,int type)4120 void setup_error_head( EHEAD *error_header, void *handle, int type )
4121 {
4122     memset( error_header, 0, sizeof( *error_header ));
4123 
4124     error_header -> owning_handle = handle;
4125     error_header -> handle_type = type;
4126 }
4127 
4128 /*
4129  * free any resources used but the error headers
4130  */
4131 
clear_error_head(EHEAD * error_header)4132 void clear_error_head( EHEAD *error_header )
4133 {
4134     ERROR *cur, *prev;
4135 
4136     prev = NULL;
4137     cur = error_header -> sql_error_head.error_list_head;
4138 
4139     while( cur )
4140     {
4141         prev = cur;
4142 
4143         free( prev -> msg );
4144         cur = prev -> next;
4145         free( prev );
4146     }
4147 
4148     error_header -> sql_error_head.error_list_head = NULL;
4149     error_header -> sql_error_head.error_list_tail = NULL;
4150 
4151     prev = NULL;
4152     cur = error_header -> sql_diag_head.error_list_head;
4153 
4154     while( cur )
4155     {
4156         prev = cur;
4157 
4158         free( prev -> msg );
4159         cur = prev -> next;
4160         free( prev );
4161     }
4162 
4163     error_header -> sql_diag_head.error_list_head = NULL;
4164     error_header -> sql_diag_head.error_list_tail = NULL;
4165 
4166     prev = NULL;
4167     cur = error_header -> sql_diag_head.internal_list_head;
4168 
4169     while( cur )
4170     {
4171         prev = cur;
4172 
4173         free( prev -> msg );
4174         cur = prev -> next;
4175         free( prev );
4176     }
4177 
4178     error_header -> sql_diag_head.internal_list_head = NULL;
4179     error_header -> sql_diag_head.internal_list_tail = NULL;
4180 }
4181 
4182 /*
4183  * get the error values from the handle
4184  */
4185 
extract_diag_error(int htype,DRV_SQLHANDLE handle,DMHDBC connection,EHEAD * head,int return_code,int save_to_diag)4186 void extract_diag_error( int htype,
4187                             DRV_SQLHANDLE handle,
4188                             DMHDBC connection,
4189                             EHEAD *head,
4190                             int return_code,
4191                             int save_to_diag )
4192 {
4193     SQLRETURN ret;
4194     SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4195     SQLCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4196     SQLCHAR sqlstate[ 6 ];
4197     SQLINTEGER native, len;
4198     SQLINTEGER rec_number;
4199 
4200     head -> return_code = return_code;
4201     head -> header_set = 0;
4202     head -> diag_cursor_row_count_ret = SQL_ERROR;
4203     head -> diag_dynamic_function_ret = SQL_ERROR;
4204     head -> diag_dynamic_function_code_ret = SQL_ERROR;
4205     head -> diag_number_ret = SQL_ERROR;
4206     head -> diag_row_count_ret = SQL_ERROR;
4207 
4208     rec_number = 1;
4209     do
4210     {
4211         len = 0;
4212 
4213         ret = SQLGETDIAGREC( connection,
4214                 head -> handle_type,
4215                 handle,
4216                 rec_number,
4217                 sqlstate,
4218                 &native,
4219                 msg1,
4220                 sizeof( msg1 ),
4221                 &len );
4222 
4223 
4224         if ( SQL_SUCCEEDED( ret ))
4225         {
4226             ERROR *e = malloc( sizeof( ERROR ));
4227             SQLWCHAR *tmp;
4228 
4229             /*
4230              * make sure we are truncated in the right place
4231              */
4232 
4233             if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4234                 msg1[ SQL_MAX_MESSAGE_LENGTH - 1 ] = '\0';
4235             }
4236 
4237 #ifdef STRICT_ODBC_ERROR
4238             strcpy((char*) msg, (char*)msg1 );
4239 #else
4240             strcpy((char*) msg, ERROR_PREFIX );
4241             strcat((char*) msg, (char*)msg1 );
4242 #endif
4243 
4244             /*
4245              * add to the SQLError list
4246              */
4247 
4248             e -> native_error = native;
4249             tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4250             wide_strcpy( e -> sqlstate, tmp );
4251             free( tmp );
4252             e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4253             e -> return_val = return_code;
4254 
4255             insert_into_error_list( head, e );
4256 
4257             /*
4258              * we do this if called from a DM function that goes on to call
4259              * a further driver function before returning
4260              */
4261 
4262             if ( save_to_diag )
4263             {
4264                 SQLWCHAR *tmp;
4265 
4266                 e = malloc( sizeof( ERROR ));
4267                 e -> native_error = native;
4268                 tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4269                 wide_strcpy( e -> sqlstate, tmp );
4270                 free( tmp );
4271                 e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4272                 e -> return_val = return_code;
4273 
4274                 insert_into_diag_list( head, e );
4275 
4276                 /*
4277                  * now we need to do some extra calls to get
4278                  * extended info
4279                  */
4280 
4281                 e -> diag_column_number_ret = SQL_ERROR;
4282                 e -> diag_row_number_ret = SQL_ERROR;
4283                 e -> diag_class_origin_ret = SQL_ERROR;
4284                 e -> diag_subclass_origin_ret = SQL_ERROR;
4285                 e -> diag_connection_name_ret = SQL_ERROR;
4286                 e -> diag_server_name_ret= SQL_ERROR;
4287 
4288 
4289                 if ( head -> handle_type == SQL_HANDLE_STMT )
4290                 {
4291                     if ( rec_number == 1 )
4292                     {
4293                         head -> header_set = 1;
4294                         head -> diag_cursor_row_count_ret = SQLGETDIAGFIELD( connection,
4295                             head -> handle_type,
4296                             handle,
4297                             0,
4298                             SQL_DIAG_CURSOR_ROW_COUNT,
4299                             &head->diag_cursor_row_count,
4300                             0,
4301                             NULL );
4302 
4303                         if ( SQL_SUCCEEDED( head -> diag_dynamic_function_ret = SQLGETDIAGFIELD( connection,
4304                             head -> handle_type,
4305                             handle,
4306                             0,
4307                             SQL_DIAG_DYNAMIC_FUNCTION,
4308                             msg,
4309                             sizeof( msg ),
4310                             &len )))
4311                         {
4312                             tmp = ansi_to_unicode_alloc(msg, SQL_NTS, connection, NULL );
4313                             wide_strcpy( head->diag_dynamic_function, tmp );
4314                             free( tmp );
4315                         }
4316 
4317                         head -> diag_dynamic_function_code_ret = SQLGETDIAGFIELD( connection,
4318                             head -> handle_type,
4319                             handle,
4320                             0,
4321                             SQL_DIAG_DYNAMIC_FUNCTION_CODE,
4322                             &head->diag_dynamic_function_code,
4323                             0,
4324                             NULL );
4325 
4326                         head -> diag_number_ret = SQLGETDIAGFIELD( connection,
4327                             head -> handle_type,
4328                             handle,
4329                             0,
4330                             SQL_DIAG_NUMBER,
4331                             &head->diag_number,
4332                             0,
4333                             NULL );
4334 
4335                         head -> diag_row_count_ret = SQLGETDIAGFIELD( connection,
4336                             head -> handle_type,
4337                             handle,
4338                             0,
4339                             SQL_DIAG_ROW_COUNT,
4340                             &head->diag_row_count,
4341                             0,
4342                             NULL );
4343                     }
4344 
4345                     e -> diag_column_number_ret = SQLGETDIAGFIELD( connection,
4346                         head -> handle_type,
4347                         handle,
4348                         rec_number,
4349                         SQL_DIAG_COLUMN_NUMBER,
4350                         &e->diag_column_number,
4351                         0,
4352                         NULL );
4353 
4354                     e -> diag_row_number_ret = SQLGETDIAGFIELD( connection,
4355                         head -> handle_type,
4356                         handle,
4357                         rec_number,
4358                         SQL_DIAG_ROW_NUMBER,
4359                         &e->diag_row_number,
4360                         0,
4361                         NULL );
4362                 }
4363                 else
4364                 {
4365                     e -> diag_column_number_ret = SQL_ERROR;
4366                     e -> diag_row_number_ret = SQL_ERROR;
4367                     e -> diag_class_origin_ret = SQL_ERROR;
4368                     e -> diag_subclass_origin_ret = SQL_ERROR;
4369                     e -> diag_connection_name_ret = SQL_ERROR;
4370                     e -> diag_server_name_ret= SQL_ERROR;
4371 
4372                     if ( SQL_SUCCEEDED( e -> diag_class_origin_ret = SQLGETDIAGFIELD( connection,
4373                         head -> handle_type,
4374                         handle,
4375                         rec_number,
4376                         SQL_DIAG_CLASS_ORIGIN,
4377                         msg,
4378                         sizeof( msg ),
4379                         &len )))
4380                     {
4381                         tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4382                         wide_strcpy( e->diag_class_origin, tmp );
4383                         free( tmp );
4384                     }
4385 
4386                     if ( SQL_SUCCEEDED( e -> diag_subclass_origin_ret = SQLGETDIAGFIELD( connection,
4387                         head -> handle_type,
4388                         handle,
4389                         rec_number,
4390                         SQL_DIAG_SUBCLASS_ORIGIN,
4391                         msg,
4392                         sizeof( msg ),
4393                         &len )))
4394                     {
4395                         tmp = ansi_to_unicode_alloc(msg, SQL_NTS, connection, NULL );
4396                         wide_strcpy( e->diag_subclass_origin, tmp );
4397                         free( tmp );
4398                     }
4399 
4400                     if ( SQL_SUCCEEDED( e -> diag_connection_name_ret = SQLGETDIAGFIELD( connection,
4401                         head -> handle_type,
4402                         handle,
4403                         rec_number,
4404                         SQL_DIAG_CONNECTION_NAME,
4405                         msg,
4406                         sizeof( msg ),
4407                         &len )))
4408                     {
4409                         tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4410                         wide_strcpy( e->diag_connection_name, tmp );
4411                         free( tmp );
4412                     }
4413 
4414                     if ( SQL_SUCCEEDED( e -> diag_server_name_ret = SQLGETDIAGFIELD( connection,
4415                         head -> handle_type,
4416                         handle,
4417                         rec_number,
4418                         SQL_DIAG_SERVER_NAME,
4419                         msg,
4420                         sizeof( msg ),
4421                         &len )))
4422                     {
4423                         tmp = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4424                         wide_strcpy( e -> diag_server_name, tmp );
4425                         free( tmp );
4426                     }
4427                 }
4428             }
4429             else
4430             {
4431                 head -> sql_diag_head.error_count ++;
4432             }
4433 
4434             rec_number ++;
4435 
4436             /*
4437              * add to logfile
4438              */
4439 
4440             if ( log_info.log_flag )
4441             {
4442                 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4443                         sqlstate, msg1 );
4444 
4445                 dm_log_write_diag( connection -> msg );
4446             }
4447         }
4448     }
4449     while( SQL_SUCCEEDED( ret ));
4450 }
4451 
extract_sql_error(DRV_SQLHANDLE henv,DRV_SQLHANDLE hdbc,DRV_SQLHANDLE hstmt,DMHDBC connection,EHEAD * head,int return_code)4452 void extract_sql_error( DRV_SQLHANDLE henv,
4453                             DRV_SQLHANDLE hdbc,
4454                             DRV_SQLHANDLE hstmt,
4455                             DMHDBC connection,
4456                             EHEAD *head,
4457                             int return_code )
4458 {
4459     SQLRETURN ret;
4460     SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4461     SQLCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4462     SQLCHAR sqlstate[ 6 ];
4463     SQLINTEGER native;
4464     SQLSMALLINT len;
4465 
4466     head -> return_code = return_code;
4467     head -> header_set = 0;
4468     head -> diag_cursor_row_count_ret = SQL_ERROR;
4469     head -> diag_dynamic_function_ret = SQL_ERROR;
4470     head -> diag_dynamic_function_code_ret = SQL_ERROR;
4471     head -> diag_number_ret = SQL_ERROR;
4472     head -> diag_row_count_ret = SQL_ERROR;
4473 
4474     do
4475     {
4476         len = 0;
4477 
4478         ret = SQLERROR( connection,
4479                 henv,
4480                 hdbc,
4481                 hstmt,
4482                 sqlstate,
4483                 &native,
4484                 msg1,
4485                 sizeof( msg1 ),
4486                 &len );
4487 
4488         if ( SQL_SUCCEEDED( ret ))
4489         {
4490             SQLWCHAR *tmp;
4491             ERROR *e = malloc( sizeof( ERROR ));
4492 
4493             /*
4494              * add to the lists, SQLError list first
4495              */
4496 
4497             /*
4498              * add our prefix
4499              */
4500 
4501             /*
4502              * make sure we are truncated in the right place
4503              */
4504 
4505             if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4506                 msg1[ SQL_MAX_MESSAGE_LENGTH ] = '\0';
4507             }
4508 
4509 #ifdef STRICT_ODBC_ERROR
4510             strcpy((char*) msg, (char*)msg1 );
4511 #else
4512             strcpy((char*) msg, ERROR_PREFIX );
4513             strcat((char*) msg, (char*)msg1 );
4514 #endif
4515 
4516             e -> native_error = native;
4517             tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4518             wide_strcpy( e -> sqlstate, tmp );
4519             free( tmp );
4520             e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4521             e -> return_val = return_code;
4522 
4523             insert_into_error_list( head, e );
4524 
4525             /*
4526              * SQLGetDiagRec list next
4527              */
4528 
4529             e = malloc( sizeof( ERROR ));
4530 
4531             e -> diag_column_number_ret = SQL_ERROR;
4532             e -> diag_row_number_ret = SQL_ERROR;
4533             e -> diag_class_origin_ret = SQL_ERROR;
4534             e -> diag_subclass_origin_ret = SQL_ERROR;
4535             e -> diag_connection_name_ret = SQL_ERROR;
4536             e -> diag_server_name_ret= SQL_ERROR;
4537 
4538             e -> native_error = native;
4539             tmp = ansi_to_unicode_alloc( sqlstate, SQL_NTS, connection, NULL );
4540             wide_strcpy( e -> sqlstate, tmp );
4541             free( tmp );
4542             e -> msg = ansi_to_unicode_alloc( msg, SQL_NTS, connection, NULL );
4543             e -> return_val = return_code;
4544 
4545             insert_into_diag_list( head, e );
4546 
4547             /*
4548              * add to logfile
4549              */
4550 
4551             if ( log_info.log_flag )
4552             {
4553                 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4554                         sqlstate, msg1 );
4555 
4556                 dm_log_write_diag( connection -> msg );
4557             }
4558         }
4559     }
4560     while( SQL_SUCCEEDED( ret ));
4561 }
4562 
extract_diag_error_w(int htype,DRV_SQLHANDLE handle,DMHDBC connection,EHEAD * head,int return_code,int save_to_diag)4563 void extract_diag_error_w( int htype,
4564                             DRV_SQLHANDLE handle,
4565                             DMHDBC connection,
4566                             EHEAD *head,
4567                             int return_code,
4568                             int save_to_diag )
4569 {
4570     SQLRETURN ret;
4571     SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4572     SQLWCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4573     SQLWCHAR sqlstate[ 6 ];
4574     SQLINTEGER native, len;
4575     SQLINTEGER rec_number;
4576 
4577     head -> return_code = return_code;
4578     head -> header_set = 0;
4579     head -> diag_cursor_row_count_ret = SQL_ERROR;
4580     head -> diag_dynamic_function_ret = SQL_ERROR;
4581     head -> diag_dynamic_function_code_ret = SQL_ERROR;
4582     head -> diag_number_ret = SQL_ERROR;
4583     head -> diag_row_count_ret = SQL_ERROR;
4584 
4585     rec_number = 1;
4586     do
4587     {
4588         len = 0;
4589 
4590         ret = SQLGETDIAGRECW( connection,
4591                 head -> handle_type,
4592                 handle,
4593                 rec_number,
4594                 sqlstate,
4595                 &native,
4596                 msg1,
4597                 SQL_MAX_MESSAGE_LENGTH,
4598                 &len );
4599 
4600         if ( SQL_SUCCEEDED( ret ))
4601         {
4602             ERROR *e = malloc( sizeof( ERROR ));
4603 #ifndef STRICT_ODBC_ERROR
4604             SQLWCHAR *tmp;
4605 #endif
4606 
4607             /*
4608              * make sure we are truncated in the right place
4609              */
4610 
4611             if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4612                 msg1[ SQL_MAX_MESSAGE_LENGTH ] = 0;
4613             }
4614 
4615 #ifdef STRICT_ODBC_ERROR
4616             wide_strcpy( msg, msg1 );
4617 #else
4618             tmp = ansi_to_unicode_alloc((SQLCHAR*) ERROR_PREFIX, SQL_NTS, connection );
4619             wide_strcpy( msg, tmp );
4620             free( tmp );
4621             wide_strcat( msg, msg1 );
4622 #endif
4623 
4624             /*
4625              * add to the SQLError list
4626              */
4627 
4628             e -> native_error = native;
4629             wide_strcpy( e -> sqlstate, sqlstate );
4630             e -> msg = wide_strdup( msg );
4631             e -> return_val = return_code;
4632 
4633             insert_into_error_list( head, e );
4634 
4635             /*
4636              * we do this if called from a DM function that goes on to call
4637              * a further driver function before returning
4638              */
4639 
4640             if ( save_to_diag )
4641             {
4642                 e = malloc( sizeof( ERROR ));
4643                 e -> native_error = native;
4644                 wide_strcpy( e -> sqlstate, sqlstate );
4645                 e -> msg = wide_strdup( msg );
4646                 e -> return_val = return_code;
4647 
4648                 insert_into_diag_list( head, e );
4649 
4650                 /*
4651                  * now we need to do some extra calls to get
4652                  * extended info
4653                  */
4654 
4655                 e -> diag_column_number_ret = SQL_ERROR;
4656                 e -> diag_row_number_ret = SQL_ERROR;
4657                 e -> diag_class_origin_ret = SQL_ERROR;
4658                 e -> diag_subclass_origin_ret = SQL_ERROR;
4659                 e -> diag_connection_name_ret = SQL_ERROR;
4660                 e -> diag_server_name_ret= SQL_ERROR;
4661 
4662                 if ( head -> handle_type == SQL_HANDLE_STMT )
4663                 {
4664                     if ( rec_number == 1 )
4665                     {
4666                         head -> header_set = 1;
4667 
4668                         head -> diag_cursor_row_count_ret = SQLGETDIAGFIELDW( connection,
4669                             head -> handle_type,
4670                             handle,
4671                             0,
4672                             SQL_DIAG_CURSOR_ROW_COUNT,
4673                             &head->diag_cursor_row_count,
4674                             0,
4675                             NULL );
4676 
4677                         head -> diag_dynamic_function_ret = SQLGETDIAGFIELDW( connection,
4678                             head -> handle_type,
4679                             handle,
4680                             0,
4681                             SQL_DIAG_DYNAMIC_FUNCTION,
4682                             head->diag_dynamic_function,
4683                             sizeof( head->diag_dynamic_function ),
4684                             &len );
4685 
4686                         head -> diag_dynamic_function_code_ret = SQLGETDIAGFIELDW( connection,
4687                             head -> handle_type,
4688                             handle,
4689                             0,
4690                             SQL_DIAG_DYNAMIC_FUNCTION_CODE,
4691                             &head->diag_dynamic_function_code,
4692                             0,
4693                             NULL );
4694 
4695                         head -> diag_number_ret = SQLGETDIAGFIELDW( connection,
4696                             head -> handle_type,
4697                             handle,
4698                             0,
4699                             SQL_DIAG_NUMBER,
4700                             &head->diag_number,
4701                             0,
4702                             NULL );
4703 
4704                         head -> diag_row_count_ret = SQLGETDIAGFIELDW( connection,
4705                             head -> handle_type,
4706                             handle,
4707                             0,
4708                             SQL_DIAG_ROW_COUNT,
4709                             &head->diag_row_count,
4710                             0,
4711                             NULL );
4712                     }
4713 
4714                     e -> diag_column_number_ret = SQLGETDIAGFIELDW( connection,
4715                         head -> handle_type,
4716                         handle,
4717                         rec_number,
4718                         SQL_DIAG_COLUMN_NUMBER,
4719                         &e->diag_column_number,
4720                         0,
4721                         NULL );
4722 
4723                     e -> diag_row_number_ret = SQLGETDIAGFIELDW( connection,
4724                         head -> handle_type,
4725                         handle,
4726                         rec_number,
4727                         SQL_DIAG_ROW_NUMBER,
4728                         &e->diag_row_number,
4729                         0,
4730                         NULL );
4731                 }
4732                 else
4733                 {
4734                     e -> diag_column_number_ret = SQL_ERROR;
4735                     e -> diag_row_number_ret = SQL_ERROR;
4736                     e -> diag_class_origin_ret = SQL_ERROR;
4737                     e -> diag_subclass_origin_ret = SQL_ERROR;
4738                     e -> diag_connection_name_ret = SQL_ERROR;
4739                     e -> diag_server_name_ret= SQL_ERROR;
4740 
4741                     e -> diag_class_origin_ret = SQLGETDIAGFIELDW( connection,
4742                         head -> handle_type,
4743                         handle,
4744                         rec_number,
4745                         SQL_DIAG_CLASS_ORIGIN,
4746                         e->diag_class_origin,
4747                         sizeof( e->diag_class_origin ),
4748                         &len );
4749 
4750                     e -> diag_subclass_origin_ret = SQLGETDIAGFIELDW( connection,
4751                         head -> handle_type,
4752                         handle,
4753                         rec_number,
4754                         SQL_DIAG_SUBCLASS_ORIGIN,
4755                         e->diag_subclass_origin,
4756                         sizeof( e->diag_subclass_origin ),
4757                         &len );
4758 
4759                     e -> diag_connection_name_ret = SQLGETDIAGFIELDW( connection,
4760                         head -> handle_type,
4761                         handle,
4762                         rec_number,
4763                         SQL_DIAG_CONNECTION_NAME,
4764                         e->diag_connection_name,
4765                         sizeof( e->diag_connection_name ),
4766                         &len );
4767 
4768                     e -> diag_server_name_ret = SQLGETDIAGFIELDW( connection,
4769                         head -> handle_type,
4770                         handle,
4771                         rec_number,
4772                         SQL_DIAG_SERVER_NAME,
4773                         e->diag_server_name,
4774                         sizeof( e->diag_server_name ),
4775                         &len );
4776                 }
4777             }
4778             else
4779             {
4780                 head -> sql_diag_head.error_count ++;
4781             }
4782 
4783             rec_number ++;
4784 
4785             /*
4786              * add to logfile
4787              */
4788 
4789             if ( log_info.log_flag )
4790             {
4791                 SQLCHAR *as1, *as2;
4792 
4793                 as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL );
4794                 as2 = (SQLCHAR*) unicode_to_ansi_alloc( msg1, SQL_NTS, connection, NULL );
4795 
4796                 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4797                         as1, as2 );
4798 
4799                 if( as1 ) free( as1 );
4800                 if( as2 ) free( as2 );
4801 
4802                 dm_log_write_diag( connection -> msg );
4803             }
4804         }
4805     }
4806     while( SQL_SUCCEEDED( ret ));
4807 }
4808 
extract_sql_error_w(DRV_SQLHANDLE henv,DRV_SQLHANDLE hdbc,DRV_SQLHANDLE hstmt,DMHDBC connection,EHEAD * head,int return_code)4809 void extract_sql_error_w( DRV_SQLHANDLE henv,
4810                             DRV_SQLHANDLE hdbc,
4811                             DRV_SQLHANDLE hstmt,
4812                             DMHDBC connection,
4813                             EHEAD *head,
4814                             int return_code )
4815 {
4816     SQLRETURN ret;
4817     SQLWCHAR msg[ SQL_MAX_MESSAGE_LENGTH + 32 ];
4818     SQLWCHAR msg1[ SQL_MAX_MESSAGE_LENGTH + 1 ];
4819     SQLWCHAR sqlstate[ 6 ];
4820     SQLINTEGER native;
4821     SQLSMALLINT len;
4822 
4823     head -> return_code = return_code;
4824 
4825     do
4826     {
4827         len = 0;
4828 
4829         ret = SQLERRORW( connection,
4830                 henv,
4831                 hdbc,
4832                 hstmt,
4833                 sqlstate,
4834                 &native,
4835                 msg1,
4836                 SQL_MAX_MESSAGE_LENGTH,
4837                 &len );
4838 
4839         if ( SQL_SUCCEEDED( ret ))
4840         {
4841 #ifndef STRICT_ODBC_ERROR
4842             SQLWCHAR *tmp;
4843 #endif
4844 
4845             /*
4846              * add to the lists, SQLError list first
4847              */
4848 
4849             ERROR *e = malloc( sizeof( ERROR ));
4850 
4851             /*
4852              * add our prefix
4853              */
4854 
4855             /*
4856              * make sure we are truncated in the right place
4857              */
4858 
4859             if ( ret == SQL_SUCCESS_WITH_INFO || len >= SQL_MAX_MESSAGE_LENGTH ) {
4860                 msg1[ SQL_MAX_MESSAGE_LENGTH ] = 0;
4861             }
4862 
4863 #ifdef STRICT_ODBC_ERROR
4864             wide_strcpy( msg, msg1 );
4865 #else
4866             tmp = ansi_to_unicode_alloc((SQLCHAR*) ERROR_PREFIX, SQL_NTS, connection, NULL );
4867             wide_strcpy( msg, tmp );
4868             free( tmp );
4869             wide_strcat( msg, msg1 );
4870 #endif
4871 
4872             e -> native_error = native;
4873             wide_strcpy( e -> sqlstate, sqlstate );
4874             e -> msg = wide_strdup( msg );
4875             e -> return_val = return_code;
4876 
4877             insert_into_error_list( head, e );
4878 
4879             /*
4880              * SQLGetDiagRec list next
4881              */
4882 
4883             e = malloc( sizeof( ERROR ));
4884             e -> native_error = native;
4885             wide_strcpy( e -> sqlstate, sqlstate );
4886             e -> msg = wide_strdup( msg );
4887             e -> return_val = return_code;
4888 
4889             insert_into_diag_list( head, e );
4890 
4891             /*
4892              * add to logfile
4893              */
4894 
4895             if ( log_info.log_flag )
4896             {
4897                 SQLCHAR *as1, *as2;
4898 
4899                 as1 = (SQLCHAR*) unicode_to_ansi_alloc( sqlstate, SQL_NTS, connection, NULL );
4900                 as2 = (SQLCHAR*) unicode_to_ansi_alloc( msg1, SQL_NTS, connection, NULL );
4901 
4902                 sprintf( connection -> msg, "\t\tDIAG [%s] %s",
4903                         as1, as2 );
4904 
4905                 if( as1 ) free( as1 );
4906                 if( as2 ) free( as2 );
4907 
4908                 dm_log_write_diag( connection -> msg );
4909             }
4910         }
4911     }
4912     while( SQL_SUCCEEDED( ret ));
4913 }
4914 
4915 /*
4916  * Extract diag information from driver
4917  */
extract_error_from_driver(EHEAD * error_handle,DMHDBC hdbc,int ret_code,int save_to_diag)4918 void extract_error_from_driver( EHEAD * error_handle,
4919                                 DMHDBC hdbc,
4920                                 int ret_code,
4921                                 int save_to_diag )
4922 {
4923     void (*extracterrorfunc)( DRV_SQLHANDLE, DRV_SQLHANDLE, DRV_SQLHANDLE, DMHDBC, EHEAD *, int ) = 0;
4924     void (*extractdiagfunc)( int, DRV_SQLHANDLE, DMHDBC, EHEAD*, int, int ) = 0;
4925 
4926     DRV_SQLHANDLE hdbc_drv = SQL_NULL_HDBC;
4927     DRV_SQLHANDLE hstmt_drv = SQL_NULL_HSTMT;
4928     DRV_SQLHANDLE handle_diag_extract = __get_driver_handle( error_handle );
4929 
4930 
4931     if ( error_handle->handle_type == SQL_HANDLE_ENV )
4932     {
4933         return;
4934     }
4935 
4936     if ( error_handle->handle_type == SQL_HANDLE_DBC )
4937     {
4938         hdbc_drv = handle_diag_extract;
4939     }
4940     else if ( error_handle->handle_type == SQL_HANDLE_STMT )
4941     {
4942         hstmt_drv = handle_diag_extract;
4943     }
4944 
4945     /* If we have the W functions may as well use them */
4946 
4947     if ( CHECK_SQLGETDIAGFIELDW( hdbc ) &&
4948         CHECK_SQLGETDIAGRECW( hdbc ))
4949     {
4950         extractdiagfunc = extract_diag_error_w;
4951     }
4952     else if ( CHECK_SQLERRORW( hdbc ))
4953     {
4954         extracterrorfunc = extract_sql_error_w;
4955     }
4956     else if ( CHECK_SQLGETDIAGFIELD( hdbc ) &&
4957              CHECK_SQLGETDIAGREC( hdbc ))
4958     {
4959         extractdiagfunc = extract_diag_error;
4960     }
4961     else if ( CHECK_SQLERROR( hdbc ))
4962     {
4963         extracterrorfunc = extract_sql_error;
4964     }
4965 
4966     if ( extractdiagfunc )
4967     {
4968         extractdiagfunc( error_handle->handle_type,
4969                 handle_diag_extract,
4970                 hdbc,
4971                 error_handle,
4972                 ret_code,
4973                 save_to_diag );
4974     }
4975     else if ( error_handle->handle_type != SQL_HANDLE_DESC && extracterrorfunc )
4976     {
4977         extracterrorfunc( SQL_NULL_HENV,
4978                 hdbc_drv,
4979                 hstmt_drv,
4980                 hdbc,
4981                 error_handle,
4982                 ret_code );
4983     }
4984     else
4985     {
4986         __post_internal_error( error_handle,
4987             ERROR_HY000, "Driver returned SQL_ERROR or SQL_SUCCESS_WITH_INFO but no error reporting API found",
4988             hdbc->environment->requested_version );
4989     }
4990 }
4991 
4992 
4993 /* Return without collecting diag recs from the handle - to be called if the
4994    DM function is returning before calling the driver function. */
function_return_nodrv(int level,void * handle,int ret_code)4995 int function_return_nodrv( int level, void *handle, int ret_code)
4996 {
4997     if ( level != IGNORE_THREAD )
4998     {
4999         thread_release( level, handle );
5000     }
5001     return ret_code;
5002 }
5003 
5004 /*
5005  * capture function returns and check error's if necessary
5006  */
5007 
function_return_ex(int level,void * handle,int ret_code,int save_to_diag,int defer_type)5008 int function_return_ex( int level, void * handle, int ret_code, int save_to_diag, int defer_type )
5009 {
5010     DMHENV  henv;
5011     DMHDBC  hdbc;
5012     DMHSTMT hstmt;
5013     DMHDESC hdesc;
5014     EHEAD   *herror = NULL;
5015 
5016     if ( ret_code == SQL_SUCCESS_WITH_INFO || ret_code == SQL_ERROR )
5017     {
5018         /*
5019          * find what type of handle it is
5020          */
5021         henv = handle;
5022 
5023         switch ( henv -> type )
5024         {
5025           case HENV_MAGIC:
5026             {
5027                 /*
5028                  * do nothing, it must be local
5029                  */
5030             }
5031             break;
5032 
5033           case HDBC_MAGIC:
5034             {
5035                 hdbc = handle;
5036 
5037                 /*
5038                  * are we connected ?
5039                  */
5040 
5041                 if ( hdbc -> state >= STATE_C4 )
5042                 {
5043                     herror = &hdbc->error;
5044                 }
5045             }
5046             break;
5047 
5048           case HSTMT_MAGIC:
5049             {
5050                 hstmt = handle;
5051                 herror = &hstmt->error;
5052                 hdbc = hstmt->connection;
5053             }
5054             break;
5055 
5056           case HDESC_MAGIC:
5057             {
5058                 hdesc = handle;
5059                 herror = &hdesc->error;
5060                 hdbc = hdesc->connection;
5061             }
5062             break;
5063         }
5064 
5065         if ( herror )
5066         {
5067             /*
5068              * set defer flag
5069              */
5070             herror->defer_extract = ( ret_code == SQL_SUCCESS_WITH_INFO ? defer_type : defer_type >> 1 ) & 1;
5071 
5072             if ( herror->defer_extract )
5073             {
5074                 herror->ret_code_deferred = ret_code;
5075             }
5076             else
5077             {
5078                 extract_error_from_driver( herror, hdbc, ret_code, save_to_diag );
5079             }
5080         }
5081     }
5082 
5083     /*
5084      * release any threads
5085      */
5086 
5087     if ( level != IGNORE_THREAD )
5088     {
5089         thread_release( level, handle );
5090     }
5091 
5092     return ret_code;
5093 }
5094 
5095 /*
5096  * clear errors down at the start of a new statement
5097  * only clear for the ODBC lists, the rest stay
5098  */
5099 
function_entry(void * handle)5100 void function_entry( void *handle )
5101 {
5102     ERROR *cur, *prev;
5103     EHEAD *error_header;
5104     DMHENV henv;
5105     DMHDBC hdbc;
5106     DMHSTMT hstmt;
5107     DMHDESC hdesc;
5108     int version;
5109 
5110     /*
5111      * find what the handle is
5112      */
5113 
5114     henv = handle;
5115     switch( henv -> type )
5116     {
5117       case HENV_MAGIC:
5118         error_header = &henv -> error;
5119         version = henv -> requested_version;
5120         break;
5121 
5122       case HDBC_MAGIC:
5123         hdbc = handle;
5124         error_header = &hdbc -> error;
5125         version = hdbc -> environment -> requested_version;
5126         break;
5127 
5128       case HSTMT_MAGIC:
5129         hstmt = handle;
5130         error_header = &hstmt -> error;
5131         version = hstmt -> connection -> environment -> requested_version;
5132         break;
5133 
5134       case HDESC_MAGIC:
5135         hdesc = handle;
5136         error_header = &hdesc -> error;
5137         version = hdesc -> connection -> environment -> requested_version;
5138         break;
5139     }
5140 
5141     error_header->defer_extract = 0;
5142     error_header->ret_code_deferred = 0;
5143 
5144     prev = NULL;
5145     cur = error_header -> sql_diag_head.error_list_head;
5146 
5147     while( cur )
5148     {
5149         prev = cur;
5150 
5151         free( prev -> msg );
5152         cur = prev -> next;
5153         free( prev );
5154     }
5155 
5156     error_header -> sql_diag_head.error_list_head = NULL;
5157     error_header -> sql_diag_head.error_list_tail = NULL;
5158     error_header -> sql_diag_head.error_count = 0;
5159     error_header -> header_set = 0;
5160 
5161     prev = NULL;
5162     cur = error_header -> sql_diag_head.internal_list_head;
5163 
5164     while( cur )
5165     {
5166         prev = cur;
5167 
5168         free( prev -> msg );
5169         cur = prev -> next;
5170         free( prev );
5171     }
5172 
5173     error_header -> sql_diag_head.internal_list_head = NULL;
5174     error_header -> sql_diag_head.internal_list_tail = NULL;
5175     error_header -> sql_diag_head.internal_count = 0;
5176 
5177     /*
5178      * if version is SQL_OV_ODBC3 then clear the SQLError list
5179      * as well
5180      */
5181 
5182 #ifdef USE_OLD_ODBC2_ERROR_CLEARING
5183     if ( version >= SQL_OV_ODBC3 )
5184 #endif
5185     {
5186         prev = NULL;
5187         cur = error_header -> sql_error_head.error_list_head;
5188 
5189         while( cur )
5190         {
5191             prev = cur;
5192 
5193             free( prev -> msg );
5194             cur = prev -> next;
5195             free( prev );
5196         }
5197 
5198         error_header -> sql_error_head.error_list_head = NULL;
5199         error_header -> sql_error_head.error_list_tail = NULL;
5200         error_header -> sql_error_head.error_count = 0;
5201     }
5202 }
5203 
__post_internal_error(EHEAD * error_handle,error_id id,char * txt,int connection_mode)5204 void __post_internal_error( EHEAD *error_handle,
5205         error_id id, char *txt, int connection_mode )
5206 {
5207     __post_internal_error_api( error_handle, id, txt, connection_mode, 0 );
5208 
5209 }
5210 
__post_internal_error_api(EHEAD * error_handle,error_id id,char * txt,int connection_mode,int calling_api)5211 void __post_internal_error_api( EHEAD *error_handle,
5212         error_id id, char *txt, int connection_mode, int calling_api )
5213 {
5214     char sqlstate[ 6 ];
5215     char *message;
5216     SQLCHAR msg[ SQL_MAX_MESSAGE_LENGTH ];
5217     SQLRETURN ret = SQL_ERROR;
5218     int class, subclass;
5219 
5220     class = SUBCLASS_ISO;
5221     subclass = SUBCLASS_ISO;
5222 
5223     switch( id )
5224     {
5225       case ERROR_01000:
5226         strcpy( sqlstate, "01000" );
5227         message = "General warning";
5228         break;
5229 
5230       case ERROR_01004:
5231         strcpy( sqlstate, "01004" );
5232         message = "String data, right truncated";
5233         break;
5234 
5235       case ERROR_01S02:
5236         strcpy( sqlstate, "01S02" );
5237         message = "Option value changed";
5238         subclass = SUBCLASS_ODBC;
5239         break;
5240 
5241       case ERROR_01S06:
5242         strcpy( sqlstate, "01S06" );
5243         message = "Attempt to fetch before the result set returned the first rowset";
5244         subclass = SUBCLASS_ODBC;
5245         break;
5246 
5247       case ERROR_07005:
5248         strcpy( sqlstate, "07005" );
5249         message = "Prepared statement not a cursor-specification";
5250         break;
5251 
5252       case ERROR_07009:
5253         switch( calling_api )
5254         {
5255           case SQL_API_SQLDESCRIBEPARAM:
5256           case SQL_API_SQLBINDPARAMETER:
5257           case SQL_API_SQLSETPARAM:
5258                 if ( connection_mode >= SQL_OV_ODBC3 )
5259                     strcpy( sqlstate, "07009" );
5260                 else
5261                     strcpy( sqlstate, "S1093" );
5262                 message = "Invalid parameter index";
5263                 break;
5264 
5265           default:
5266                 if ( connection_mode >= SQL_OV_ODBC3 )
5267                     strcpy( sqlstate, "07009" );
5268                 else
5269                     strcpy( sqlstate, "S1002" );
5270                 message = "Invalid descriptor index";
5271                 break;
5272         }
5273         break;
5274 
5275       case ERROR_08002:
5276         strcpy( sqlstate, "08002" );
5277         message = "Connection in use";
5278         break;
5279 
5280       case ERROR_08003:
5281         strcpy( sqlstate, "08003" );
5282         message = "Connection not open";
5283         break;
5284 
5285       case ERROR_24000:
5286         strcpy( sqlstate, "24000" );
5287         message = "Invalid cursor state";
5288         break;
5289 
5290       case ERROR_25000:
5291         message = "Invalid transaction state";
5292         strcpy( sqlstate, "25000" );
5293         break;
5294 
5295       case ERROR_25S01:
5296         message = "Transaction state unknown";
5297         strcpy( sqlstate, "25S01" );
5298         subclass = SUBCLASS_ODBC;
5299         break;
5300 
5301       case ERROR_S1000:
5302         message = "General error";
5303         strcpy( sqlstate, "S1000" );
5304         break;
5305 
5306       case ERROR_S1003:
5307         message = "Program type out of range";
5308         strcpy( sqlstate, "S1003" );
5309         break;
5310 
5311       case ERROR_S1010:
5312         message = "Function sequence error";
5313         strcpy( sqlstate, "S1010" );
5314         break;
5315 
5316       case ERROR_S1011:
5317         message = "Operation invalid at this time";
5318         strcpy( sqlstate, "S1011" );
5319         break;
5320 
5321       case ERROR_S1107:
5322         message = "Row value out of range";
5323         strcpy( sqlstate, "S1107" );
5324         break;
5325 
5326       case ERROR_S1108:
5327         message = "Concurrency option out of range";
5328         strcpy( sqlstate, "S1108" );
5329         break;
5330 
5331       case ERROR_S1C00:
5332         message = "Driver not capable";
5333         strcpy( sqlstate, "S1C00" );
5334         break;
5335 
5336       case ERROR_HY001:
5337         if ( connection_mode >= SQL_OV_ODBC3 )
5338             strcpy( sqlstate, "HY001" );
5339         else
5340             strcpy( sqlstate, "S1011" );
5341         message = "Memory allocation error";
5342         break;
5343 
5344       case ERROR_HY003:
5345         if ( connection_mode >= SQL_OV_ODBC3 )
5346         {
5347             strcpy( sqlstate, "HY003" );
5348             /* Windows DM returns " Program type out of range" instead of
5349                "Invalid application buffer type" */
5350             message = "Program type out of range";
5351         }
5352         else
5353         {
5354             strcpy( sqlstate, "S1003" );
5355         message = "Invalid application buffer type";
5356         }
5357         break;
5358 
5359       case ERROR_HY004:
5360         if ( connection_mode >= SQL_OV_ODBC3 )
5361             strcpy( sqlstate, "HY004" );
5362         else
5363             strcpy( sqlstate, "S1004" );
5364         message = "Invalid SQL data type";
5365         break;
5366 
5367       case ERROR_HY007:
5368         if ( connection_mode >= SQL_OV_ODBC3 )
5369             strcpy( sqlstate, "HY007" );
5370         else
5371             strcpy( sqlstate, "S1007" );
5372         message = "Associated statement is not prepared";
5373         break;
5374 
5375       case ERROR_HY009:
5376         if ( connection_mode >= SQL_OV_ODBC3 )
5377             strcpy( sqlstate, "HY009" );
5378         else
5379             strcpy( sqlstate, "S1009" );
5380         message = "Invalid use of null pointer";
5381         break;
5382 
5383       case ERROR_HY010:
5384         if ( connection_mode >= SQL_OV_ODBC3 )
5385             strcpy( sqlstate, "HY010" );
5386         else
5387             strcpy( sqlstate, "S1010" );
5388         message = "Function sequence error";
5389         break;
5390 
5391       case ERROR_HY011:
5392         if ( connection_mode >= SQL_OV_ODBC3 )
5393             strcpy( sqlstate, "HY011" );
5394         else
5395             strcpy( sqlstate, "S1011" );
5396         message = "Attribute cannot be set now";
5397         break;
5398 
5399       case ERROR_HY012:
5400 	    if ( connection_mode >= SQL_OV_ODBC3 )
5401             strcpy( sqlstate, "HY012" );
5402         else
5403             strcpy( sqlstate, "S1012" );
5404         message = "Invalid transaction operation code";
5405         break;
5406 
5407       case ERROR_HY013:
5408         if ( connection_mode >= SQL_OV_ODBC3 )
5409             strcpy( sqlstate, "HY013" );
5410         else
5411             strcpy( sqlstate, "S1013" );
5412         message = "Memory management error";
5413         break;
5414 
5415       case ERROR_HY017:
5416         strcpy( sqlstate, "HY017" );
5417         message = "Invalid use of an automatically allocated descriptor handle";
5418         break;
5419 
5420       case ERROR_HY024:
5421         if ( connection_mode >= SQL_OV_ODBC3 )
5422             strcpy( sqlstate, "HY024" );
5423         else
5424             strcpy( sqlstate, "S1009" );
5425         message = "Invalid attribute value";
5426         break;
5427 
5428       case ERROR_HY090:
5429         if ( connection_mode >= SQL_OV_ODBC3 )
5430             strcpy( sqlstate, "HY090" );
5431         else
5432             strcpy( sqlstate, "S1090" );
5433         message = "Invalid string or buffer length";
5434         break;
5435 
5436       case ERROR_HY092:
5437         if ( connection_mode >= SQL_OV_ODBC3 )
5438             strcpy( sqlstate, "HY092" );
5439         else
5440             strcpy( sqlstate, "S1092" );
5441         message = "Invalid attribute/option identifier";
5442         break;
5443 
5444       case ERROR_HY095:
5445         if ( connection_mode >= SQL_OV_ODBC3 )
5446             strcpy( sqlstate, "HY095" );
5447         else
5448             strcpy( sqlstate, "S1095" );
5449         message = "Function type out of range";
5450         break;
5451 
5452       case ERROR_HY097:
5453         if ( connection_mode >= SQL_OV_ODBC3 )
5454             strcpy( sqlstate, "HY097" );
5455         else
5456             strcpy( sqlstate, "S1097" );
5457         message = "Column type out of range";
5458         break;
5459 
5460       case ERROR_HY098:
5461         if ( connection_mode >= SQL_OV_ODBC3 )
5462             strcpy( sqlstate, "HY098" );
5463         else
5464             strcpy( sqlstate, "S1098" );
5465         message = "Scope type out of range";
5466         break;
5467 
5468       case ERROR_HY099:
5469         if ( connection_mode >= SQL_OV_ODBC3 )
5470             strcpy( sqlstate, "HY099" );
5471         else
5472             strcpy( sqlstate, "S1099" );
5473         message = "Nullable type out of range";
5474         break;
5475 
5476       case ERROR_HY100:
5477         if ( connection_mode >= SQL_OV_ODBC3 )
5478             strcpy( sqlstate, "HY100" );
5479         else
5480             strcpy( sqlstate, "S1100" );
5481         message = "Uniqueness option type out of range";
5482         break;
5483 
5484       case ERROR_HY101:
5485         if ( connection_mode >= SQL_OV_ODBC3 )
5486             strcpy( sqlstate, "HY101" );
5487         else
5488             strcpy( sqlstate, "S1101" );
5489         message = "Accuracy option type out of range";
5490         break;
5491 
5492       case ERROR_HY103:
5493         if ( connection_mode >= SQL_OV_ODBC3 )
5494             strcpy( sqlstate, "HY103" );
5495         else
5496             strcpy( sqlstate, "S1103" );
5497         message = "Invalid retrieval code";
5498         break;
5499 
5500       case ERROR_HY105:
5501         if ( connection_mode >= SQL_OV_ODBC3 )
5502             strcpy( sqlstate, "HY105" );
5503         else
5504             strcpy( sqlstate, "S1105" );
5505         message = "Invalid parameter type";
5506         break;
5507 
5508       case ERROR_HY106:
5509         if ( connection_mode >= SQL_OV_ODBC3 )
5510             strcpy( sqlstate, "HY106" );
5511         else
5512             strcpy( sqlstate, "S1106" );
5513         message = "Fetch type out of range";
5514         break;
5515 
5516       case ERROR_HY110:
5517         if ( connection_mode >= SQL_OV_ODBC3 )
5518             strcpy( sqlstate, "HY110" );
5519         else
5520             strcpy( sqlstate, "S1110" );
5521         message = "Invalid driver completion";
5522         break;
5523 
5524       case ERROR_HY111:
5525         if ( connection_mode >= SQL_OV_ODBC3 )
5526             strcpy( sqlstate, "HY111" );
5527         else
5528             strcpy( sqlstate, "S1111" );
5529         message = "Invalid bookmark value";
5530         break;
5531 
5532       case ERROR_HYC00:
5533         if ( connection_mode >= SQL_OV_ODBC3 )
5534             strcpy( sqlstate, "HYC00" );
5535         else
5536             strcpy( sqlstate, "S1C00" );
5537         message = "Optional feature not implemented";
5538         break;
5539 
5540       case ERROR_IM001:
5541         strcpy( sqlstate, "IM001" );
5542         message = "Driver does not support this function";
5543         subclass = SUBCLASS_ODBC;
5544         class = SUBCLASS_ODBC;
5545         break;
5546 
5547       case ERROR_IM002:
5548         strcpy( sqlstate, "IM002" );
5549         message = "Data source name not found and no default driver specified";
5550         subclass = SUBCLASS_ODBC;
5551         class = SUBCLASS_ODBC;
5552         break;
5553 
5554       case ERROR_IM003:
5555         strcpy( sqlstate, "IM003" );
5556         message = "Specified driver could not be loaded";
5557         subclass = SUBCLASS_ODBC;
5558         class = SUBCLASS_ODBC;
5559         break;
5560 
5561       case ERROR_IM004:
5562         strcpy( sqlstate, "IM004" );
5563         message = "Driver's SQLAllocHandle on SQL_HANDLE_HENV failed";
5564         subclass = SUBCLASS_ODBC;
5565         class = SUBCLASS_ODBC;
5566         break;
5567 
5568       case ERROR_IM005:
5569         strcpy( sqlstate, "IM005" );
5570         message = "Driver's SQLAllocHandle on SQL_HANDLE_DBC failed";
5571         subclass = SUBCLASS_ODBC;
5572         class = SUBCLASS_ODBC;
5573         break;
5574 
5575       case ERROR_IM010:
5576         strcpy( sqlstate, "IM010" );
5577         message = "Data source name too long";
5578         subclass = SUBCLASS_ODBC;
5579         class = SUBCLASS_ODBC;
5580         break;
5581 
5582       case ERROR_IM011:
5583         strcpy( sqlstate, "IM011" );
5584         message = "Driver name too long";
5585         subclass = SUBCLASS_ODBC;
5586         class = SUBCLASS_ODBC;
5587         break;
5588 
5589       case ERROR_IM012:
5590         strcpy( sqlstate, "IM012" );
5591         message = "DRIVER keyword syntax error";
5592         subclass = SUBCLASS_ODBC;
5593         class = SUBCLASS_ODBC;
5594         break;
5595 
5596       case ERROR_SL004:
5597         strcpy( sqlstate, "SL004" );
5598         message = "Result set not generated by a SELECT statement";
5599         subclass = SUBCLASS_ODBC;
5600         class = SUBCLASS_ODBC;
5601         break;
5602 
5603       case ERROR_SL009:
5604         strcpy( sqlstate, "SL009" );
5605         message = "No columns were bound prior to calling SQLFetch or SQLFetchScroll";
5606         subclass = SUBCLASS_ODBC;
5607         class = SUBCLASS_ODBC;
5608         break;
5609 
5610       case ERROR_SL010:
5611         strcpy( sqlstate, "SL010" );
5612         message = "SQLBindCol returned SQL_ERROR on a attempt to bind a internal buffer";
5613         subclass = SUBCLASS_ODBC;
5614         class = SUBCLASS_ODBC;
5615         break;
5616 
5617       case ERROR_SL008:
5618         strcpy( sqlstate, "SL008" );
5619         message = "SQLGetData is not allowed on a forward only (non-buffered) cursor";
5620         subclass = SUBCLASS_ODBC;
5621         class = SUBCLASS_ODBC;
5622         break;
5623 
5624       case ERROR_HY000:
5625         if ( connection_mode >= SQL_OV_ODBC3 )
5626             strcpy( sqlstate, "HY000" );
5627         else
5628             strcpy( sqlstate, "S1000" );
5629         message = "General error";
5630         break;
5631 
5632 	  default:
5633         strcpy( sqlstate, "?????" );
5634         message = "Unknown";
5635     }
5636 
5637     if ( txt )
5638         message = txt;
5639 
5640     strcpy((char*) msg, DM_ERROR_PREFIX );
5641     strncat((char*) msg, message, sizeof(msg) - sizeof(DM_ERROR_PREFIX) );
5642 
5643     error_handle -> return_code = ret;
5644 
5645     __post_internal_error_ex( error_handle,
5646         (SQLCHAR*)sqlstate, 0, msg, class, subclass );
5647 }
5648 
5649 /*
5650  * open a log file
5651  */
5652 
dm_log_open(char * program_name,char * log_file_name,int pid_logging)5653 void  dm_log_open( char *program_name,
5654         char *log_file_name, int pid_logging )
5655 {
5656     if ( log_info.program_name )
5657     {
5658         free( log_info.program_name );
5659     }
5660     if ( log_info.log_file_name )
5661     {
5662         free( log_info.log_file_name );
5663     }
5664     log_info.program_name = strdup( program_name );
5665     log_info.log_file_name = strdup( log_file_name );
5666     log_info.log_flag = 1;
5667 
5668     /*
5669      * are we doing perprocess logging
5670      */
5671 
5672     log_info.pid_logging = pid_logging;
5673     log_info.ref_count++;
5674 }
5675 
dm_log_write(char * function_name,int line,int type,int severity,char * message)5676 void dm_log_write( char *function_name, int line, int type, int severity,
5677         char *message )
5678 {
5679     FILE *fp;
5680     char tmp[ 24 ];
5681 
5682     if ( !log_info.log_flag && !ODBCSharedTraceFlag )
5683         return;
5684 
5685     if ( log_info.pid_logging )
5686     {
5687         char file_name[ 256 ], str[ 20 ];
5688 
5689         if ( !log_info.log_file_name )
5690         {
5691             strcpy( file_name, "/tmp/sql.log" );
5692         }
5693         else
5694         {
5695             sprintf( file_name, "%s/%s", log_info.log_file_name, __get_pid((SQLCHAR*) str ));
5696         }
5697         fp = uo_fopen( file_name, "a" );
5698 
5699         /*
5700          * Change the mode to be rw for all
5701          */
5702         chmod( file_name, 0666 );
5703     }
5704     else
5705     {
5706         if ( !log_info.log_file_name )
5707         {
5708             fp = uo_fopen( "/tmp/sql.log", "a" );
5709         }
5710         else
5711         {
5712             fp = uo_fopen( log_info.log_file_name, "a" );
5713         }
5714     }
5715 
5716     if ( fp )
5717     {
5718 		char tstamp_str[ 128 ];
5719 
5720 #if defined( HAVE_GETTIMEOFDAY ) && defined( HAVE_SYS_TIME_H )
5721 		{
5722 			struct timeval tv;
5723 			void* tz = NULL;
5724 
5725 			gettimeofday( &tv, tz );
5726 
5727 			sprintf( tstamp_str, "[%ld.%06ld]", tv.tv_sec, tv.tv_usec );
5728 		}
5729 #elif defined( HAVE_FTIME ) && defined( HAVE_SYS_TIMEB_H )
5730 		{
5731 			struct timeb tp;
5732 
5733 			ftime( &tp );
5734 
5735 			sprintf( tstamp_str, "[%ld.%03d]", tp.time, tp.millitm );
5736 		}
5737 #elif defined( DHAVE_TIME ) && defined( HAVE_TIME_H )
5738 		{
5739 			time_t tv;
5740 
5741 			time( &tv );
5742 			sprintf( tstamp_str, "[%ld]", tv );
5743 		}
5744 #else
5745 		tstamp_str[ 0 ] = '\0';
5746 #endif
5747         if ( !log_info.program_name )
5748         {
5749             uo_fprintf( fp, "[ODBC][%s]%s[%s][%d]%s\n", __get_pid((SQLCHAR*) tmp ),
5750 					tstamp_str,
5751                     function_name, line, message );
5752         }
5753         else
5754         {
5755             uo_fprintf( fp, "[%s][%s]%s[%s][%d]%s\n", log_info.program_name,
5756                 __get_pid((SQLCHAR*) tmp ),
5757 				tstamp_str,
5758 				function_name, line, message );
5759         }
5760 
5761         uo_fclose( fp );
5762     }
5763 }
5764 
dm_log_write_diag(char * message)5765 void dm_log_write_diag( char *message )
5766 {
5767     FILE *fp;
5768 
5769     if ( !log_info.log_flag && !ODBCSharedTraceFlag )
5770         return;
5771 
5772     if ( log_info.pid_logging )
5773     {
5774         char file_name[ 256 ], str[ 20 ];
5775 
5776         if ( !log_info.log_file_name )
5777         {
5778             strcpy( file_name, "/tmp/sql.log" );
5779         }
5780         else
5781         {
5782             sprintf( file_name, "%s/%s", log_info.log_file_name, __get_pid((SQLCHAR*) str ));
5783         }
5784         fp = uo_fopen( file_name, "a" );
5785 
5786         /*
5787          * Change the mode to be rw for all
5788          */
5789         chmod( file_name, 0666 );
5790     }
5791     else
5792     {
5793         if ( !log_info.log_file_name )
5794         {
5795             fp = uo_fopen( "/tmp/sql.log", "a" );
5796         }
5797         else
5798         {
5799             fp = uo_fopen( log_info.log_file_name, "a" );
5800         }
5801     }
5802 
5803     if ( fp )
5804     {
5805         uo_fprintf( fp, "%s\n\n", message );
5806 
5807         uo_fclose( fp );
5808     }
5809 }
5810 
dm_log_close(void)5811 void dm_log_close( void )
5812 {
5813     if ( !log_info.ref_count )
5814         return;
5815 
5816     log_info.ref_count--;
5817     if ( !log_info.ref_count )
5818     {
5819         free( log_info.program_name );
5820         free( log_info.log_file_name );
5821         log_info.program_name = NULL;
5822         log_info.log_file_name = NULL;
5823         log_info.log_flag = 0;
5824     }
5825 }
5826