FreeTDS API
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
tds.h
Go to the documentation of this file.
1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns
3  * Copyright (C) 2010, 2011 Frediano Ziglio
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #ifndef _tds_h_
22 #define _tds_h_
23 
24 /* $Id: tds.h,v 1.352.2.4 2011-08-12 16:29:36 freddy77 Exp $ */
25 
26 #include <stdarg.h>
27 #include <stdio.h>
28 #include <time.h>
29 
30 #if HAVE_NETINET_IN_H
31 #include <netinet/in.h>
32 #endif /* HAVE_NET_INET_IN_H */
33 #if HAVE_ARPA_INET_H
34 #include <arpa/inet.h>
35 #endif /* HAVE_ARPA_INET_H */
36 
37 /* forward declaration */
38 typedef struct tdsiconvinfo TDSICONV;
39 typedef struct tds_socket TDSSOCKET;
40 
41 #include "tdsver.h"
42 #include "tds_sysdep_public.h"
43 #ifdef _FREETDS_LIBRARY_SOURCE
44 #include "tds_sysdep_private.h"
45 #endif /* _FREETDS_LIBRARY_SOURCE */
46 
47 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
48 #pragma GCC visibility push(hidden)
49 #endif
50 
51 #ifdef __cplusplus
52 extern "C"
53 {
54 #if 0
55 }
56 #endif
57 #endif
58 
65 {
66  const char *freetds_version; /* release version of FreeTDS */
67  const char *sysconfdir; /* location of freetds.conf */
68  const char *last_update; /* latest software_version date among the modules */
69  int msdblib; /* for MS style dblib */
70  int sybase_compat; /* enable increased Open Client binary compatibility */
71  int threadsafe; /* compile for thread safety default=no */
72  int libiconv; /* search for libiconv in DIR/include and DIR/lib */
73  const char *tdsver; /* TDS protocol version (4.2/4.6/5.0/7.0/8.0) 5.0 */
74  int iodbc; /* build odbc driver against iODBC in DIR */
75  int unixodbc; /* build odbc driver against unixODBC in DIR */
76 
78 
79 typedef struct tds_dstr {
80  char *dstr_s;
81  size_t dstr_size;
82 } DSTR;
83 
99 /*
100  * All references to data that touch the wire should use the following typedefs.
101  *
102  * If you have problems on 64-bit machines and the code is
103  * using a native datatype, please change it to use
104  * these. (In the TDS layer only, the API layers have their
105  * own typedefs which equate to these).
106  */
107 typedef char TDS_CHAR; /* 8-bit char */
108 typedef unsigned char TDS_UCHAR; /* 8-bit uchar */
109 typedef unsigned char TDS_TINYINT; /* 8-bit unsigned */
110 typedef tds_sysdep_int16_type TDS_SMALLINT; /* 16-bit int */
111 typedef unsigned tds_sysdep_int16_type TDS_USMALLINT; /* 16-bit unsigned */
112 typedef tds_sysdep_int32_type TDS_INT; /* 32-bit int */
113 typedef unsigned tds_sysdep_int32_type TDS_UINT; /* 32-bit unsigned */
114 typedef tds_sysdep_real32_type TDS_REAL; /* 32-bit real */
115 typedef tds_sysdep_real64_type TDS_FLOAT; /* 64-bit real */
116 typedef tds_sysdep_int64_type TDS_INT8; /* 64-bit integer */
117 typedef unsigned tds_sysdep_int64_type TDS_UINT8; /* 64-bit unsigned */
118 typedef tds_sysdep_intptr_type TDS_INTPTR;
119 
120 typedef struct tdsnumeric
121 {
122  unsigned char precision;
123  unsigned char scale;
124  unsigned char array[33];
125 } TDS_NUMERIC;
126 
127 typedef struct tdsoldmoney
128 {
129  TDS_INT mnyhigh;
130  TDS_UINT mnylow;
131 } TDS_OLD_MONEY;
132 
133 typedef union tdsmoney
134 {
136  TDS_INT8 mny;
137 } TDS_MONEY;
138 
139 typedef struct tdsmoney4
140 {
141  TDS_INT mny4;
142 } TDS_MONEY4;
143 
144 typedef struct tdsdatetime
145 {
146  TDS_INT dtdays;
147  TDS_INT dttime;
148 } TDS_DATETIME;
149 
150 typedef struct tdsdatetime4
151 {
152  TDS_USMALLINT days;
153  TDS_USMALLINT minutes;
154 } TDS_DATETIME4;
155 
156 typedef struct tdsvarbinary
157 {
158  TDS_SMALLINT len;
159  TDS_CHAR array[256];
160 } TDS_VARBINARY;
161 typedef struct tdsvarchar
162 {
163  TDS_SMALLINT len;
164  TDS_CHAR array[256];
165 } TDS_VARCHAR;
166 
167 typedef struct tdsunique
168 {
169  TDS_UINT Data1;
170  TDS_USMALLINT Data2;
171  TDS_USMALLINT Data3;
172  TDS_UCHAR Data4[8];
173 } TDS_UNIQUE;
174 
176 typedef struct tdsdaterec
177 {
178  TDS_INT year;
179  TDS_INT quarter;
180  TDS_INT month;
181  TDS_INT day;
182  TDS_INT dayofyear;
183  TDS_INT week;
184  TDS_INT weekday;
185  TDS_INT hour;
186  TDS_INT minute;
187  TDS_INT second;
188  TDS_INT millisecond;
189  TDS_INT tzone;
190 } TDSDATEREC;
191 
197 extern const int tds_numeric_bytes_per_prec[];
198 
199 #define TDS_SUCCEED 1
200 #define TDS_FAIL 0
201 #define TDS_NO_MORE_RESULTS 2
202 #define TDS_CANCELLED 3
203 
204 #define TDS_INT_CONTINUE 1
205 #define TDS_INT_CANCEL 2
206 #define TDS_INT_TIMEOUT 3
207 
208 
209 #define TDS_NO_COUNT -1
210 
211 #define TDS_ROW_RESULT 4040
212 #define TDS_PARAM_RESULT 4042
213 #define TDS_STATUS_RESULT 4043
214 #define TDS_MSG_RESULT 4044
215 #define TDS_COMPUTE_RESULT 4045
216 #define TDS_CMD_DONE 4046
217 #define TDS_CMD_SUCCEED 4047
218 #define TDS_CMD_FAIL 4048
219 #define TDS_ROWFMT_RESULT 4049
220 #define TDS_COMPUTEFMT_RESULT 4050
221 #define TDS_DESCRIBE_RESULT 4051
222 #define TDS_DONE_RESULT 4052
223 #define TDS_DONEPROC_RESULT 4053
224 #define TDS_DONEINPROC_RESULT 4054
225 #define TDS_OTHERS_RESULT 4055
226 
227 enum tds_token_results
228 {
229  TDS_TOKEN_RES_OTHERS,
230  TDS_TOKEN_RES_ROWFMT,
231  TDS_TOKEN_RES_COMPUTEFMT,
232  TDS_TOKEN_RES_PARAMFMT,
233  TDS_TOKEN_RES_DONE,
234  TDS_TOKEN_RES_ROW,
235  TDS_TOKEN_RES_COMPUTE,
236  TDS_TOKEN_RES_PROC,
237  TDS_TOKEN_RES_MSG
238 };
239 
240 #define TDS_TOKEN_FLAG(flag) TDS_RETURN_##flag = (1 << (TDS_TOKEN_RES_##flag*2)), TDS_STOPAT_##flag = (2 << (TDS_TOKEN_RES_##flag*2))
241 
242 enum tds_token_flags
243 {
244  TDS_HANDLE_ALL = 0,
245  TDS_TOKEN_FLAG(OTHERS),
246  TDS_TOKEN_FLAG(ROWFMT),
247  TDS_TOKEN_FLAG(COMPUTEFMT),
248  TDS_TOKEN_FLAG(PARAMFMT),
249  TDS_TOKEN_FLAG(DONE),
250  TDS_TOKEN_FLAG(ROW),
251  TDS_TOKEN_FLAG(COMPUTE),
252  TDS_TOKEN_FLAG(PROC),
253  TDS_TOKEN_FLAG(MSG),
254  TDS_TOKEN_RESULTS = TDS_RETURN_ROWFMT|TDS_RETURN_COMPUTEFMT|TDS_RETURN_DONE|TDS_STOPAT_ROW|TDS_STOPAT_COMPUTE|TDS_RETURN_PROC,
255  TDS_TOKEN_TRAILING = TDS_STOPAT_ROWFMT|TDS_STOPAT_COMPUTEFMT|TDS_STOPAT_ROW|TDS_STOPAT_COMPUTE|TDS_STOPAT_MSG|TDS_STOPAT_OTHERS
256 };
257 
262 {
265  , TDS_DONE_ERROR = 0x02
266  , TDS_DONE_INXACT = 0x04
267  , TDS_DONE_PROC = 0x08
268  , TDS_DONE_COUNT = 0x10
270  , TDS_DONE_EVENT = 0x40 /* part of an event notification. */
271  , TDS_DONE_SRVERROR = 0x100
273  /* after the above flags, a TDS_DONE packet has a field describing the state of the transaction */
274  , TDS_DONE_NO_TRAN = 0 /* No transaction in effect */
275  , TDS_DONE_TRAN_SUCCEED = 1 /* Transaction completed successfully */
276  , TDS_DONE_TRAN_PROGRESS= 2 /* Transaction in progress */
277  , TDS_DONE_STMT_ABORT = 3 /* A statement aborted */
278  , TDS_DONE_TRAN_ABORT = 4 /* Transaction aborted */
279 };
280 
281 
282 /*
283  * TDSERRNO is emitted by libtds to the client library's error handler
284  * (which may in turn call the client's error handler).
285  * These match the db-lib msgno, because the same values have the same meaning
286  * in db-lib and ODBC. ct-lib maps them to ct-lib numbers (todo).
287  */
288 typedef enum { TDSEOK = TDS_SUCCEED,
289  TDSEVERDOWN = 100,
290  TDSEICONVIU = 2400,
291  TDSEICONVAVAIL = 2401,
292  TDSEICONVO = 2402,
293  TDSEICONVI = 2403,
294  TDSEICONV2BIG = 2404,
295  TDSEPORTINSTANCE = 2500,
296  TDSESYNC = 20001,
297  TDSEFCON = 20002,
298  TDSETIME = 20003,
299  TDSEREAD = 20004,
300  TDSEWRIT = 20006,
301  TDSESOCK = 20008,
302  TDSECONN = 20009,
303  TDSEMEM = 20010,
304  TDSEINTF = 20012, /* Server name not found in interface file */
305  TDSEUHST = 20013, /* Unknown host machine name. */
306  TDSEPWD = 20014,
307  TDSESEOF = 20017,
308  TDSERPND = 20019,
309  TDSEBTOK = 20020,
310  TDSEOOB = 20022,
311  TDSECLOS = 20056,
312  TDSEUSCT = 20058,
313  TDSEUTDS = 20146,
314  TDSEEUNR = 20185,
315  TDSECAP = 20203,
316  TDSENEG = 20210,
317  TDSEUMSG = 20212,
318  TDSECAPTYP = 20213,
319  TDSEBPROBADTYP = 20250,
320  TDSECLOSEIN = 20292
321 } TDSERRNO;
322 
323 #define TDS5_PARAMFMT2_TOKEN 32 /* 0x20 */
324 #define TDS_LANGUAGE_TOKEN 33 /* 0x21 TDS 5.0 only */
325 #define TDS_ORDERBY2_TOKEN 34 /* 0x22 */
326 #define TDS_ROWFMT2_TOKEN 97 /* 0x61 TDS 5.0 only */
327 #define TDS_LOGOUT_TOKEN 113 /* 0x71 TDS 5.0 only? ct_close() */
328 #define TDS_RETURNSTATUS_TOKEN 121 /* 0x79 */
329 #define TDS_PROCID_TOKEN 124 /* 0x7C TDS 4.2 only - TDS_PROCID */
330 #define TDS7_RESULT_TOKEN 129 /* 0x81 TDS 7.0 only */
331 #define TDS7_COMPUTE_RESULT_TOKEN 136 /* 0x88 TDS 7.0 only */
332 #define TDS_COLNAME_TOKEN 160 /* 0xA0 TDS 4.2 only */
333 #define TDS_COLFMT_TOKEN 161 /* 0xA1 TDS 4.2 only - TDS_COLFMT */
334 #define TDS_DYNAMIC2_TOKEN 163 /* 0xA3 */
335 #define TDS_TABNAME_TOKEN 164 /* 0xA4 */
336 #define TDS_COLINFO_TOKEN 165 /* 0xA5 */
337 #define TDS_OPTIONCMD_TOKEN 166 /* 0xA6 */
338 #define TDS_COMPUTE_NAMES_TOKEN 167 /* 0xA7 */
339 #define TDS_COMPUTE_RESULT_TOKEN 168 /* 0xA8 */
340 #define TDS_ORDERBY_TOKEN 169 /* 0xA9 TDS_ORDER */
341 #define TDS_ERROR_TOKEN 170 /* 0xAA */
342 #define TDS_INFO_TOKEN 171 /* 0xAB */
343 #define TDS_PARAM_TOKEN 172 /* 0xAC RETURNVALUE? */
344 #define TDS_LOGINACK_TOKEN 173 /* 0xAD */
345 #define TDS_CONTROL_TOKEN 174 /* 0xAE TDS_CONTROL */
346 #define TDS_ROW_TOKEN 209 /* 0xD1 */
347 #define TDS_NBC_ROW_TOKEN 210 /* 0xD2 as of TDS 7.3.B */ /* not implemented */
348 #define TDS_CMP_ROW_TOKEN 211 /* 0xD3 */
349 #define TDS5_PARAMS_TOKEN 215 /* 0xD7 TDS 5.0 only */
350 #define TDS_CAPABILITY_TOKEN 226 /* 0xE2 */
351 #define TDS_ENVCHANGE_TOKEN 227 /* 0xE3 */
352 #define TDS_EED_TOKEN 229 /* 0xE5 */
353 #define TDS_DBRPC_TOKEN 230 /* 0xE6 */
354 #define TDS5_DYNAMIC_TOKEN 231 /* 0xE7 TDS 5.0 only */
355 #define TDS5_PARAMFMT_TOKEN 236 /* 0xEC TDS 5.0 only */
356 #define TDS_AUTH_TOKEN 237 /* 0xED TDS 7.0 only */
357 #define TDS_RESULT_TOKEN 238 /* 0xEE */
358 #define TDS_DONE_TOKEN 253 /* 0xFD TDS_DONE */
359 #define TDS_DONEPROC_TOKEN 254 /* 0xFE TDS_DONEPROC */
360 #define TDS_DONEINPROC_TOKEN 255 /* 0xFF TDS_DONEINPROC */
361 
362 /* CURSOR support: TDS 5.0 only*/
363 #define TDS_CURCLOSE_TOKEN 128 /* 0x80 TDS 5.0 only */
364 #define TDS_CURDELETE_TOKEN 129 /* 0x81 TDS 5.0 only */
365 #define TDS_CURFETCH_TOKEN 130 /* 0x82 TDS 5.0 only */
366 #define TDS_CURINFO_TOKEN 131 /* 0x83 TDS 5.0 only */
367 #define TDS_CUROPEN_TOKEN 132 /* 0x84 TDS 5.0 only */
368 #define TDS_CURDECLARE_TOKEN 134 /* 0x86 TDS 5.0 only */
369 
370 enum {
371  TDS_CUR_ISTAT_UNUSED = 0x00,
372  TDS_CUR_ISTAT_DECLARED = 0x01,
373  TDS_CUR_ISTAT_OPEN = 0x02,
374  TDS_CUR_ISTAT_CLOSED = 0x04,
375  TDS_CUR_ISTAT_RDONLY = 0x08,
376  TDS_CUR_ISTAT_UPDATABLE = 0x10,
377  TDS_CUR_ISTAT_ROWCNT = 0x20,
378  TDS_CUR_ISTAT_DEALLOC = 0x40
379 };
380 
381 /* environment type field */
382 #define TDS_ENV_DATABASE 1
383 #define TDS_ENV_LANG 2
384 #define TDS_ENV_CHARSET 3
385 #define TDS_ENV_PACKSIZE 4
386 #define TDS_ENV_LCID 5
387 #define TDS_ENV_SQLCOLLATION 7
388 #define TDS_ENV_BEGINTRANS 8
389 #define TDS_ENV_COMMITTRANS 9
390 #define TDS_ENV_ROLLBACKTRANS 10
391 
392 /* string types */
393 #define TDS_NULLTERM -9
394 
395 /* Microsoft internal stored procedure id's */
396 
397 #define TDS_SP_CURSOR 1
398 #define TDS_SP_CURSOROPEN 2
399 #define TDS_SP_CURSORPREPARE 3
400 #define TDS_SP_CURSOREXECUTE 4
401 #define TDS_SP_CURSORPREPEXEC 5
402 #define TDS_SP_CURSORUNPREPARE 6
403 #define TDS_SP_CURSORFETCH 7
404 #define TDS_SP_CURSOROPTION 8
405 #define TDS_SP_CURSORCLOSE 9
406 #define TDS_SP_EXECUTESQL 10
407 #define TDS_SP_PREPARE 11
408 #define TDS_SP_EXECUTE 12
409 #define TDS_SP_PREPEXEC 13
410 #define TDS_SP_PREPEXECRPC 14
411 #define TDS_SP_UNPREPARE 15
412 /*
413  * <rant> Sybase does an awful job of this stuff, non null ints of size 1 2
414  * and 4 have there own codes but nullable ints are lumped into INTN
415  * sheesh! </rant>
416  */
417 typedef enum
418 {
419  SYBCHAR = 47, /* 0x2F */
420 #define SYBCHAR SYBCHAR
421  SYBVARCHAR = 39, /* 0x27 */
422 #define SYBVARCHAR SYBVARCHAR
423  SYBINTN = 38, /* 0x26 */
424 #define SYBINTN SYBINTN
425  SYBINT1 = 48, /* 0x30 */
426 #define SYBINT1 SYBINT1
427  SYBINT2 = 52, /* 0x34 */
428 #define SYBINT2 SYBINT2
429  SYBINT4 = 56, /* 0x38 */
430 #define SYBINT4 SYBINT4
431  SYBFLT8 = 62, /* 0x3E */
432 #define SYBFLT8 SYBFLT8
433  SYBDATETIME = 61, /* 0x3D */
434 #define SYBDATETIME SYBDATETIME
435  SYBBIT = 50, /* 0x32 */
436 #define SYBBIT SYBBIT
437  SYBTEXT = 35, /* 0x23 */
438 #define SYBTEXT SYBTEXT
439  SYBNTEXT = 99, /* 0x63 */
440 #define SYBNTEXT SYBNTEXT
441  SYBIMAGE = 34, /* 0x22 */
442 #define SYBIMAGE SYBIMAGE
443  SYBMONEY4 = 122, /* 0x7A */
444 #define SYBMONEY4 SYBMONEY4
445  SYBMONEY = 60, /* 0x3C */
446 #define SYBMONEY SYBMONEY
447  SYBDATETIME4 = 58, /* 0x3A */
448 #define SYBDATETIME4 SYBDATETIME4
449  SYBREAL = 59, /* 0x3B */
450 #define SYBREAL SYBREAL
451  SYBBINARY = 45, /* 0x2D */
452 #define SYBBINARY SYBBINARY
453  SYBVOID = 31, /* 0x1F */
454 #define SYBVOID SYBVOID
455  SYBVARBINARY = 37, /* 0x25 */
456 #define SYBVARBINARY SYBVARBINARY
457  SYBBITN = 104, /* 0x68 */
458 #define SYBBITN SYBBITN
459  SYBNUMERIC = 108, /* 0x6C */
460 #define SYBNUMERIC SYBNUMERIC
461  SYBDECIMAL = 106, /* 0x6A */
462 #define SYBDECIMAL SYBDECIMAL
463  SYBFLTN = 109, /* 0x6D */
464 #define SYBFLTN SYBFLTN
465  SYBMONEYN = 110, /* 0x6E */
466 #define SYBMONEYN SYBMONEYN
467  SYBDATETIMN = 111, /* 0x6F */
468 #define SYBDATETIMN SYBDATETIMN
469 
470 /*
471  * MS only types
472  */
473  SYBNVARCHAR = 103, /* 0x67 */
474 #define SYBNVARCHAR SYBNVARCHAR
475  SYBINT8 = 127, /* 0x7F */
476 #define SYBINT8 SYBINT8
477  XSYBCHAR = 175, /* 0xAF */
478 #define XSYBCHAR XSYBCHAR
479  XSYBVARCHAR = 167, /* 0xA7 */
480 #define XSYBVARCHAR XSYBVARCHAR
481  XSYBNVARCHAR = 231, /* 0xE7 */
482 #define XSYBNVARCHAR XSYBNVARCHAR
483  XSYBNCHAR = 239, /* 0xEF */
484 #define XSYBNCHAR XSYBNCHAR
485  XSYBVARBINARY = 165, /* 0xA5 */
486 #define XSYBVARBINARY XSYBVARBINARY
487  XSYBBINARY = 173, /* 0xAD */
488 #define XSYBBINARY XSYBBINARY
489  SYBUNIQUE = 36, /* 0x24 */
490 #define SYBUNIQUE SYBUNIQUE
491  SYBVARIANT = 98, /* 0x62 */
492 #define SYBVARIANT SYBVARIANT
493  SYBMSUDT = 240, /* 0xF0 */
494 #define SYBMSUDT SYBMSUDT
495  SYBMSXML = 241, /* 0xF1 */
496 #define SYBMSXML SYBMSXML
497 
498 /*
499  * Sybase only types
500  */
501  SYBLONGBINARY = 225, /* 0xE1 */
502 #define SYBLONGBINARY SYBLONGBINARY
503  SYBUINT1 = 64, /* 0x40 */
504 #define SYBUINT1 SYBUINT1
505  SYBUINT2 = 65, /* 0x41 */
506 #define SYBUINT2 SYBUINT2
507  SYBUINT4 = 66, /* 0x42 */
508 #define SYBUINT4 SYBUINT4
509  SYBUINT8 = 67, /* 0x43 */
510 #define SYBUINT8 SYBUINT8
511  SYBBLOB = 36, /* 0x24 */
512 #define SYBBLOB SYBBLOB
513  SYBBOUNDARY = 104, /* 0x68 */
514 #define SYBBOUNDARY SYBBOUNDARY
515  SYBDATE = 49, /* 0x31 */
516 #define SYBDATE SYBDATE
517  SYBDATEN = 123, /* 0x7B */
518 #define SYBDATEN SYBDATEN
519  SYB5INT8 = 191, /* 0xBF */
520 #define SYB5INT8 SYB5INT8
521  SYBINTERVAL = 46, /* 0x2E */
522 #define SYBINTERVAL SYBINTERVAL
523  SYBLONGCHAR = 175, /* 0xAF */
524 #define SYBLONGCHAR SYBLONGCHAR
525  SYBSENSITIVITY = 103, /* 0x67 */
526 #define SYBSENSITIVITY SYBSENSITIVITY
527  SYBSINT1 = 176, /* 0xB0 */
528 #define SYBSINT1 SYBSINT1
529  SYBTIME = 51, /* 0x33 */
530 #define SYBTIME SYBTIME
531  SYBTIMEN = 147, /* 0x93 */
532 #define SYBTIMEN SYBTIMEN
533  SYBUINTN = 68, /* 0x44 */
534 #define SYBUINTN SYBUINTN
535  SYBUNITEXT = 174, /* 0xAE */
536 #define SYBUNITEXT SYBUNITEXT
537  SYBXML = 163, /* 0xA3 */
538 #define SYBXML SYBXML
539 
540 } TDS_SERVER_TYPE;
541 
542 
543 typedef enum
544 {
545  USER_UNICHAR_TYPE = 34, /* 0x22 */
546  USER_UNIVARCHAR_TYPE = 35 /* 0x23 */
547 } TDS_USER_TYPE;
548 
549 #define SYBAOPCNT 0x4b
550 #define SYBAOPCNTU 0x4c
551 #define SYBAOPSUM 0x4d
552 #define SYBAOPSUMU 0x4e
553 #define SYBAOPAVG 0x4f
554 #define SYBAOPAVGU 0x50
555 #define SYBAOPMIN 0x51
556 #define SYBAOPMAX 0x52
557 
558 /* mssql2k compute operator */
559 #define SYBAOPCNT_BIG 0x09
560 #define SYBAOPSTDEV 0x30
561 #define SYBAOPSTDEVP 0x31
562 #define SYBAOPVAR 0x32
563 #define SYBAOPVARP 0x33
564 #define SYBAOPCHECKSUM_AGG 0x72
565 
566 
570 typedef enum
571 {
572  TDS_OPT_SET = 1 /* Set an option. */
573  , TDS_OPT_DEFAULT = 2 /* Set option to its default value. */
574  , TDS_OPT_LIST = 3 /* Request current setting of a specific option. */
575  , TDS_OPT_INFO = 4 /* Report current setting of a specific option. */
577 
578 typedef enum
579 {
580  TDS_OPT_DATEFIRST = 1 /* 0x01 */
581  , TDS_OPT_TEXTSIZE = 2 /* 0x02 */
582  , TDS_OPT_STAT_TIME = 3 /* 0x03 */
583  , TDS_OPT_STAT_IO = 4 /* 0x04 */
584  , TDS_OPT_ROWCOUNT = 5 /* 0x05 */
585  , TDS_OPT_NATLANG = 6 /* 0x06 */
586  , TDS_OPT_DATEFORMAT = 7 /* 0x07 */
587  , TDS_OPT_ISOLATION = 8 /* 0x08 */
588  , TDS_OPT_AUTHON = 9 /* 0x09 */
589  , TDS_OPT_CHARSET = 10 /* 0x0a */
590  , TDS_OPT_SHOWPLAN = 13 /* 0x0d */
591  , TDS_OPT_NOEXEC = 14 /* 0x0e */
592  , TDS_OPT_ARITHIGNOREON = 15 /* 0x0f */
593  , TDS_OPT_ARITHABORTON = 17 /* 0x11 */
594  , TDS_OPT_PARSEONLY = 18 /* 0x12 */
595  , TDS_OPT_GETDATA = 20 /* 0x14 */
596  , TDS_OPT_NOCOUNT = 21 /* 0x15 */
597  , TDS_OPT_FORCEPLAN = 23 /* 0x17 */
598  , TDS_OPT_FORMATONLY = 24 /* 0x18 */
599  , TDS_OPT_CHAINXACTS = 25 /* 0x19 */
600  , TDS_OPT_CURCLOSEONXACT = 26 /* 0x1a */
601  , TDS_OPT_FIPSFLAG = 27 /* 0x1b */
602  , TDS_OPT_RESTREES = 28 /* 0x1c */
603  , TDS_OPT_IDENTITYON = 29 /* 0x1d */
604  , TDS_OPT_CURREAD = 30 /* 0x1e */
605  , TDS_OPT_CURWRITE = 31 /* 0x1f */
606  , TDS_OPT_IDENTITYOFF = 32 /* 0x20 */
607  , TDS_OPT_AUTHOFF = 33 /* 0x21 */
608  , TDS_OPT_ANSINULL = 34 /* 0x22 */
609  , TDS_OPT_QUOTED_IDENT = 35 /* 0x23 */
610  , TDS_OPT_ARITHIGNOREOFF = 36 /* 0x24 */
611  , TDS_OPT_ARITHABORTOFF = 37 /* 0x25 */
612  , TDS_OPT_TRUNCABORT = 38 /* 0x26 */
613 } TDS_OPTION;
614 
615 typedef union tds_option_arg
616 {
617  TDS_TINYINT ti;
618  TDS_INT i;
619  TDS_CHAR *c;
621 
622 enum {
623  TDS_OPT_ARITHOVERFLOW = 0x01,
624  TDS_OPT_NUMERICTRUNC = 0x02
625 };
626 
627 enum TDS_OPT_DATEFIRST_CHOICE
628 {
629  TDS_OPT_MONDAY = 1, TDS_OPT_TUESDAY = 2, TDS_OPT_WEDNESDAY = 3, TDS_OPT_THURSDAY = 4, TDS_OPT_FRIDAY = 5, TDS_OPT_SATURDAY =
630  6, TDS_OPT_SUNDAY = 7
631 };
632 
633 enum TDS_OPT_DATEFORMAT_CHOICE
634 {
635  TDS_OPT_FMTMDY = 1, TDS_OPT_FMTDMY = 2, TDS_OPT_FMTYMD = 3, TDS_OPT_FMTYDM = 4, TDS_OPT_FMTMYD = 5, TDS_OPT_FMTDYM = 6
636 };
637 enum TDS_OPT_ISOLATION_CHOICE
638 {
639  TDS_OPT_LEVEL1 = 1, TDS_OPT_LEVEL3 = 3
640 };
641 
642 typedef enum tds_packet_type
643 {
644  TDS_QUERY = 1,
645  TDS_LOGIN = 2,
646  TDS_RPC = 3,
647  TDS_REPLY = 4,
648  TDS_CANCEL = 6,
649  TDS_BULK = 7,
650  TDS_NORMAL = 15,
651  TDS7_LOGIN = 16,
652  TDS7_AUTH = 17,
653  TDS8_PRELOGIN = 18
654 } TDS_PACKET_TYPE;
655 
656 typedef enum tds_encryption_level {
657  TDS_ENCRYPTION_OFF, TDS_ENCRYPTION_REQUEST, TDS_ENCRYPTION_REQUIRE
658 } TDS_ENCRYPTION_LEVEL;
659 
660 #define TDS_ZERO_FREE(x) do {free((x)); (x) = NULL;} while(0)
661 #define TDS_VECTOR_SIZE(x) (sizeof(x)/sizeof(x[0]))
662 
663 #if defined(__GNUC__) && __GNUC__ >= 3
664 # define TDS_LIKELY(x) __builtin_expect(!!(x), 1)
665 # define TDS_UNLIKELY(x) __builtin_expect(!!(x), 0)
666 #else
667 # define TDS_LIKELY(x) (x)
668 # define TDS_UNLIKELY(x) (x)
669 #endif
670 
671 /*
672  * TODO use system macros for optimization
673  * See mcrypt for reference and linux kernel source for optimization
674  * check if unaligned access and use fast write/read when implemented
675  */
676 #define TDS_BYTE_SWAP16(value) \
677  (((((unsigned short)value)<<8) & 0xFF00) | \
678  ((((unsigned short)value)>>8) & 0x00FF))
679 
680 #define TDS_BYTE_SWAP32(value) \
681  (((((unsigned long)value)<<24) & 0xFF000000) | \
682  ((((unsigned long)value)<< 8) & 0x00FF0000) | \
683  ((((unsigned long)value)>> 8) & 0x0000FF00) | \
684  ((((unsigned long)value)>>24) & 0x000000FF))
685 
686 #define is_end_token(x) (x==TDS_DONE_TOKEN || \
687  x==TDS_DONEPROC_TOKEN || \
688  x==TDS_DONEINPROC_TOKEN)
689 
690 #define is_hard_end_token(x) (x==TDS_DONE_TOKEN || \
691  x==TDS_DONEPROC_TOKEN)
692 
693 #define is_msg_token(x) (x==TDS_INFO_TOKEN || \
694  x==TDS_ERROR_TOKEN || \
695  x==TDS_EED_TOKEN)
696 
697 #define is_result_token(x) (x==TDS_RESULT_TOKEN || \
698  x==TDS_ROWFMT2_TOKEN || \
699  x==TDS7_RESULT_TOKEN || \
700  x==TDS_COLFMT_TOKEN || \
701  x==TDS_COLNAME_TOKEN || \
702  x==TDS_RETURNSTATUS_TOKEN)
703 
704 /* FIXME -- not a complete list */
705 #define is_fixed_type(x) (x==SYBINT1 || \
706  x==SYBINT2 || \
707  x==SYBINT4 || \
708  x==SYBINT8 || \
709  x==SYBREAL || \
710  x==SYBFLT8 || \
711  x==SYBDATETIME || \
712  x==SYBDATETIME4 || \
713  x==SYBBIT || \
714  x==SYBMONEY || \
715  x==SYBMONEY4 || \
716  x==SYBVOID || \
717  x==SYBUNIQUE)
718 #define is_nullable_type(x) ( \
719  x==SYBBITN || \
720  x==SYBINTN || \
721  x==SYBFLTN || \
722  x==SYBMONEYN || \
723  x==SYBDATETIMN || \
724  x==SYBVARCHAR || \
725  x==SYBBINARY || \
726  x==SYBVARBINARY || \
727  x==SYBTEXT || \
728  x==SYBNTEXT || \
729  x==SYBIMAGE)
730 
731 #define is_variable_type(x) ( \
732  (x)==SYBTEXT || \
733  (x)==SYBIMAGE || \
734  (x)==SYBNTEXT || \
735  (x)==SYBCHAR || \
736  (x)==SYBVARCHAR || \
737  (x)==SYBBINARY || \
738  (x)==SYBVARBINARY || \
739  (x)==SYBLONGBINARY || \
740  (x)==XSYBCHAR || \
741  (x)==XSYBVARCHAR || \
742  (x)==XSYBNVARCHAR || \
743  (x)==XSYBNCHAR)
744 
745 #define is_blob_type(x) (x==SYBTEXT || x==SYBIMAGE || x==SYBNTEXT)
746 #define is_blob_col(x) ((x)->column_varint_size > 2)
747 /* large type means it has a two byte size field */
748 /* define is_large_type(x) (x>128) */
749 #define is_numeric_type(x) (x==SYBNUMERIC || x==SYBDECIMAL)
750 #define is_unicode_type(x) (x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT || x==SYBMSXML)
751 #define is_collate_type(x) (x==XSYBVARCHAR || x==XSYBCHAR || x==SYBTEXT || x==XSYBNVARCHAR || x==XSYBNCHAR || x==SYBNTEXT)
752 #define is_ascii_type(x) ( x==XSYBCHAR || x==XSYBVARCHAR || x==SYBTEXT || x==SYBCHAR || x==SYBVARCHAR)
753 #define is_char_type(x) (is_unicode_type(x) || is_ascii_type(x))
754 #define is_similar_type(x, y) ((is_char_type(x) && is_char_type(y)) || ((is_unicode_type(x) && is_unicode_type(y))))
755 
756 
757 #define TDS_MAX_CAPABILITY 22
758 #define MAXPRECISION 77
759 #define TDS_MAX_CONN 4096
760 #define TDS_MAX_DYNID_LEN 30
761 
762 /* defaults to use if no others are found */
763 #define TDS_DEF_SERVER "SYBASE"
764 #define TDS_DEF_BLKSZ 512
765 #define TDS_DEF_CHARSET "iso_1"
766 #define TDS_DEF_LANG "us_english"
767 #if TDS42
768 #define TDS_DEFAULT_VERSION 0x402
769 #define TDS_DEF_PORT 1433
770 #elif TDS46
771 #define TDS_DEFAULT_VERSION 0x406
772 #define TDS_DEF_PORT 4000
773 #elif TDS70
774 #define TDS_DEFAULT_VERSION 0x700
775 #define TDS_DEF_PORT 1433
776 #elif TDS71
777 #define TDS_DEFAULT_VERSION 0x701
778 #define TDS_DEF_PORT 1433
779 #elif TDS72
780 #define TDS_DEFAULT_VERSION 0x702
781 #define TDS_DEF_PORT 1433
782 #else
783 #define TDS_DEFAULT_VERSION 0x500
784 #define TDS_DEF_PORT 4000
785 #endif
786 
787 /* normalized strings from freetds.conf file */
788 #define TDS_STR_VERSION "tds version"
789 #define TDS_STR_BLKSZ "initial block size"
790 #define TDS_STR_SWAPDT "swap broken dates"
791 #define TDS_STR_DUMPFILE "dump file"
792 #define TDS_STR_DEBUGLVL "debug level"
793 #define TDS_STR_DEBUGFLAGS "debug flags"
794 #define TDS_STR_TIMEOUT "timeout"
795 #define TDS_STR_QUERY_TIMEOUT "query timeout"
796 #define TDS_STR_CONNTIMEOUT "connect timeout"
797 #define TDS_STR_HOSTNAME "hostname"
798 #define TDS_STR_HOST "host"
799 #define TDS_STR_PORT "port"
800 #define TDS_STR_TEXTSZ "text size"
801 /* for big endian hosts */
802 #define TDS_STR_EMUL_LE "emulate little endian"
803 #define TDS_STR_CHARSET "charset"
804 #define TDS_STR_CLCHARSET "client charset"
805 #define TDS_STR_LANGUAGE "language"
806 #define TDS_STR_APPENDMODE "dump file append"
807 #define TDS_STR_DATEFMT "date format"
808 #define TDS_STR_INSTANCE "instance"
809 #define TDS_STR_ASA_DATABASE "asa database"
810 #define TDS_STR_ENCRYPTION "encryption"
811 #define TDS_STR_USENTLMV2 "use ntlmv2"
812 /* conf values */
813 #define TDS_STR_ENCRYPTION_OFF "off"
814 #define TDS_STR_ENCRYPTION_REQUEST "request"
815 #define TDS_STR_ENCRYPTION_REQUIRE "require"
816 /* Defines to enable optional GSSAPI delegation */
817 #define TDS_GSSAPI_DELEGATION "enable gssapi delegation"
818 /* Kerberos realm name */
819 #define TDS_STR_REALM "realm"
820 
821 
822 /* TODO do a better check for alignment than this */
823 typedef union
824 {
825  void *p;
826  int i;
828 
829 #define TDS_ALIGN_SIZE sizeof(tds_align_struct)
830 
831 #define TDS_MAX_LOGIN_STR_SZ 30
832 typedef struct tds_login
833 {
834  DSTR server_name;
835  int port;
836  TDS_USMALLINT tds_version; /* TDS version */
837  int block_size;
838  DSTR language; /* e.g. us-english */
839  DSTR server_charset; /* e.g. iso_1 */
840  TDS_INT connect_timeout;
841  DSTR client_host_name;
842  DSTR app_name;
843  DSTR user_name;
844  DSTR password;
845 
846  DSTR library; /* Ct-Library, DB-Library, TDS-Library or ODBC */
847  TDS_TINYINT encryption_level;
848 
849  TDS_INT query_timeout;
850  unsigned char capabilities[TDS_MAX_CAPABILITY];
851  DSTR client_charset;
852  DSTR database;
853  unsigned int bulk_copy:1;
854  unsigned int suppress_language:1;
855 } TDSLOGIN;
856 
857 typedef struct tds_connection
858 {
859  /* first part of structure is the same of login one */
861  int port;
862  TDS_USMALLINT tds_version;
863  int block_size;
864  DSTR language;
866  TDS_INT connect_timeout;
867  DSTR client_host_name;
868  DSTR server_host_name;
870  DSTR app_name;
873  DSTR library;
874  TDS_TINYINT encryption_level;
875 
876  TDS_INT query_timeout;
877  unsigned char capabilities[TDS_MAX_CAPABILITY];
878  unsigned char option_flag2;
879  DSTR client_charset;
880 
882  DSTR instance_name;
883  DSTR database;
884  DSTR dump_file;
885  int debug_flags;
886  int text_size;
887  unsigned int broken_dates:1;
888  unsigned int emul_little_endian:1;
889  unsigned int bulk_copy:1;
890  unsigned int suppress_language:1;
891  unsigned int gssapi_use_delegation:1;
892  unsigned int use_ntlmv2:1;
893 } TDSCONNECTION;
894 
895 typedef struct tds_locale
896 {
897  char *language;
898  char *server_charset;
899  char *date_fmt;
900 } TDSLOCALE;
901 
906 typedef struct tds_blob
907 {
908  TDS_CHAR *textvalue;
909  TDS_CHAR textptr[16];
910  TDS_CHAR timestamp[8];
911 } TDSBLOB;
912 
916 typedef struct tds_variant
917 {
918  /* this MUST have same position and place of textvalue in tds_blob */
919  TDS_CHAR *data;
920  TDS_INT size;
921  TDS_INT data_len;
922  TDS_UCHAR type;
923  TDS_UCHAR collation[5];
924 } TDSVARIANT;
925 
929 typedef struct
930 {
931  TDS_USMALLINT locale_id; /* master..syslanguages.lcid */
932  TDS_USMALLINT flags;
933  TDS_UCHAR charset_id; /* or zero */
935 
936 /* SF stands for "sort flag" */
937 #define TDS_SF_BIN (TDS_USMALLINT) 0x100
938 #define TDS_SF_WIDTH_INSENSITIVE (TDS_USMALLINT) 0x080
939 #define TDS_SF_KATATYPE_INSENSITIVE (TDS_USMALLINT) 0x040
940 #define TDS_SF_ACCENT_SENSITIVE (TDS_USMALLINT) 0x020
941 #define TDS_SF_CASE_INSENSITIVE (TDS_USMALLINT) 0x010
942 
943 /* UT stands for user type */
944 #define TDS_UT_TIMESTAMP 80
945 
946 
951 typedef struct tds_encoding
952 {
953  const char *name;
954  unsigned char min_bytes_per_char;
955  unsigned char max_bytes_per_char;
956  unsigned char canonic;
957 } TDS_ENCODING;
958 
959 typedef struct tds_bcpcoldata
960 {
961  TDS_UCHAR *data;
962  TDS_INT datalen;
963  TDS_INT is_null;
964 } BCPCOLDATA;
965 
966 
967 enum
968 { TDS_SYSNAME_SIZE = 512 };
969 
973 typedef struct tds_column
974 {
975  TDS_SMALLINT column_type;
980  TDS_INT column_usertype;
981  TDS_INT column_flags;
982 
983  TDS_INT column_size;
985  TDS_TINYINT column_varint_size;
987  TDS_TINYINT column_prec;
988  TDS_TINYINT column_scale;
990  TDS_SMALLINT column_namelen;
991  TDS_SMALLINT table_namelen;
992  struct
993  {
994  TDS_SMALLINT column_type;
995  TDS_INT column_size;
996  } on_server;
997 
1000  TDS_CHAR table_name[TDS_SYSNAME_SIZE];
1001  TDS_CHAR column_name[TDS_SYSNAME_SIZE];
1002  char * table_column_name;
1003 
1004  unsigned char *column_data;
1005  void (*column_data_free)(struct tds_column *column);
1006  unsigned int column_nullable:1;
1007  unsigned int column_writeable:1;
1008  unsigned int column_identity:1;
1009  unsigned int column_key:1;
1010  unsigned int column_hidden:1;
1011  unsigned int column_output:1;
1012  unsigned int column_timestamp:1;
1013  TDS_UCHAR column_collation[5];
1014 
1015  /* additional fields flags for compute results */
1016  TDS_TINYINT column_operator;
1017  TDS_SMALLINT column_operand;
1018 
1019  /* FIXME this is data related, not column */
1022 
1023  /* related to binding or info stored by client libraries */
1024  /* FIXME find a best place to store these data, some are unused */
1025  TDS_SMALLINT column_bindtype;
1026  TDS_SMALLINT column_bindfmt;
1027  TDS_UINT column_bindlen;
1028  TDS_SMALLINT *column_nullbind;
1029  TDS_CHAR *column_varaddr;
1030  TDS_INT *column_lenbind;
1031  TDS_INT column_textpos;
1032  TDS_INT column_text_sqlgetdatapos;
1033  TDS_CHAR column_text_sqlputdatainfo;
1034 
1035  BCPCOLDATA *bcp_column_data;
1045  TDS_INT bcp_term_len;
1046  TDS_CHAR *bcp_terminator;
1047 } TDSCOLUMN;
1048 
1049 
1051 typedef struct tds_result_info
1052 {
1053  /* TODO those fields can became a struct */
1054  TDS_SMALLINT num_cols;
1055  TDSCOLUMN **columns;
1056  TDS_INT row_size;
1057  TDS_INT ref_count;
1058  unsigned char *current_row;
1059  void (*row_free)(struct tds_result_info* result, unsigned char *row);
1060 
1061  TDS_SMALLINT rows_exist;
1062  /* TODO remove ?? used only in dblib */
1063  TDS_INT row_count;
1064  /* TODO remove ?? used only in dblib */
1065  TDS_TINYINT more_results;
1066  TDS_SMALLINT computeid;
1067  TDS_SMALLINT *bycolumns;
1068  TDS_SMALLINT by_cols;
1069 } TDSRESULTINFO;
1070 
1072 typedef enum _TDS_STATE
1073 {
1079 } TDS_STATE;
1080 
1081 #define TDS_DBG_LOGIN __FILE__, ((__LINE__ << 4) | 11)
1082 #define TDS_DBG_HEADER __FILE__, ((__LINE__ << 4) | 10)
1083 #define TDS_DBG_FUNC __FILE__, ((__LINE__ << 4) | 7)
1084 #define TDS_DBG_INFO2 __FILE__, ((__LINE__ << 4) | 6)
1085 #define TDS_DBG_INFO1 __FILE__, ((__LINE__ << 4) | 5)
1086 #define TDS_DBG_NETWORK __FILE__, ((__LINE__ << 4) | 4)
1087 #define TDS_DBG_WARN __FILE__, ((__LINE__ << 4) | 3)
1088 #define TDS_DBG_ERROR __FILE__, ((__LINE__ << 4) | 2)
1089 #define TDS_DBG_SEVERE __FILE__, ((__LINE__ << 4) | 1)
1090 
1091 #define TDS_DBGFLAG_FUNC 0x80
1092 #define TDS_DBGFLAG_INFO2 0x40
1093 #define TDS_DBGFLAG_INFO1 0x20
1094 #define TDS_DBGFLAG_NETWORK 0x10
1095 #define TDS_DBGFLAG_WARN 0x08
1096 #define TDS_DBGFLAG_ERROR 0x04
1097 #define TDS_DBGFLAG_SEVERE 0x02
1098 #define TDS_DBGFLAG_ALL 0xfff
1099 #define TDS_DBGFLAG_LOGIN 0x0800
1100 #define TDS_DBGFLAG_HEADER 0x0400
1101 #define TDS_DBGFLAG_PID 0x1000
1102 #define TDS_DBGFLAG_TIME 0x2000
1103 #define TDS_DBGFLAG_SOURCE 0x4000
1104 #define TDS_DBGFLAG_THREAD 0x8000
1105 
1106 #if 0
1107 
1112 enum TDS_DBG_LOG_STATE
1113 {
1114  TDS_DBG_LOGIN = (1 << 0)
1116  , TDS_DBG_API = (1 << 1)
1117  , TDS_DBG_ASYNC = (1 << 2)
1118  , TDS_DBG_DIAG = (1 << 3)
1119  , TDS_DBG_error = (1 << 4)
1120  /* TODO: ^^^^^ make upper case when old #defines (above) are removed */
1121  /* Log FreeTDS runtime/logic error occurs. */
1122  , TDS_DBG_PACKET = (1 << 5)
1123  , TDS_DBG_LIBTDS = (1 << 6)
1124  , TDS_DBG_CONFIG = (1 << 7)
1125  , TDS_DBG_DEFAULT = 0xFE
1126 };
1127 #endif
1128 
1129 typedef struct tds_result_info TDSCOMPUTEINFO;
1130 
1131 typedef TDSRESULTINFO TDSPARAMINFO;
1132 
1133 typedef struct tds_message
1134 {
1135  TDS_CHAR *server;
1136  TDS_CHAR *message;
1137  TDS_CHAR *proc_name;
1138  TDS_CHAR *sql_state;
1139  TDS_UINT msgno;
1140  TDS_INT line_number;
1141  /* -1 .. 255 */
1142  TDS_SMALLINT state;
1143  TDS_TINYINT priv_msg_type;
1144  TDS_TINYINT severity;
1145  /* for library-generated errors */
1146  int oserr;
1147 } TDSMESSAGE;
1148 
1149 typedef struct tds_upd_col
1150 {
1151  struct tds_upd_col *next;
1152  TDS_INT colnamelength;
1153  char * columnname;
1154 } TDSUPDCOL;
1155 
1156 typedef enum {
1157  TDS_CURSOR_STATE_UNACTIONED = 0 /* initial value */
1158  , TDS_CURSOR_STATE_REQUESTED = 1 /* called by ct_cursor */
1159  , TDS_CURSOR_STATE_SENT = 2 /* sent to server */
1160  , TDS_CURSOR_STATE_ACTIONED = 3 /* acknowledged by server */
1161 } TDS_CURSOR_STATE;
1162 
1163 typedef struct tds_cursor_status
1164 {
1165  TDS_CURSOR_STATE declare;
1166  TDS_CURSOR_STATE cursor_row;
1167  TDS_CURSOR_STATE open;
1168  TDS_CURSOR_STATE fetch;
1169  TDS_CURSOR_STATE close;
1170  TDS_CURSOR_STATE dealloc;
1172 
1173 typedef enum tds_cursor_operation
1174 {
1175  TDS_CURSOR_POSITION = 0,
1176  TDS_CURSOR_UPDATE = 1,
1177  TDS_CURSOR_DELETE = 2,
1178  TDS_CURSOR_INSERT = 4
1179 } TDS_CURSOR_OPERATION;
1180 
1181 typedef enum tds_cursor_fetch
1182 {
1183  TDS_CURSOR_FETCH_NEXT = 1,
1184  TDS_CURSOR_FETCH_PREV,
1185  TDS_CURSOR_FETCH_FIRST,
1186  TDS_CURSOR_FETCH_LAST,
1187  TDS_CURSOR_FETCH_ABSOLUTE,
1188  TDS_CURSOR_FETCH_RELATIVE
1189 } TDS_CURSOR_FETCH;
1190 
1194 typedef struct tds_cursor
1195 {
1196  struct tds_cursor *next;
1197  TDS_INT ref_count;
1198  TDS_TINYINT cursor_name_len;
1199  char *cursor_name;
1200  TDS_INT cursor_id;
1201  TDS_TINYINT options;
1202  TDS_TINYINT hasargs;
1203  TDS_USMALLINT query_len;
1204  char *query;
1205  /* TODO for updatable columns */
1206  /* TDS_TINYINT number_upd_cols; */
1207  /* TDSUPDCOL *cur_col_list; */
1208  TDS_INT cursor_rows;
1209  /* TDSPARAMINFO *params; */
1211  TDS_SMALLINT srv_status;
1212  TDSRESULTINFO *res_info;
1213  TDS_INT type, concurrency;
1214 } TDSCURSOR;
1215 
1219 typedef struct tds_env
1220 {
1221  int block_size;
1222  char *language;
1223  char *charset;
1224  char *database;
1225 } TDSENV;
1226 
1230 typedef struct tds_dynamic
1231 {
1232  struct tds_dynamic *next;
1238  char id[30];
1239  /* int dyn_state; */ /* TODO use it */
1241  TDS_INT num_id;
1258  char *query;
1259 } TDSDYNAMIC;
1260 
1261 typedef enum {
1262  TDS_MULTIPLE_QUERY,
1263  TDS_MULTIPLE_EXECUTE,
1264  TDS_MULTIPLE_RPC
1265 } TDS_MULTIPLE_TYPE;
1266 
1267 typedef struct tds_multiple
1268 {
1269  TDS_MULTIPLE_TYPE type;
1270  unsigned int flags;
1271 } TDSMULTIPLE;
1272 
1273 /* forward declaration */
1274 typedef struct tds_context TDSCONTEXT;
1275 typedef int (*err_handler_t) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
1276 
1278 {
1279  TDSLOCALE *locale;
1280  void *parent;
1281  /* handlers */
1282  int (*msg_handler) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
1283  int (*err_handler) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
1284  int (*int_handler) (void *);
1285 };
1286 
1287 enum TDS_ICONV_ENTRY
1288 {
1289  client2ucs2
1290  , client2server_chardata
1291  , iso2server_metadata
1292  , initial_char_conv_count /* keep last */
1293 };
1294 
1295 typedef struct tds_authentication
1296 {
1297  TDS_UCHAR *packet;
1298  int packet_len;
1299  int (*free)(TDSSOCKET * tds, struct tds_authentication * auth);
1300  int (*handle_next)(TDSSOCKET * tds, struct tds_authentication * auth, size_t len);
1302 
1307 {
1308  TDS_SYS_SOCKET s;
1310  TDS_USMALLINT tds_version;
1311  TDS_UINT product_version;
1312  char *product_name;
1313 
1314  unsigned char capabilities[TDS_MAX_CAPABILITY];
1315  unsigned int broken_dates:1;
1316  unsigned int emul_little_endian:1;
1317  unsigned int use_iconv:1;
1318  unsigned int tds71rev1:1;
1319 
1320  unsigned char *in_buf;
1321  unsigned char *out_buf;
1322  unsigned int in_buf_max;
1323  unsigned in_pos;
1324  unsigned out_pos;
1325  unsigned in_len;
1327  unsigned char in_flag;
1328  unsigned char out_flag;
1329  void *parent;
1330 
1337  TDSRESULTINFO *res_info;
1338  TDS_INT num_comp_info;
1339  TDSCOMPUTEINFO **comp_info;
1340  TDSPARAMINFO *param_info;
1343  TDS_TINYINT has_status;
1344  TDS_INT ret_status;
1345  TDS_STATE state;
1346 
1347  volatile
1348  unsigned char in_cancel;
1350  TDS_INT8 rows_affected;
1351  TDS_INT query_timeout;
1352  TDSENV env;
1353 
1357  const TDSCONTEXT *tds_ctx;
1358  int char_conv_count;
1359  TDSICONV **char_convs;
1360 
1363  int spid;
1364  TDS_UCHAR collation[5];
1365  TDS_UCHAR tds9_transaction[8];
1366  void (*env_chg_func) (TDSSOCKET * tds, int type, char *oldval, char *newval);
1367  int internal_sp_called;
1368 
1369  void *tls_session;
1370  void *tls_credentials;
1371  TDSAUTHENTICATION *authentication;
1372  int option_value;
1373 };
1374 
1375 int tds_init_write_buf(TDSSOCKET * tds);
1376 void tds_free_result_info(TDSRESULTINFO * info);
1377 void tds_free_socket(TDSSOCKET * tds);
1378 void tds_free_connection(TDSCONNECTION * connection);
1379 void tds_free_all_results(TDSSOCKET * tds);
1380 void tds_free_results(TDSRESULTINFO * res_info);
1381 void tds_free_param_results(TDSPARAMINFO * param_info);
1382 void tds_free_param_result(TDSPARAMINFO * param_info);
1383 void tds_free_msg(TDSMESSAGE * message);
1384 void tds_cursor_deallocated(TDSSOCKET *tds, TDSCURSOR *cursor);
1385 void tds_release_cursor(TDSSOCKET *tds, TDSCURSOR *cursor);
1386 void tds_free_bcp_column_data(BCPCOLDATA * coldata);
1387 
1388 int tds_put_n(TDSSOCKET * tds, const void *buf, size_t n);
1389 int tds_put_string(TDSSOCKET * tds, const char *buf, int len);
1390 int tds_put_int(TDSSOCKET * tds, TDS_INT i);
1391 int tds_put_int8(TDSSOCKET * tds, TDS_INT8 i);
1392 int tds_put_smallint(TDSSOCKET * tds, TDS_SMALLINT si);
1394 #define tds_put_tinyint(tds, ti) tds_put_byte(tds,ti)
1395 int tds_put_byte(TDSSOCKET * tds, unsigned char c);
1396 TDSRESULTINFO *tds_alloc_results(int num_cols);
1397 TDSCOMPUTEINFO **tds_alloc_compute_results(TDSSOCKET * tds, int num_cols, int by_cols);
1398 TDSCONTEXT *tds_alloc_context(void * parent);
1399 void tds_free_context(TDSCONTEXT * locale);
1400 TDSSOCKET *tds_alloc_socket(TDSCONTEXT * context, int bufsize);
1401 
1402 /* config.c */
1403 int tds_default_port(int major, int minor);
1405 typedef void (*TDSCONFPARSE) (const char *option, const char *value, void *param);
1406 int tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *parse_param);
1407 int tds_read_conf_file(TDSCONNECTION * connection, const char *server);
1408 void tds_parse_conf_section(const char *option, const char *value, void *param);
1410 void tds_fix_connection(TDSCONNECTION * connection);
1411 TDS_USMALLINT tds_config_verstr(const char *tdsver, TDSCONNECTION * connection);
1412 int tds_lookup_host(const char *servername, char *ip);
1413 int tds_set_interfaces_file_loc(const char *interfloc);
1414 extern const char STD_DATETIME_FMT[];
1415 int tds_config_boolean(const char *value);
1416 
1417 TDSLOCALE *tds_get_locale(void);
1418 int tds_alloc_row(TDSRESULTINFO * res_info);
1419 int tds_alloc_compute_row(TDSCOMPUTEINFO * res_info);
1420 BCPCOLDATA * tds_alloc_bcp_column_data(int column_size);
1421 unsigned char *tds7_crypt_pass(const unsigned char *clear_pass, size_t len, unsigned char *crypt_pass);
1422 TDSDYNAMIC *tds_lookup_dynamic(TDSSOCKET * tds, const char *id);
1423 /*@observer@*/ const char *tds_prtype(int token);
1424 int tds_get_varint_size(TDSSOCKET * tds, int datatype);
1425 int tds_get_cardinal_type(int datatype, int usertype);
1426 
1427 
1428 
1429 /* iconv.c */
1430 void tds_iconv_open(TDSSOCKET * tds, const char *charset);
1431 void tds_iconv_close(TDSSOCKET * tds);
1432 void tds_srv_charset_changed(TDSSOCKET * tds, const char *charset);
1433 void tds7_srv_charset_changed(TDSSOCKET * tds, int sql_collate, int lcid);
1434 int tds_iconv_alloc(TDSSOCKET * tds);
1435 void tds_iconv_free(TDSSOCKET * tds);
1436 TDSICONV *tds_iconv_from_collate(TDSSOCKET * tds, TDS_UCHAR collate[5]);
1437 
1438 /* threadsafe.c */
1439 char *tds_timestamp_str(char *str, int maxlen);
1440 struct tm *tds_localtime_r(const time_t *timep, struct tm *result);
1441 struct hostent *tds_gethostbyname_r(const char *servername, struct hostent *result, char *buffer, int buflen, int *h_errnop);
1442 struct hostent *tds_gethostbyaddr_r(const char *addr, int len, int type, struct hostent *result, char *buffer, int buflen,
1443  int *h_errnop);
1444 struct servent *tds_getservbyname_r(const char *name, const char *proto, struct servent *result, char *buffer, int buflen);
1445 #ifdef INADDR_NONE
1446 const char *tds_inet_ntoa_r(struct in_addr iaddr, char *ip, size_t len);
1447 #endif
1448 char *tds_get_homedir(void);
1449 
1450 /* mem.c */
1452 void tds_free_input_params(TDSDYNAMIC * dyn);
1453 void tds_free_dynamic(TDSSOCKET * tds, TDSDYNAMIC * dyn);
1454 TDSSOCKET *tds_realloc_socket(TDSSOCKET * tds, size_t bufsize);
1455 char *tds_alloc_client_sqlstate(int msgno);
1456 char *tds_alloc_lookup_sqlstate(TDSSOCKET * tds, int msgno);
1457 TDSLOGIN *tds_alloc_login(void);
1458 TDSDYNAMIC *tds_alloc_dynamic(TDSSOCKET * tds, const char *id);
1459 void tds_free_login(TDSLOGIN * login);
1461 TDSLOCALE *tds_alloc_locale(void);
1462 void *tds_alloc_param_data(TDSCOLUMN * curparam);
1463 void tds_free_locale(TDSLOCALE * locale);
1464 TDSCURSOR * tds_alloc_cursor(TDSSOCKET * tds, const char *name, TDS_INT namelen, const char *query, TDS_INT querylen);
1465 void tds_free_row(TDSRESULTINFO * res_info, unsigned char *row);
1466 
1467 /* login.c */
1468 void tds_set_packet(TDSLOGIN * tds_login, int packet_size);
1469 void tds_set_port(TDSLOGIN * tds_login, int port);
1470 void tds_set_passwd(TDSLOGIN * tds_login, const char *password);
1471 void tds_set_bulk(TDSLOGIN * tds_login, TDS_TINYINT enabled);
1472 void tds_set_user(TDSLOGIN * tds_login, const char *username);
1473 void tds_set_app(TDSLOGIN * tds_login, const char *application);
1474 void tds_set_host(TDSLOGIN * tds_login, const char *hostname);
1475 void tds_set_library(TDSLOGIN * tds_login, const char *library);
1476 void tds_set_server(TDSLOGIN * tds_login, const char *server);
1477 void tds_set_client_charset(TDSLOGIN * tds_login, const char *charset);
1478 void tds_set_language(TDSLOGIN * tds_login, const char *language);
1479 void tds_set_database_name(TDSLOGIN * tds_login, const char *dbname);
1480 void tds_set_version(TDSLOGIN * tds_login, TDS_TINYINT major_ver, TDS_TINYINT minor_ver);
1481 void tds_set_capabilities(TDSLOGIN * tds_login, unsigned char *capabilities, int size);
1482 int tds_connect_and_login(TDSSOCKET * tds, TDSCONNECTION * connection);
1483 
1484 /* query.c */
1485 int tds_submit_query(TDSSOCKET * tds, const char *query);
1486 int tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
1487 int tds_submit_queryf(TDSSOCKET * tds, const char *queryf, ...);
1488 int tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
1489 int tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params);
1490 int tds8_submit_prepexec(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
1491 int tds_submit_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn);
1492 int tds_send_cancel(TDSSOCKET * tds);
1493 const char *tds_next_placeholder(const char *start);
1494 int tds_count_placeholders(const char *query);
1495 int tds_needs_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn);
1496 int tds_submit_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn);
1497 int tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params);
1498 int tds_submit_optioncmd(TDSSOCKET * tds, TDS_OPTION_CMD command, TDS_OPTION option, TDS_OPTION_ARG *param, TDS_INT param_size);
1499 int tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen);
1500 int tds_quote_string(TDSSOCKET * tds, char *buffer, const char *str, int len);
1501 const char *tds_skip_quoted(const char *s);
1502 
1503 int tds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *send);
1504 int tds_cursor_setrows(TDSSOCKET * tds, TDSCURSOR * cursor, int *send);
1505 int tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, int *send);
1506 int tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_type, TDS_INT i_row);
1507 int tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_number, TDS_UINT * row_count);
1508 int tds_cursor_close(TDSSOCKET * tds, TDSCURSOR * cursor);
1509 int tds_cursor_dealloc(TDSSOCKET * tds, TDSCURSOR * cursor);
1510 int tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op, TDS_INT i_row, TDSPARAMINFO * params);
1511 int tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor);
1512 
1513 int tds_multiple_init(TDSSOCKET *tds, TDSMULTIPLE *multiple, TDS_MULTIPLE_TYPE type);
1514 int tds_multiple_done(TDSSOCKET *tds, TDSMULTIPLE *multiple);
1515 int tds_multiple_query(TDSSOCKET *tds, TDSMULTIPLE *multiple, const char *query, TDSPARAMINFO * params);
1516 int tds_multiple_execute(TDSSOCKET *tds, TDSMULTIPLE *multiple, TDSDYNAMIC * dyn);
1517 
1518 /* token.c */
1519 int tds_process_cancel(TDSSOCKET * tds);
1520 #ifdef WORDS_BIGENDIAN
1521 void tds_swap_datatype(int coltype, unsigned char *buf);
1522 #endif
1523 void tds_swap_numeric(TDS_NUMERIC *num);
1524 int tds_get_token_size(int marker);
1527 int tds5_send_optioncmd(TDSSOCKET * tds, TDS_OPTION_CMD tds_command, TDS_OPTION tds_option, TDS_OPTION_ARG * tds_argument,
1528  TDS_INT * tds_argsize);
1529 int tds_process_tokens(TDSSOCKET * tds, /*@out@*/ TDS_INT * result_type, /*@out@*/ int *done_flags, unsigned flag);
1530 
1531 /* data.c */
1532 void tds_set_param_type(TDSSOCKET * tds, TDSCOLUMN * curcol, TDS_SERVER_TYPE type);
1533 void tds_set_column_type(TDSSOCKET * tds, TDSCOLUMN * curcol, int type);
1534 TDS_INT tds_data_get_info(TDSSOCKET *tds, TDSCOLUMN *col);
1535 
1536 
1537 /* tds_convert.c */
1538 TDS_INT tds_datecrack(TDS_INT datetype, const void *di, TDSDATEREC * dr);
1539 int tds_get_conversion_type(int srctype, int colsize);
1540 extern const char tds_hex_digits[];
1541 
1542 /* write.c */
1543 int tds_flush_packet(TDSSOCKET * tds);
1544 int tds_put_buf(TDSSOCKET * tds, const unsigned char *buf, int dsize, int ssize);
1545 
1546 /* read.c */
1547 unsigned char tds_get_byte(TDSSOCKET * tds);
1548 void tds_unget_byte(TDSSOCKET * tds);
1549 unsigned char tds_peek(TDSSOCKET * tds);
1550 TDS_SMALLINT tds_get_smallint(TDSSOCKET * tds);
1551 TDS_INT tds_get_int(TDSSOCKET * tds);
1552 TDS_INT8 tds_get_int8(TDSSOCKET * tds);
1553 int tds_get_string(TDSSOCKET * tds, int string_len, char *dest, size_t dest_size);
1554 int tds_get_char_data(TDSSOCKET * tds, char *dest, size_t wire_size, TDSCOLUMN * curcol);
1555 void *tds_get_n(TDSSOCKET * tds, /*@out@*/ /*@null@*/ void *dest, int n);
1556 int tds_get_size_by_type(int servertype);
1557 
1558 
1559 /* util.c */
1560 int tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum);
1561 TDS_STATE tds_set_state(TDSSOCKET * tds, TDS_STATE state);
1562 void tds_set_parent(TDSSOCKET * tds, void *the_parent);
1563 int tds_swap_bytes(unsigned char *buf, int bytes);
1564 int tds_version(TDSSOCKET * tds_socket, char *pversion_string);
1565 unsigned int tds_gettime_ms(void);
1566 int tds_get_req_capability(TDSSOCKET * tds, int cap);
1567 
1568 /* log.c */
1569 void tdsdump_off(void);
1570 void tdsdump_on(void);
1571 int tdsdump_isopen(void);
1572 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
1573 #pragma GCC visibility pop
1574 #endif
1575 int tdsdump_open(const char *filename);
1576 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
1577 #pragma GCC visibility push(hidden)
1578 #endif
1579 void tdsdump_close(void);
1580 void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length);
1581 void tdsdump_col(const TDSCOLUMN *col);
1582 #undef tdsdump_log
1583 void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
1584 #if defined(__GNUC__) && __GNUC__ >= 2
1585  __attribute__ ((__format__ (__printf__, 3, 4)))
1586 #endif
1587 ;
1588 #define tdsdump_log if (TDS_UNLIKELY(tds_write_dump)) tdsdump_log
1589 
1590 extern int tds_write_dump;
1591 extern int tds_debug_flags;
1592 extern int tds_g_append_mode;
1593 
1594 /* net.c */
1595 int tds_lastpacket(TDSSOCKET * tds);
1596 TDSERRNO tds_open_socket(TDSSOCKET * tds, const char *ip_addr, unsigned int port, int timeout, int *p_oserr);
1597 int tds_close_socket(TDSSOCKET * tds);
1598 int tds_read_packet(TDSSOCKET * tds);
1599 int tds_write_packet(TDSSOCKET * tds, unsigned char final);
1600 int tds7_get_instance_ports(FILE *output, const char *ip_addr);
1601 int tds7_get_instance_port(const char *ip_addr, const char *instance);
1602 int tds_ssl_init(TDSSOCKET *tds);
1603 void tds_ssl_deinit(TDSSOCKET *tds);
1604 const char *tds_prwsaerror(int erc);
1605 
1606 
1607 
1608 /* vstrbuild.c */
1609 int tds_vstrbuild(char *buffer, int buflen, int *resultlen, char *text, int textlen, const char *formats, int formatlen,
1610  va_list ap);
1611 
1612 /* numeric.c */
1613 char *tds_money_to_string(const TDS_MONEY * money, char *s);
1614 TDS_INT tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s);
1615 TDS_INT tds_numeric_change_prec_scale(TDS_NUMERIC * numeric, unsigned char new_prec, unsigned char new_scale);
1616 
1617 /* getmac.c */
1618 void tds_getmac(TDS_SYS_SOCKET s, unsigned char mac[6]);
1619 
1620 #ifndef HAVE_SSPI
1622 TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds);
1623 #else
1624 TDSAUTHENTICATION * tds_sspi_get_auth(TDSSOCKET * tds);
1625 #endif
1626 
1627 /* bulk.c */
1628 
1631 {
1632  TDS_BCP_IN = 1,
1633  TDS_BCP_OUT = 2,
1634  TDS_BCP_QUERYOUT = 3
1635 };
1636 
1637 typedef struct tds_bcpinfo
1638 {
1639  const char *hint;
1640  void *parent;
1641  TDS_CHAR *tablename;
1642  TDS_CHAR *insert_stmt;
1643  TDS_INT direction;
1644  TDS_INT identity_insert_on;
1645  TDS_INT xfer_init;
1646  TDS_INT var_cols;
1647  TDS_INT bind_count;
1648  TDSRESULTINFO *bindinfo;
1649 } TDSBCPINFO;
1650 
1651 int tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
1652 typedef int (*tds_bcp_get_col_data) (TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
1653 typedef void (*tds_bcp_null_error) (TDSBCPINFO *bulk, int index, int offset);
1654 int tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset);
1655 int tds_bcp_done(TDSSOCKET *tds, int *rows_copied);
1656 int tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
1657 int tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
1658 
1659 int tds_writetext_start(TDSSOCKET *tds, const char *objname, const char *textptr, const char *timestamp, int with_log, TDS_UINT size);
1660 int tds_writetext_continue(TDSSOCKET *tds, const TDS_UCHAR *text, TDS_UINT size);
1661 int tds_writetext_end(TDSSOCKET *tds);
1662 
1663 
1664 #define IS_TDS42(x) (x->tds_version==0x402)
1665 #define IS_TDS46(x) (x->tds_version==0x406)
1666 #define IS_TDS50(x) (x->tds_version==0x500)
1667 #define IS_TDS70(x) (x->tds_version==0x700)
1668 #define IS_TDS71(x) (x->tds_version==0x701)
1669 #define IS_TDS72(x) (x->tds_version==0x702)
1670 
1671 #define IS_TDS7_PLUS(x) ((x)->tds_version>=0x700)
1672 #define IS_TDS71_PLUS(x) ((x)->tds_version>=0x701)
1673 #define IS_TDS72_PLUS(x) ((x)->tds_version>=0x702)
1674 
1675 #define TDS_MAJOR(x) ((x)->tds_version >> 8)
1676 #define TDS_MINOR(x) ((x)->tds_version & 0xff)
1677 
1678 #define IS_TDSDEAD(x) (((x) == NULL) || TDS_IS_SOCKET_INVALID((x)->s))
1679 
1681 #define TDS_IS_SYBASE(x) (!(x->product_version & 0x80000000u))
1682 
1683 #define TDS_IS_MSSQL(x) ((x->product_version & 0x80000000u)!=0)
1684 
1688 #define TDS_MS_VER(maj,min,x) (0x80000000u|((maj)<<24)|((min)<<16)|(x))
1689 
1690 /* TODO test if not similar to ms one*/
1692 #define TDS_SYB_VER(maj,min,x) (((maj)<<24)|((min)<<16)|(x)<<8)
1693 
1694 #ifdef __cplusplus
1695 #if 0
1696 {
1697 #endif
1698 }
1699 #endif
1700 
1701 #if defined(__GNUC__) && __GNUC__ >= 4 && !defined(__MINGW32__)
1702 #pragma GCC visibility pop
1703 #endif
1704 
1705 #define TDS_PUT_INT(tds,v) tds_put_int((tds), ((TDS_INT)(v)))
1706 #define TDS_PUT_SMALLINT(tds,v) tds_put_smallint((tds), ((TDS_SMALLINT)(v)))
1707 #define TDS_PUT_BYTE(tds,v) tds_put_byte((tds), ((unsigned char)(v)))
1708 
1709 #endif /* _tds_h_ */