LCOV - code coverage report
Current view: top level - include/freetds - tds.h (source / functions) Hit Total Coverage
Test: FreeTDS coverage Lines: 5 7 71.4 %
Date: 2025-01-18 11:50:39 Functions: 0 0 -

          Line data    Source code
       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 _tdsguard_hfOrWb5znoUCWdBPoNQvqN_
      22             : #define _tdsguard_hfOrWb5znoUCWdBPoNQvqN_
      23             : 
      24             : #ifndef _freetds_config_h_
      25             : #error should include config.h before
      26             : #endif
      27             : 
      28             : #include <stdarg.h>
      29             : #include <stdio.h>
      30             : #include <time.h>
      31             : 
      32             : #ifdef HAVE_STDDEF_H
      33             : #include <stddef.h>
      34             : #endif
      35             : 
      36             : #if HAVE_NETDB_H
      37             : #include <netdb.h>
      38             : #endif /* HAVE_NETDB_H */
      39             : 
      40             : #if HAVE_NETINET_IN_H
      41             : #include <netinet/in.h>
      42             : #endif /* HAVE_NET_INET_IN_H */
      43             : #if HAVE_ARPA_INET_H
      44             : #include <arpa/inet.h>
      45             : #endif /* HAVE_ARPA_INET_H */
      46             : 
      47             : #if HAVE_SYS_SOCKET_H
      48             : #include <sys/socket.h>
      49             : #endif /* HAVE_SYS_SOCKET_H */
      50             : 
      51             : /* forward declaration */
      52             : typedef struct tdsiconvinfo TDSICONV;
      53             : typedef struct tds_connection TDSCONNECTION;
      54             : typedef struct tds_socket TDSSOCKET;
      55             : typedef struct tds_column TDSCOLUMN;
      56             : typedef struct tds_bcpinfo TDSBCPINFO;
      57             : 
      58             : #include <freetds/version.h>
      59             : #include <freetds/sysdep_private.h>
      60             : #include <freetds/thread.h>
      61             : #include <freetds/bool.h>
      62             : #include <freetds/macros.h>
      63             : #include <freetds/utils/string.h>
      64             : #include <freetds/utils/path.h>
      65             : #include <freetds/replacements.h>
      66             : 
      67             : #include <freetds/pushvis.h>
      68             : 
      69             : #ifdef __cplusplus
      70             : extern "C"
      71             : {
      72             : #if 0
      73             : }
      74             : #endif
      75             : #endif
      76             : 
      77             : /**
      78             :  * A structure to hold all the compile-time settings.
      79             :  * This structure is returned by tds_get_compiletime_settings
      80             :  */
      81             : 
      82             : typedef struct tds_compiletime_settings
      83             : {
      84             :         const char *freetds_version;    /* release version of FreeTDS */
      85             :         const tds_dir_char *sysconfdir;         /* location of freetds.conf */
      86             :         const char *last_update;        /* latest software_version date among the modules */
      87             :         const char *tdsver;     /* TDS protocol version (4.2/4.6/5.0/7.0/7.1/8.0) 5.0 */
      88             :         bool msdblib;           /* for MS style dblib */
      89             :         bool sybase_compat;     /* enable increased Open Client binary compatibility */
      90             :         bool threadsafe;                /* compile for thread safety default=no */
      91             :         bool libiconv;          /* search for libiconv in DIR/include and DIR/lib */
      92             :         bool iodbc;             /* build odbc driver against iODBC in DIR */
      93             :         bool unixodbc;          /* build odbc driver against unixODBC in DIR */
      94             :         bool openssl;           /* build against OpenSSL */
      95             :         bool gnutls;            /* build against GnuTLS */
      96             :         bool mars;              /* MARS enabled */
      97             :         bool sspi;              /* SSPI enabled */
      98             :         bool kerberos;          /* Kerberos enabled */
      99             : } TDS_COMPILETIME_SETTINGS;
     100             : 
     101             : /**
     102             :  * @file tds.h
     103             :  * Main include file for libtds
     104             :  */
     105             : 
     106             : /**
     107             :  * \defgroup libtds LibTDS API
     108             :  * Callable functions in \c libtds.
     109             :  * 
     110             :  * The \c libtds library is for use internal to \em FreeTDS.  It is not
     111             :  * intended for use by applications.  Although any use is \em permitted, you're
     112             :  * encouraged to use one of the established public APIs instead, because their
     113             :  * interfaces are stable and documented by the vendors.  
     114             :  */
     115             : 
     116             : /* 
     117             :  * All references to data that touch the wire should use the following typedefs.  
     118             :  *
     119             :  * If you have problems on 64-bit machines and the code is 
     120             :  * using a native datatype, please change it to use
     121             :  * these. (In the TDS layer only, the API layers have their
     122             :  * own typedefs which equate to these).
     123             :  */
     124             : typedef char TDS_CHAR;                          /*  8-bit char     */
     125             : typedef uint8_t TDS_UCHAR;                      /*  8-bit uchar    */
     126             : typedef uint8_t  TDS_TINYINT;                   /*  8-bit unsigned */
     127             : typedef int16_t  TDS_SMALLINT;                  /* 16-bit int      */
     128             : typedef uint16_t TDS_USMALLINT;                 /* 16-bit unsigned */
     129             : typedef int32_t TDS_INT;                        /* 32-bit int      */
     130             : typedef uint32_t TDS_UINT;                      /* 32-bit unsigned */
     131             : typedef int64_t TDS_INT8;                       /* 64-bit integer  */
     132             : typedef uint64_t TDS_UINT8;                     /* 64-bit unsigned */
     133             : typedef tds_sysdep_real32_type TDS_REAL;        /* 32-bit real     */
     134             : typedef tds_sysdep_real64_type TDS_FLOAT;       /* 64-bit real     */
     135             : 
     136             : #include <freetds/proto.h>
     137             : 
     138             : #define TDS_INVALID_TYPE ((TDS_SERVER_TYPE) 0)
     139             : 
     140             : /**
     141             :  * This structure is not directly connected to TDS protocol but
     142             :  * keeps any DATE/TIME information.
     143             :  */
     144             : typedef struct
     145             : {
     146             :         TDS_UINT8   time;       /**< time, 7 digit precision */
     147             :         TDS_INT      date;      /**< date, 0 = 1900-01-01 */
     148             :         TDS_SMALLINT offset;    /**< time offset */
     149             :         TDS_USMALLINT time_prec:3;
     150             :         TDS_USMALLINT _tds_reserved:10;
     151             :         TDS_USMALLINT has_time:1;
     152             :         TDS_USMALLINT has_date:1;
     153             :         TDS_USMALLINT has_offset:1;
     154             : } TDS_DATETIMEALL;
     155             : 
     156             : /** Used by tds_datecrack */
     157             : typedef struct tdsdaterec
     158             : {
     159             :         TDS_INT year;          /**< year */
     160             :         TDS_INT quarter;       /**< quarter (0-3) */
     161             :         TDS_INT month;         /**< month number (0-11) */
     162             :         TDS_INT day;           /**< day of month (1-31) */
     163             :         TDS_INT dayofyear;     /**< day of year  (1-366) */
     164             :         TDS_INT weekday;       /**< day of week  (0-6, 0 = sunday) */
     165             :         TDS_INT hour;          /**< 0-23 */
     166             :         TDS_INT minute;        /**< 0-59 */
     167             :         TDS_INT second;        /**< 0-59 */
     168             :         TDS_INT decimicrosecond;   /**< 0-9999999 */
     169             :         TDS_INT timezone;      /**< -840 - 840 minutes from UTC */
     170             : } TDSDATEREC;
     171             : 
     172             : /**
     173             :  * The following little table is indexed by precision and will
     174             :  * tell us the number of bytes required to store the specified
     175             :  * precision.
     176             :  */
     177             : extern const int tds_numeric_bytes_per_prec[];
     178             : 
     179             : typedef int TDSRET;
     180             : #define TDS_NO_MORE_RESULTS  ((TDSRET)1)
     181             : #define TDS_SUCCESS          ((TDSRET)0)
     182             : #define TDS_FAIL             ((TDSRET)-1)
     183             : #define TDS_CANCELLED        ((TDSRET)-2)
     184             : #define TDS_FAILED(rc) ((rc)<0)
     185             : #define TDS_SUCCEED(rc) ((rc)>=0)
     186             : #define TDS_PROPAGATE(rc) \
     187             :         do { TDSRET _tds_ret = (rc); if (TDS_FAILED(_tds_ret)) return _tds_ret; } while(0)
     188             : 
     189             : #define TDS_INT_CONTINUE 1
     190             : #define TDS_INT_CANCEL 2
     191             : #define TDS_INT_TIMEOUT 3
     192             : 
     193             : 
     194             : #define TDS_NO_COUNT         -1
     195             : 
     196             : #define TDS_ROW_RESULT        4040
     197             : #define TDS_PARAM_RESULT      4042
     198             : #define TDS_STATUS_RESULT     4043
     199             : #define TDS_MSG_RESULT        4044
     200             : #define TDS_COMPUTE_RESULT    4045
     201             : #define TDS_CMD_DONE          4046
     202             : #define TDS_CMD_SUCCEED       4047
     203             : #define TDS_CMD_FAIL          4048
     204             : #define TDS_ROWFMT_RESULT     4049
     205             : #define TDS_COMPUTEFMT_RESULT 4050
     206             : #define TDS_DESCRIBE_RESULT   4051
     207             : #define TDS_DONE_RESULT       4052
     208             : #define TDS_DONEPROC_RESULT   4053
     209             : #define TDS_DONEINPROC_RESULT 4054
     210             : #define TDS_OTHERS_RESULT     4055
     211             : 
     212             : enum tds_token_results
     213             : {
     214             :         TDS_TOKEN_RES_OTHERS,
     215             :         TDS_TOKEN_RES_ROWFMT,
     216             :         TDS_TOKEN_RES_COMPUTEFMT,
     217             :         TDS_TOKEN_RES_PARAMFMT,
     218             :         TDS_TOKEN_RES_DONE,
     219             :         TDS_TOKEN_RES_ROW,
     220             :         TDS_TOKEN_RES_COMPUTE,
     221             :         TDS_TOKEN_RES_PROC,
     222             :         TDS_TOKEN_RES_MSG,
     223             :         TDS_TOKEN_RES_ENV,
     224             : };
     225             : 
     226             : #define TDS_TOKEN_FLAG(flag) TDS_RETURN_##flag = (1 << (TDS_TOKEN_RES_##flag*2)), TDS_STOPAT_##flag = (2 << (TDS_TOKEN_RES_##flag*2))
     227             : 
     228             : enum tds_token_flags
     229             : {
     230             :         TDS_HANDLE_ALL = 0,
     231             :         TDS_TOKEN_FLAG(OTHERS),
     232             :         TDS_TOKEN_FLAG(ROWFMT),
     233             :         TDS_TOKEN_FLAG(COMPUTEFMT),
     234             :         TDS_TOKEN_FLAG(PARAMFMT),
     235             :         TDS_TOKEN_FLAG(DONE),
     236             :         TDS_TOKEN_FLAG(ROW),
     237             :         TDS_TOKEN_FLAG(COMPUTE),
     238             :         TDS_TOKEN_FLAG(PROC),
     239             :         TDS_TOKEN_FLAG(MSG),
     240             :         TDS_TOKEN_FLAG(ENV),
     241             :         TDS_TOKEN_RESULTS = TDS_RETURN_ROWFMT|TDS_RETURN_COMPUTEFMT|TDS_RETURN_DONE|TDS_STOPAT_ROW|TDS_STOPAT_COMPUTE|TDS_RETURN_PROC,
     242             :         TDS_TOKEN_TRAILING = TDS_STOPAT_ROWFMT|TDS_STOPAT_COMPUTEFMT|TDS_STOPAT_ROW|TDS_STOPAT_COMPUTE|TDS_STOPAT_MSG|TDS_STOPAT_OTHERS
     243             : };
     244             : 
     245             : /*
     246             :  * TDSERRNO is emitted by libtds to the client library's error handler
     247             :  * (which may in turn call the client's error handler).
     248             :  * These match the db-lib msgno, because the same values have the same meaning
     249             :  * in db-lib and ODBC.  ct-lib maps them to ct-lib numbers (todo). 
     250             :  */
     251             : typedef enum {  TDSEOK    = TDS_SUCCESS, 
     252             :                 TDSEVERDOWN    =  100,
     253             :                 TDSEINPROGRESS,
     254             :                 TDSEICONVIU    = 2400, 
     255             :                 TDSEICONVAVAIL = 2401, 
     256             :                 TDSEICONVO     = 2402, 
     257             :                 TDSEICONVI     = 2403, 
     258             :                 TDSEICONV2BIG  = 2404,
     259             :                 TDSEPORTINSTANCE        = 2500,
     260             :                 TDSESYNC = 20001, 
     261             :                 TDSEFCON = 20002, 
     262             :                 TDSETIME = 20003, 
     263             :                 TDSEREAD = 20004, 
     264             :                 TDSEWRIT = 20006, 
     265             :                 TDSESOCK = 20008, 
     266             :                 TDSECONN = 20009, 
     267             :                 TDSEMEM  = 20010,
     268             :                 TDSEINTF = 20012,       /* Server name not found in interface file */
     269             :                 TDSEUHST = 20013,       /* Unknown host machine name. */
     270             :                 TDSEPWD  = 20014, 
     271             :                 TDSESEOF = 20017, 
     272             :                 TDSERPND = 20019, 
     273             :                 TDSEBTOK = 20020, 
     274             :                 TDSEOOB  = 20022, 
     275             :                 TDSECLOS = 20056,
     276             :                 TDSEUSCT = 20058, 
     277             :                 TDSEUTDS = 20146, 
     278             :                 TDSEEUNR = 20185, 
     279             :                 TDSECAP  = 20203, 
     280             :                 TDSENEG  = 20210, 
     281             :                 TDSEUMSG = 20212, 
     282             :                 TDSECAPTYP  = 20213, 
     283             :                 TDSECONF = 20214,
     284             :                 TDSEBPROBADTYP = 20250,
     285             :                 TDSECLOSEIN = 20292 
     286             : } TDSERRNO;
     287             : 
     288             : 
     289             : enum {
     290             :         TDS_CUR_ISTAT_UNUSED    = 0x00,
     291             :         TDS_CUR_ISTAT_DECLARED  = 0x01,
     292             :         TDS_CUR_ISTAT_OPEN      = 0x02,
     293             :         TDS_CUR_ISTAT_CLOSED    = 0x04,
     294             :         TDS_CUR_ISTAT_RDONLY    = 0x08,
     295             :         TDS_CUR_ISTAT_UPDATABLE = 0x10,
     296             :         TDS_CUR_ISTAT_ROWCNT    = 0x20,
     297             :         TDS_CUR_ISTAT_DEALLOC   = 0x40
     298             : };
     299             : 
     300             : /* string types */
     301             : #define TDS_NULLTERM -9
     302             : 
     303             : 
     304             : typedef union tds_option_arg
     305             : {
     306             :         TDS_TINYINT ti;
     307             :         TDS_INT i;
     308             :         TDS_CHAR *c;
     309             : } TDS_OPTION_ARG;
     310             : 
     311             : 
     312             : typedef enum tds_encryption_level {
     313             :         TDS_ENCRYPTION_DEFAULT,
     314             :         TDS_ENCRYPTION_OFF,
     315             :         TDS_ENCRYPTION_REQUEST,
     316             :         TDS_ENCRYPTION_REQUIRE,
     317             :         TDS_ENCRYPTION_STRICT
     318             : } TDS_ENCRYPTION_LEVEL;
     319             : 
     320             : /*
     321             :  * TODO use system macros for optimization
     322             :  * See mcrypt for reference and linux kernel source for optimization
     323             :  * check if unaligned access and use fast write/read when implemented
     324             :  */
     325             : #define TDS_BYTE_SWAP16(value)                 \
     326             :          (((((uint16_t)value)<<8) & 0xFF00u) | \
     327             :           ((((uint16_t)value)>>8) & 0x00FFu))
     328             : 
     329             : #define TDS_BYTE_SWAP32(value)                     \
     330             :          (((((uint32_t)value)<<24) & 0xFF000000u)| \
     331             :           ((((uint32_t)value)<< 8) & 0x00FF0000u)| \
     332             :           ((((uint32_t)value)>> 8) & 0x0000FF00u)| \
     333             :           ((((uint32_t)value)>>24) & 0x000000FFu))
     334             : 
     335             : #define is_end_token(x) ((x) >= TDS_DONE_TOKEN && (x) <= TDS_DONEINPROC_TOKEN)
     336             : 
     337             : enum {
     338             :         TDS_TYPEFLAG_INVALID  = 0,
     339             :         TDS_TYPEFLAG_NULLABLE = 1,
     340             :         TDS_TYPEFLAG_FIXED    = 2,
     341             :         TDS_TYPEFLAG_VARIABLE = 4,
     342             :         TDS_TYPEFLAG_COLLATE  = 8,
     343             :         TDS_TYPEFLAG_ASCII    = 16,
     344             :         TDS_TYPEFLAG_UNICODE  = 32,
     345             :         TDS_TYPEFLAG_BINARY   = 64,
     346             :         TDS_TYPEFLAG_DATETIME = 128,
     347             :         TDS_TYPEFLAG_NUMERIC  = 256,
     348             :         TDS_TYPEFLAG_VARIANT  = 512,
     349             : };
     350             : 
     351             : extern const uint16_t tds_type_flags_ms[256];
     352             : #if 0
     353             : extern const uint16_t tds_type_flags_syb[256];
     354             : extern const char *const tds_type_names[256];
     355             : #endif
     356             : 
     357             : #define is_fixed_type(x)      ((tds_type_flags_ms[x] & TDS_TYPEFLAG_FIXED)    != 0)
     358             : #define is_nullable_type(x)   ((tds_type_flags_ms[x] & TDS_TYPEFLAG_NULLABLE) != 0)
     359             : #define is_variable_type(x)   ((tds_type_flags_ms[x] & TDS_TYPEFLAG_VARIABLE) != 0)
     360             : #define is_variant_inner_type(x)   ((tds_type_flags_ms[x] & TDS_TYPEFLAG_VARIANT) != 0)
     361             : 
     362             : 
     363             : #define is_blob_type(x)       ((x)==SYBTEXT || (x)==SYBIMAGE || (x)==SYBNTEXT)
     364             : #define is_blob_col(x)        ((x)->column_varint_size > 2)
     365             : /* large type means it has a two byte size field */
     366             : /* define is_large_type(x) (x>128) */
     367             : #define is_numeric_type(x)    ((x)==SYBNUMERIC || (x)==SYBDECIMAL)
     368             : /** return true if type is a datetime (but not date or time) */
     369             : #define is_datetime_type(x)   ((tds_type_flags_ms[x] & TDS_TYPEFLAG_DATETIME) != 0)
     370             : #define is_unicode_type(x)    ((tds_type_flags_ms[x] & TDS_TYPEFLAG_UNICODE) != 0)
     371             : #define is_collate_type(x)    ((tds_type_flags_ms[x] & TDS_TYPEFLAG_COLLATE) != 0)
     372             : #define is_ascii_type(x)      ((tds_type_flags_ms[x] & TDS_TYPEFLAG_ASCII) != 0)
     373             : #define is_binary_type(x)     ((tds_type_flags_ms[x] & TDS_TYPEFLAG_BINARY) != 0)
     374             : #define is_char_type(x)       ((tds_type_flags_ms[x] & (TDS_TYPEFLAG_ASCII|TDS_TYPEFLAG_UNICODE)) != 0)
     375             : #define is_similar_type(x, y) (is_char_type(x) && is_char_type(y))
     376             : inline static bool
     377             : is_tds_type_valid(int type)
     378             : {
     379       68892 :         return (unsigned) type < 256u && tds_type_flags_ms[type] != 0;
     380             : }
     381             : 
     382             : 
     383             : #define TDS_MAX_CAPABILITY      32
     384             : #define MAXPRECISION            77
     385             : #define TDS_MAX_CONN            4096
     386             : #define TDS_MAX_DYNID_LEN       30
     387             : 
     388             : /* defaults to use if no others are found */
     389             : #define TDS_DEF_SERVER          "SYBASE"
     390             : #define TDS_DEF_BLKSZ           512
     391             : #define TDS_DEF_CHARSET         "iso_1"
     392             : #define TDS_DEF_LANG            "us_english"
     393             : #if TDS50
     394             : #define TDS_DEFAULT_VERSION     0x500
     395             : #define TDS_DEF_PORT            4000
     396             : #elif TDS71
     397             : #define TDS_DEFAULT_VERSION     0x701
     398             : #define TDS_DEF_PORT            1433
     399             : #elif TDS72
     400             : #define TDS_DEFAULT_VERSION     0x702
     401             : #define TDS_DEF_PORT            1433
     402             : #elif TDS73
     403             : #define TDS_DEFAULT_VERSION     0x703
     404             : #define TDS_DEF_PORT            1433
     405             : #elif TDS74
     406             : #define TDS_DEFAULT_VERSION     0x704
     407             : #define TDS_DEF_PORT            1433
     408             : #else
     409             : #define TDS_DEFAULT_VERSION     0x000
     410             : #define TDS_DEF_PORT            1433
     411             : #endif
     412             : 
     413             : /* normalized strings from freetds.conf file */
     414             : #define TDS_STR_VERSION  "tds version"
     415             : #define TDS_STR_BLKSZ    "initial block size"
     416             : #define TDS_STR_SWAPDT   "swap broken dates"
     417             : #define TDS_STR_DUMPFILE "dump file"
     418             : #define TDS_STR_DEBUGLVL "debug level"
     419             : #define TDS_STR_DEBUGFLAGS "debug flags"
     420             : #define TDS_STR_TIMEOUT  "timeout"
     421             : #define TDS_STR_QUERY_TIMEOUT  "query timeout"
     422             : #define TDS_STR_CONNTIMEOUT "connect timeout"
     423             : #define TDS_STR_HOSTNAME "hostname"
     424             : #define TDS_STR_HOST     "host"
     425             : #define TDS_STR_PORT     "port"
     426             : #define TDS_STR_TEXTSZ   "text size"
     427             : /* for big endian hosts, obsolete, ignored */
     428             : #define TDS_STR_EMUL_LE "emulate little endian"
     429             : #define TDS_STR_CHARSET "charset"
     430             : #define TDS_STR_CLCHARSET       "client charset"
     431             : #define TDS_STR_USE_UTF_16      "use utf-16"
     432             : #define TDS_STR_LANGUAGE        "language"
     433             : #define TDS_STR_APPENDMODE      "dump file append"
     434             : #define TDS_STR_DATETIMEFMT     "date format"
     435             : #define TDS_STR_DATEFMT "date-only format"
     436             : #define TDS_STR_TIMEFMT "time-only format"
     437             : #define TDS_STR_INSTANCE "instance"
     438             : #define TDS_STR_ASA_DATABASE    "asa database"
     439             : #define TDS_STR_DATABASE        "database"
     440             : #define TDS_STR_ENCRYPTION       "encryption"
     441             : #define TDS_STR_USENTLMV2       "use ntlmv2"
     442             : #define TDS_STR_USELANMAN       "use lanman"
     443             : /* conf values */
     444             : #define TDS_STR_ENCRYPTION_OFF   "off"
     445             : #define TDS_STR_ENCRYPTION_REQUEST "request"
     446             : #define TDS_STR_ENCRYPTION_REQUIRE "require"
     447             : #define TDS_STR_ENCRYPTION_STRICT "strict"
     448             : /* Defines to enable optional GSSAPI delegation */
     449             : #define TDS_GSSAPI_DELEGATION "enable gssapi delegation"
     450             : /* Mutual authentication */
     451             : #define TDS_STR_MUTUAL_AUTHENTICATION "mutual authentication"
     452             : /* Kerberos realm name */
     453             : #define TDS_STR_REALM   "realm"
     454             : /* Kerberos SPN */
     455             : #define TDS_STR_SPN     "spn"
     456             : /* CA file */
     457             : #define TDS_STR_CAFILE  "ca file"
     458             : /* CRL file */
     459             : #define TDS_STR_CRLFILE "crl file"
     460             : /* check SSL hostname */
     461             : #define TDS_STR_CHECKSSLHOSTNAME        "check certificate hostname"
     462             : /* SSL hostname to check certificate */
     463             : #define TDS_STR_SSLHOSTNAME     "certificate hostname"
     464             : /* database filename to attach on login (MSSQL) */
     465             : #define TDS_STR_DBFILENAME      "database filename"
     466             : /* Application Intent MSSQL 2012 support */
     467             : #define TDS_STR_READONLY_INTENT "read-only intent"
     468             : /* configurable cipher suite to send to openssl's SSL_set_cipher_list() function */
     469             : #define TLS_STR_OPENSSL_CIPHERS "openssl ciphers"
     470             : /* enable old TLS v1, required for instance if you are using a really old Windows XP */
     471             : #define TDS_STR_ENABLE_TLS_V1 "enable tls v1"
     472             : 
     473             : 
     474             : /* TODO do a better check for alignment than this */
     475             : typedef union
     476             : {
     477             :         void *p;
     478             :         int i;
     479             :         int64_t ui;
     480             : } tds_align_struct;
     481             : 
     482             : #define TDS_ALIGN_SIZE sizeof(tds_align_struct)
     483             : 
     484             : typedef struct tds_capability_type
     485             : {
     486             :         unsigned char type;
     487             :         unsigned char len; /* always sizeof(values) */
     488             :         unsigned char values[TDS_MAX_CAPABILITY/2-2];
     489             : } TDS_CAPABILITY_TYPE;
     490             : 
     491             : typedef struct tds_capabilities
     492             : {
     493             :         TDS_CAPABILITY_TYPE types[2];
     494             : } TDS_CAPABILITIES;
     495             : 
     496             : #define TDS_MAX_LOGIN_STR_SZ 128
     497             : typedef struct tds_login
     498             : {
     499             :         DSTR server_name;               /**< server name (in freetds.conf) */
     500             :         int port;                       /**< port of database service */
     501             :         TDS_USMALLINT tds_version;      /**< TDS version */
     502             :         int block_size;
     503             :         DSTR language;                  /* e.g. us-english */
     504             :         DSTR server_charset;            /**< charset of server e.g. iso_1 */
     505             :         TDS_INT connect_timeout;
     506             :         DSTR client_host_name;
     507             :         DSTR server_host_name;
     508             :         DSTR server_realm_name;         /**< server realm name (in freetds.conf) */
     509             :         DSTR server_spn;                /**< server SPN (in freetds.conf) */
     510             :         DSTR db_filename;               /**< database filename to attach (MSSQL) */
     511             :         DSTR cafile;                    /**< certificate authorities file */
     512             :         DSTR crlfile;                   /**< certificate revocation file */
     513             :         DSTR certificate_host_name;     /**< certificate hostname to check, if empty use server_host_name */
     514             :         DSTR openssl_ciphers;
     515             :         DSTR app_name;
     516             :         DSTR user_name;         /**< account for login */
     517             :         DSTR password;          /**< password of account login */
     518             :         DSTR new_password;              /**< new password to set (TDS 7.2+) */
     519             : 
     520             :         DSTR library;   /* Ct-Library, DB-Library,  TDS-Library or ODBC */
     521             :         TDS_TINYINT encryption_level;
     522             : 
     523             :         TDS_INT query_timeout;
     524             :         TDS_CAPABILITIES capabilities;
     525             :         DSTR client_charset;
     526             :         DSTR database;
     527             : 
     528             :         struct addrinfo *ip_addrs;                      /**< ip(s) of server */
     529             :         DSTR instance_name;
     530             :         tds_dir_char *dump_file;
     531             :         int debug_flags;
     532             :         int text_size;
     533             :         DSTR routing_address;
     534             :         uint16_t routing_port;
     535             : 
     536             :         unsigned char option_flag2;
     537             : 
     538             :         unsigned int bulk_copy:1;       /**< if bulk copy should be enabled */
     539             :         unsigned int suppress_language:1;
     540             :         unsigned int gssapi_use_delegation:1;
     541             :         unsigned int mutual_authentication:1;
     542             :         unsigned int use_ntlmv2:1;
     543             :         unsigned int use_ntlmv2_specified:1;
     544             :         unsigned int use_lanman:1;
     545             :         unsigned int mars:1;
     546             :         unsigned int use_utf16:1;
     547             :         unsigned int use_new_password:1;
     548             :         unsigned int valid_configuration:1;
     549             :         unsigned int check_ssl_hostname:1;
     550             :         unsigned int readonly_intent:1;
     551             :         unsigned int enable_tls_v1:1;
     552             :         unsigned int enable_tls_v1_specified:1;
     553             :         unsigned int server_is_valid:1;
     554             : } TDSLOGIN;
     555             : 
     556             : typedef struct tds_headers
     557             : {
     558             :         const char *qn_options;
     559             :         const char *qn_msgtext;
     560             :         TDS_INT qn_timeout;
     561             :         /* TDS 7.4+: trace activity ID char[20] */
     562             : } TDSHEADERS;
     563             : 
     564             : typedef struct tds_locale
     565             : {
     566             :         char *language;
     567             :         char *server_charset;
     568             :         char *datetime_fmt;
     569             :         char *date_fmt;
     570             :         char *time_fmt;
     571             : } TDSLOCALE;
     572             : 
     573             : /** 
     574             :  * Information about blobs (e.g. text or image).
     575             :  * current_row contains this structure.
     576             :  */
     577             : typedef struct tds_blob
     578             : {
     579             :         TDS_CHAR *textvalue;
     580             :         TDS_CHAR textptr[16];
     581             :         TDS_CHAR timestamp[8];
     582             :         bool valid_ptr;
     583             : } TDSBLOB;
     584             : 
     585             : /**
     586             :  * Store variant information
     587             :  */
     588             : typedef struct tds_variant
     589             : {
     590             :         /* this MUST have same position and place of textvalue in tds_blob */
     591             :         TDS_CHAR *data;
     592             :         TDS_INT size;
     593             :         TDS_INT data_len;
     594             :         TDS_SERVER_TYPE type;
     595             :         TDS_UCHAR collation[5];
     596             : } TDSVARIANT;
     597             : 
     598             : /**
     599             :  * Information relevant to libiconv.  The name is an iconv name, not 
     600             :  * the same as found in master..syslanguages. 
     601             :  */
     602             : typedef struct tds_encoding
     603             : {
     604             :         /** name of the encoding (ie UTF-8) */
     605             :         const char *name;
     606             :         unsigned char min_bytes_per_char;
     607             :         unsigned char max_bytes_per_char;
     608             :         /** internal numeric index into array of all encodings */
     609             :         unsigned char canonic;
     610             : } TDS_ENCODING;
     611             : 
     612             : typedef struct tds_bcpcoldata
     613             : {
     614             :         TDS_UCHAR *data;
     615             :         TDS_INT    datalen;
     616             :         bool       is_null;
     617             : } BCPCOLDATA;
     618             : 
     619             : 
     620             : typedef TDSRET  tds_func_get_info(TDSSOCKET *tds, TDSCOLUMN *col);
     621             : typedef TDSRET  tds_func_get_data(TDSSOCKET *tds, TDSCOLUMN *col);
     622             : typedef TDS_INT tds_func_row_len(TDSCOLUMN *col);
     623             : typedef TDSRET  tds_func_put_info(TDSSOCKET *tds, TDSCOLUMN *col);
     624             : typedef TDSRET  tds_func_put_data(TDSSOCKET *tds, TDSCOLUMN *col, int bcp7);
     625             : typedef int     tds_func_check(const TDSCOLUMN *col);
     626             : 
     627             : typedef struct tds_column_funcs
     628             : {
     629             :         tds_func_get_info *get_info;
     630             :         tds_func_get_data *get_data;
     631             :         tds_func_row_len  *row_len;
     632             :         /**
     633             :          * Send metadata column information to server.
     634             :          * \tds
     635             :          * \param col  column to send
     636             :          */
     637             :         tds_func_put_info *put_info;
     638             :         /**
     639             :          * Send column data to server.
     640             :          * Usually send parameters unless bcp7 is specified, in
     641             :          * this case send BCP for TDS7+ (Sybase use a completely
     642             :          * different format for BCP)
     643             :          * \tds
     644             :          * \param col  column to send
     645             :          * \param bcp7 1 to send BCP column on TDS7+
     646             :          */
     647             :         tds_func_put_data *put_data;
     648             : #if ENABLE_EXTRA_CHECKS
     649             :         /**
     650             :          * Check column is valid.
     651             :          * Some things should be checked:
     652             :          * - column_type and on_server.column_type;
     653             :          * - column_size and on_server.column_size;
     654             :          * - column_cur_size;
     655             :          * - column_prec and column_scale;
     656             :          * - is_XXXX_type macros/functions (nullable/fixed/blob/variable);
     657             :          * - tds_get_size_by_type;
     658             :          * - tds_get_conversion_type.
     659             :          *
     660             :          * \tds
     661             :          * \param col  column to check
     662             :          */
     663             :         tds_func_check    *check;
     664             : #endif
     665             : #if 0
     666             :         TDSRET (*convert)(TDSSOCKET *tds, TDSCOLUMN *col);
     667             : #endif
     668             : } TDSCOLUMNFUNCS;
     669             : 
     670             : /** 
     671             :  * Metadata about columns in regular and compute rows 
     672             :  */
     673             : struct tds_column
     674             : {
     675             :         const TDSCOLUMNFUNCS *funcs;
     676             :         TDS_INT column_usertype;
     677             :         TDS_INT column_flags;
     678             : 
     679             :         TDS_INT column_size;            /**< maximun size of data. For fixed is the size. */
     680             : 
     681             :         TDS_SERVER_TYPE column_type;    /**< This type can be different from wire type because
     682             :                                          * conversion (e.g. UCS-2->Ascii) can be applied.
     683             :                                          * I'm beginning to wonder about the wisdom of this, however.
     684             :                                          * April 2003 jkl
     685             :                                          */
     686             :         TDS_TINYINT column_varint_size; /**< size of length when reading from wire (0, 1, 2 or 4) */
     687             : 
     688             :         TDS_TINYINT column_prec;        /**< precision for decimal/numeric */
     689             :         TDS_TINYINT column_scale;       /**< scale for decimal/numeric */
     690             : 
     691             :         struct
     692             :         {
     693             :                 TDS_SERVER_TYPE column_type;    /**< type of data, saved from wire */
     694             :                 TDS_INT column_size;
     695             :         } on_server;
     696             : 
     697             :         TDSICONV *char_conv;    /**< refers to previously allocated iconv information */
     698             : 
     699             :         DSTR table_name;
     700             :         DSTR column_name;
     701             :         DSTR table_column_name;
     702             : 
     703             :         unsigned char *column_data;
     704             :         void (*column_data_free)(struct tds_column *column);
     705             :         unsigned char column_nullable:1;
     706             :         unsigned char column_writeable:1;
     707             :         unsigned char column_identity:1;
     708             :         unsigned char column_key:1;
     709             :         unsigned char column_hidden:1;
     710             :         unsigned char column_output:1;
     711             :         unsigned char column_timestamp:1;
     712             :         unsigned char column_computed:1;
     713             :         TDS_UCHAR column_collation[5];
     714             : 
     715             :         /* additional fields flags for compute results */
     716             :         TDS_SMALLINT column_operand;
     717             :         TDS_TINYINT column_operator;
     718             : 
     719             :         /* FIXME this is data related, not column */
     720             :         /** size written in variable (ie: char, text, binary). -1 if NULL. */
     721             :         TDS_INT column_cur_size;
     722             : 
     723             :         /* related to binding or info stored by client libraries */
     724             :         /* FIXME find a best place to store these data, some are unused */
     725             :         TDS_SMALLINT column_bindtype;
     726             :         TDS_SMALLINT column_bindfmt;
     727             :         TDS_INT column_bindlen;
     728             :         TDS_SMALLINT *column_nullbind;
     729             :         TDS_CHAR *column_varaddr;
     730             :         TDS_INT *column_lenbind;
     731             :         TDS_INT column_textpos;
     732             :         TDS_INT column_text_sqlgetdatapos;
     733             :         TDS_CHAR column_text_sqlputdatainfo;
     734             :         unsigned char column_iconv_left;
     735             :         char column_iconv_buf[9];
     736             : 
     737             :         BCPCOLDATA *bcp_column_data;
     738             :         /**
     739             :          * The length, in bytes, of any length prefix this column may have.
     740             :          * For example, strings in some non-C programming languages are
     741             :          * made up of a one-byte length prefix, followed by the string
     742             :          * data itself.
     743             :          * If the data do not have a length prefix, set prefixlen to 0.
     744             :          * Currently not very used in code, however do not remove.
     745             :          */
     746             :         TDS_INT bcp_prefix_len;
     747             :         TDS_INT bcp_term_len;
     748             :         TDS_CHAR *bcp_terminator;
     749             : };
     750             : 
     751             : 
     752             : /** Hold information for any results */
     753             : typedef struct tds_result_info
     754             : {
     755             :         /* TODO those fields can became a struct */
     756             :         TDSCOLUMN **columns;
     757             :         TDS_USMALLINT num_cols;
     758             :         TDS_USMALLINT computeid;
     759             :         TDS_INT ref_count;
     760             :         TDSSOCKET *attached_to;
     761             :         unsigned char *current_row;
     762             :         void (*row_free)(struct tds_result_info* result, unsigned char *row);
     763             :         TDS_INT row_size;
     764             : 
     765             :         TDS_SMALLINT *bycolumns;
     766             :         TDS_USMALLINT by_cols;
     767             :         bool rows_exist;
     768             :         /* TODO remove ?? used only in dblib */
     769             :         bool more_results;
     770             : } TDSRESULTINFO;
     771             : 
     772             : /** values for tds->state */
     773             : typedef enum tds_states
     774             : {
     775             :         TDS_IDLE,       /**< no data expected */
     776             :         TDS_WRITING,    /**< client is writing data */
     777             :         TDS_SENDING,    /**< client would send data */
     778             :         TDS_PENDING,    /**< cilent is waiting for data */
     779             :         TDS_READING,    /**< client is reading data */
     780             :         TDS_DEAD        /**< no connection */
     781             : } TDS_STATE;
     782             : 
     783             : typedef enum tds_operations
     784             : {
     785             :         TDS_OP_NONE             = 0,
     786             : 
     787             :         /* MSSQL operations, these matches protocol definitions */
     788             :         TDS_OP_CURSOR           = TDS_SP_CURSOR,
     789             :         TDS_OP_CURSOROPEN       = TDS_SP_CURSOROPEN,
     790             :         TDS_OP_CURSORPREPARE    = TDS_SP_CURSORPREPARE,
     791             :         TDS_OP_CURSOREXECUTE    = TDS_SP_CURSOREXECUTE,
     792             :         TDS_OP_CURSORPREPEXEC   = TDS_SP_CURSORPREPEXEC,
     793             :         TDS_OP_CURSORUNPREPARE  = TDS_SP_CURSORUNPREPARE,
     794             :         TDS_OP_CURSORFETCH      = TDS_SP_CURSORFETCH,
     795             :         TDS_OP_CURSOROPTION     = TDS_SP_CURSOROPTION,
     796             :         TDS_OP_CURSORCLOSE      = TDS_SP_CURSORCLOSE,
     797             :         TDS_OP_EXECUTESQL       = TDS_SP_EXECUTESQL,
     798             :         TDS_OP_PREPARE          = TDS_SP_PREPARE,
     799             :         TDS_OP_EXECUTE          = TDS_SP_EXECUTE,
     800             :         TDS_OP_PREPEXEC         = TDS_SP_PREPEXEC,
     801             :         TDS_OP_PREPEXECRPC      = TDS_SP_PREPEXECRPC,
     802             :         TDS_OP_UNPREPARE        = TDS_SP_UNPREPARE,
     803             : 
     804             :         /* sybase operations */
     805             :         TDS_OP_DYN_DEALLOC      = 100,
     806             : } TDS_OPERATION;
     807             : 
     808             : #define TDS_DBG_LOGIN   __FILE__, ((__LINE__ << 4) | 11)
     809             : #define TDS_DBG_HEADER  __FILE__, ((__LINE__ << 4) | 10)
     810             : #define TDS_DBG_FUNC    __FILE__, ((__LINE__ << 4) |  7)
     811             : #define TDS_DBG_INFO2   __FILE__, ((__LINE__ << 4) |  6)
     812             : #define TDS_DBG_INFO1   __FILE__, ((__LINE__ << 4) |  5)
     813             : #define TDS_DBG_NETWORK __FILE__, ((__LINE__ << 4) |  4)
     814             : #define TDS_DBG_WARN    __FILE__, ((__LINE__ << 4) |  3)
     815             : #define TDS_DBG_ERROR   __FILE__, ((__LINE__ << 4) |  2)
     816             : #define TDS_DBG_SEVERE  __FILE__, ((__LINE__ << 4) |  1)
     817             : 
     818             : #define TDS_DBGFLAG_FUNC    0x80
     819             : #define TDS_DBGFLAG_INFO2   0x40
     820             : #define TDS_DBGFLAG_INFO1   0x20
     821             : #define TDS_DBGFLAG_NETWORK 0x10
     822             : #define TDS_DBGFLAG_WARN    0x08
     823             : #define TDS_DBGFLAG_ERROR   0x04
     824             : #define TDS_DBGFLAG_SEVERE  0x02
     825             : #define TDS_DBGFLAG_ALL     0xfff
     826             : #define TDS_DBGFLAG_LOGIN   0x0800
     827             : #define TDS_DBGFLAG_HEADER  0x0400
     828             : #define TDS_DBGFLAG_PID     0x1000
     829             : #define TDS_DBGFLAG_TIME    0x2000
     830             : #define TDS_DBGFLAG_SOURCE  0x4000
     831             : #define TDS_DBGFLAG_THREAD  0x8000
     832             : 
     833             : #if 0
     834             : /**
     835             :  * An attempt at better logging.
     836             :  * Using these bitmapped values, various logging features can be turned on and off.
     837             :  * It can be especially helpful to turn packet data on/off for security reasons.
     838             :  */
     839             : enum TDS_DBG_LOG_STATE
     840             : {
     841             :           TDS_DBG_LOGIN =  (1 << 0)       /**< for diagnosing login problems;                                       
     842             :                                            otherwise the username/password information is suppressed. */
     843             :         , TDS_DBG_API =    (1 << 1)       /**< Log calls to client libraries */
     844             :         , TDS_DBG_ASYNC =  (1 << 2)       /**< Log asynchronous function starts or completes. */
     845             :         , TDS_DBG_DIAG =   (1 << 3)       /**< Log client- and server-generated messages */
     846             :         , TDS_DBG_error =  (1 << 4)
     847             :         /* TODO:  ^^^^^ make upper case when old #defines (above) are removed */
     848             :         /* Log FreeTDS runtime/logic error occurs. */
     849             :         , TDS_DBG_PACKET = (1 << 5)       /**< Log hex dump of packets to/from the server. */
     850             :         , TDS_DBG_LIBTDS = (1 << 6)       /**< Log calls to (and in) libtds */
     851             :         , TDS_DBG_CONFIG = (1 << 7)       /**< replaces TDSDUMPCONFIG */
     852             :         , TDS_DBG_DEFAULT = 0xFE        /**< all above except login packets */
     853             : };
     854             : #endif
     855             : 
     856             : typedef struct tds_result_info TDSCOMPUTEINFO;
     857             : 
     858             : typedef TDSRESULTINFO TDSPARAMINFO;
     859             : 
     860             : typedef struct tds_message
     861             : {
     862             :         TDS_CHAR *server;
     863             :         TDS_CHAR *message;
     864             :         TDS_CHAR *proc_name;
     865             :         TDS_CHAR *sql_state;
     866             :         TDS_INT msgno;
     867             :         TDS_INT line_number;
     868             :         /* -1 .. 255 */
     869             :         TDS_SMALLINT state;
     870             :         TDS_TINYINT priv_msg_type;
     871             :         TDS_TINYINT severity;
     872             :         /* for library-generated errors */
     873             :         int oserr;
     874             : } TDSMESSAGE;
     875             : 
     876             : typedef struct tds_upd_col
     877             : {
     878             :         struct tds_upd_col *next;       
     879             :         TDS_INT colnamelength;
     880             :         char * columnname;
     881             : } TDSUPDCOL;
     882             : 
     883             : typedef enum {
     884             :           TDS_CURSOR_STATE_UNACTIONED = 0       /* initial value */
     885             :         , TDS_CURSOR_STATE_REQUESTED = 1        /* called by ct_cursor */ 
     886             :         , TDS_CURSOR_STATE_SENT = 2             /* sent to server */
     887             :         , TDS_CURSOR_STATE_ACTIONED = 3         /* acknowledged by server */
     888             : } TDS_CURSOR_STATE;
     889             : 
     890             : typedef struct tds_cursor_status
     891             : {
     892             :         TDS_CURSOR_STATE declare;
     893             :         TDS_CURSOR_STATE cursor_row;
     894             :         TDS_CURSOR_STATE open;
     895             :         TDS_CURSOR_STATE fetch;
     896             :         TDS_CURSOR_STATE close; 
     897             :         TDS_CURSOR_STATE dealloc;
     898             : } TDS_CURSOR_STATUS;
     899             : 
     900             : typedef enum tds_cursor_operation
     901             : {
     902             :         TDS_CURSOR_POSITION = 0,
     903             :         TDS_CURSOR_UPDATE = 1,
     904             :         TDS_CURSOR_DELETE = 2,
     905             :         TDS_CURSOR_INSERT = 4
     906             : } TDS_CURSOR_OPERATION;
     907             : 
     908             : typedef enum tds_cursor_fetch
     909             : {
     910             :         TDS_CURSOR_FETCH_NEXT = 1,
     911             :         TDS_CURSOR_FETCH_PREV,
     912             :         TDS_CURSOR_FETCH_FIRST,
     913             :         TDS_CURSOR_FETCH_LAST,
     914             :         TDS_CURSOR_FETCH_ABSOLUTE,
     915             :         TDS_CURSOR_FETCH_RELATIVE
     916             : } TDS_CURSOR_FETCH;
     917             : 
     918             : /**
     919             :  * Holds information about a cursor
     920             :  */
     921             : typedef struct tds_cursor
     922             : {
     923             :         struct tds_cursor *next;        /**< next in linked list, keep first */
     924             :         TDS_INT ref_count;              /**< reference counter so client can retain safely a pointer */
     925             :         char *cursor_name;              /**< name of the cursor */
     926             :         TDS_INT cursor_id;              /**< cursor id returned by the server after cursor declare */
     927             :         TDS_TINYINT options;            /**< read only|updatable TODO use it */
     928             :         /**
     929             :          * true if cursor was marker to be closed when connection is idle
     930             :          */
     931             :         bool defer_close;
     932             :         char *query;                    /**< SQL query */
     933             :         /* TODO for updatable columns */
     934             :         /* TDS_TINYINT number_upd_cols; */      /**< number of updatable columns */
     935             :         /* TDSUPDCOL *cur_col_list; */  /**< updatable column list */
     936             :         TDS_INT cursor_rows;            /**< number of cursor rows to fetch */
     937             :         /* TDSPARAMINFO *params; */     /** cursor parameter */
     938             :         TDS_CURSOR_STATUS status;
     939             :         TDS_USMALLINT srv_status;
     940             :         TDSRESULTINFO *res_info;        /** row fetched from this cursor */
     941             :         TDS_INT type, concurrency;
     942             : } TDSCURSOR;
     943             : 
     944             : /**
     945             :  * Current environment as reported by the server
     946             :  */
     947             : typedef struct tds_env
     948             : {
     949             :         /** packet size (512-65535) */
     950             :         int block_size;
     951             :         char *language;
     952             :         /** character set encoding */
     953             :         char *charset;
     954             :         /** database name */
     955             :         char *database;
     956             : } TDSENV;
     957             : 
     958             : /**
     959             :  * Holds information for a dynamic (also called prepared) query.
     960             :  */
     961             : typedef struct tds_dynamic
     962             : {
     963             :         struct tds_dynamic *next;       /**< next in linked list, keep first */
     964             :         TDS_INT ref_count;              /**< reference counter so client can retain safely a pointer */
     965             :         /** numeric id for mssql7+*/
     966             :         TDS_INT num_id;
     967             :         /** 
     968             :          * id of dynamic.
     969             :          * Usually this id correspond to server one but if not specified
     970             :          * is generated automatically by libTDS
     971             :          */
     972             :         char id[30];
     973             :         /**
     974             :          * this dynamic query cannot be prepared so libTDS have to construct a simple query.
     975             :          * This can happen for instance is tds protocol doesn't support dynamics or trying
     976             :          * to prepare query under Sybase that have BLOBs as parameters.
     977             :          */
     978             :         TDS_TINYINT emulated;
     979             :         /**
     980             :          * true if dynamic was marker to be closed when connection is idle
     981             :          */
     982             :         bool defer_close;
     983             :         /* int dyn_state; */ /* TODO use it */
     984             :         TDSPARAMINFO *res_info; /**< query results */
     985             :         /**
     986             :          * query parameters.
     987             :          * Mostly used executing query however is a good idea to prepare query
     988             :          * again if parameter type change in an incompatible way (ie different
     989             :          * types or larger size). Is also better to prepare a query knowing
     990             :          * parameter types earlier.
     991             :          */
     992             :         TDSPARAMINFO *params;
     993             :         /** saved query, we need to know original query if prepare is impossible */
     994             :         char *query;
     995             : } TDSDYNAMIC;
     996             : 
     997             : typedef enum {
     998             :         TDS_MULTIPLE_QUERY,
     999             :         TDS_MULTIPLE_EXECUTE,
    1000             :         TDS_MULTIPLE_RPC
    1001             : } TDS_MULTIPLE_TYPE;
    1002             : 
    1003             : typedef struct tds_multiple
    1004             : {
    1005             :         TDS_MULTIPLE_TYPE type;
    1006             :         unsigned int flags;
    1007             : } TDSMULTIPLE;
    1008             : 
    1009             : /* forward declaration */
    1010             : typedef struct tds_context TDSCONTEXT;
    1011             : typedef int (*err_handler_t) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
    1012             : typedef int (*int_handler_t) (void *);
    1013             : 
    1014             : struct tds_context
    1015             : {
    1016             :         TDSLOCALE *locale;
    1017             :         void *parent;
    1018             :         /* handlers */
    1019             :         int (*msg_handler) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
    1020             :         int (*err_handler) (const TDSCONTEXT *, TDSSOCKET *, TDSMESSAGE *);
    1021             :         int (*int_handler) (void *);
    1022             :         bool money_use_2_digits;
    1023             : };
    1024             : 
    1025             : enum TDS_ICONV_ENTRY
    1026             : { 
    1027             :           client2ucs2
    1028             :         , client2server_chardata
    1029             :         , initial_char_conv_count       /* keep last */
    1030             : };
    1031             : 
    1032             : typedef struct tds_authentication
    1033             : {
    1034             :         uint8_t *packet;
    1035             :         int packet_len;
    1036             :         /* TDS_MSG_TOKEN type, for TDS5 */
    1037             :         uint16_t msg_type;
    1038             :         TDSRET (*free)(TDSCONNECTION* conn, struct tds_authentication * auth);
    1039             :         TDSRET (*handle_next)(TDSSOCKET * tds, struct tds_authentication * auth, size_t len);
    1040             : } TDSAUTHENTICATION;
    1041             : 
    1042             : typedef struct tds_packet
    1043             : {
    1044             :         struct tds_packet *next;
    1045             :         uint16_t sid;
    1046             : 
    1047             : #if ENABLE_ODBC_MARS
    1048             :         /**
    1049             :          * Data before TDS data, currently can be 0 or sizeof(TDS72_SMP_HEADER)
    1050             :          */
    1051             :         uint8_t data_start;
    1052             : #endif
    1053             : 
    1054             :         /**
    1055             :          * data length, this does not account SMP header, only TDS part
    1056             :          */
    1057             :         unsigned data_len;
    1058             :         unsigned capacity;
    1059             :         unsigned char buf[1];
    1060             : } TDSPACKET;
    1061             : 
    1062             : #if ENABLE_ODBC_MARS
    1063             : #define tds_packet_zero_data_start(pkt) do { (pkt)->data_start = 0; } while(0)
    1064             : #define tds_packet_get_data_start(pkt) ((pkt)->data_start)
    1065             : #else
    1066             : #define tds_packet_zero_data_start(pkt) do { } while(0)
    1067             : #define tds_packet_get_data_start(pkt) 0
    1068             : #endif
    1069             : 
    1070             : typedef struct tds_poll_wakeup
    1071             : {
    1072             :         TDS_SYS_SOCKET s_signal, s_signaled;
    1073             : } TDSPOLLWAKEUP;
    1074             : 
    1075             : /* field related to connection */
    1076             : struct tds_connection
    1077             : {
    1078             :         TDS_USMALLINT tds_version;
    1079             :         TDS_UINT product_version;       /**< version of product (Sybase/MS and full version) */
    1080             :         char *product_name;
    1081             : 
    1082             :         TDS_SYS_SOCKET s;               /**< tcp socket, INVALID_SOCKET if not connected */
    1083             :         TDSPOLLWAKEUP wakeup;
    1084             :         const TDSCONTEXT *tds_ctx;
    1085             : 
    1086             :         /** environment is shared between all sessions */
    1087             :         TDSENV env;
    1088             : 
    1089             :         /**
    1090             :          * linked list of cursors allocated for this connection
    1091             :          * contains only cursors allocated on the server
    1092             :          */
    1093             :         TDSCURSOR *cursors;
    1094             :         /**
    1095             :          * list of dynamic allocated for this connection
    1096             :          * contains only dynamic allocated on the server
    1097             :          */
    1098             :         TDSDYNAMIC *dyns;
    1099             : 
    1100             :         int char_conv_count;
    1101             :         TDSICONV **char_convs;
    1102             : 
    1103             :         TDS_UCHAR collation[5];
    1104             :         TDS_UCHAR tds72_transaction[8];
    1105             : 
    1106             :         TDS_CAPABILITIES capabilities;
    1107             :         unsigned int use_iconv:1;
    1108             :         unsigned int tds71rev1:1;
    1109             :         unsigned int pending_close:1;   /**< true is connection has pending closing (cursors or dynamic) */
    1110             :         unsigned int encrypt_single_packet:1;
    1111             : #if ENABLE_ODBC_MARS
    1112             :         unsigned int mars:1;
    1113             : 
    1114             :         TDSSOCKET *in_net_tds;
    1115             :         TDSPACKET *packets;
    1116             :         TDSPACKET *recv_packet;
    1117             :         TDSPACKET *send_packets;
    1118             :         unsigned send_pos, recv_pos;
    1119             : 
    1120             : #define BUSY_SOCKET ((TDSSOCKET*)(TDS_UINTPTR)1)
    1121             : #define TDSSOCKET_VALID(tds) (((TDS_UINTPTR)(tds)) > 1)
    1122             :         struct tds_socket **sessions;
    1123             :         unsigned num_sessions;
    1124             : #endif
    1125             :         tds_mutex list_mtx;
    1126             : 
    1127             :         unsigned num_cached_packets;
    1128             :         TDSPACKET *packet_cache;
    1129             : 
    1130             :         int spid;
    1131             :         int client_spid;
    1132             : 
    1133             :         /**
    1134             :          * Ratio between bytes allocated for a NCHAR type and type length (Sybase).
    1135             :          * For instance in case a NVARCHAR(3) takes 9 bytes it's 3.
    1136             :          */
    1137             :         uint8_t ncharsize;
    1138             : 
    1139             :         /**
    1140             :          * Ratio between bytes allocated for a UNICHAR type and type length (Sybase).
    1141             :          * For instance in case a UNIVARCHAR(2) takes 4 bytes it's 2.
    1142             :          * It really should be only 2.
    1143             :          */
    1144             :         uint8_t unicharsize;
    1145             : 
    1146             :         void *tls_session;
    1147             : #if defined(HAVE_GNUTLS)
    1148             :         void *tls_credentials;
    1149             : #elif defined(HAVE_OPENSSL)
    1150             :         void *tls_ctx;
    1151             : #else
    1152             :         void *tls_dummy;
    1153             : #endif
    1154             :         TDSAUTHENTICATION *authentication;
    1155             :         char *server;
    1156             : };
    1157             : 
    1158             : /**
    1159             :  * Information for a server connection
    1160             :  */
    1161             : struct tds_socket
    1162             : {
    1163             : #if ENABLE_ODBC_MARS
    1164             :         TDSCONNECTION *conn;
    1165             : #else
    1166             :         TDSCONNECTION conn[1];
    1167             : #endif
    1168             : 
    1169             :         void *parent;
    1170             : 
    1171             :         /** Input buffer.
    1172             :          * Points to receiving packet buffer.
    1173             :          * As input buffer contains just the raw packet actually this pointer
    1174             :          * is the address of recv_packet->buf.
    1175             :          */
    1176             :         unsigned char *in_buf;
    1177             : 
    1178             :         /** Output buffer.
    1179             :          * Points to sending packet buffer.
    1180             :          * Output buffer can contain additional data before the raw TDS packet
    1181             :          * so this buffer can point some bytes after send_packet->buf.
    1182             :          * Specifically this will point to send_packet->buf + send_packet->data_start.
    1183             :          */
    1184             :         unsigned char *out_buf;
    1185             : 
    1186             :         /** Maximum size of packet pointed by out_buf.
    1187             :          * The buffer is actually a bit larger to make possible to do some
    1188             :          * optimizations (at least TDS_ADDITIONAL_SPACE bytes).
    1189             :          */
    1190             :         unsigned int out_buf_max;
    1191             :         unsigned in_pos;                /**< current position in in_buf */
    1192             :         unsigned out_pos;               /**< current position in out_buf */
    1193             :         unsigned in_len;                /**< input buffer length */
    1194             :         unsigned char in_flag;          /**< input buffer type */
    1195             :         unsigned char out_flag;         /**< output buffer type */
    1196             : 
    1197             :         unsigned frozen;
    1198             :         /**
    1199             :          * list of packets frozen, points to first one.
    1200             :          * send_packet is the last packet in the list.
    1201             :          */
    1202             :         TDSPACKET *frozen_packets;
    1203             : 
    1204             : #if ENABLE_ODBC_MARS
    1205             :         /** SID of MARS session.
    1206             :          * ==0  Not in a MARS session or first session
    1207             :          * >0   SID of MARS session valid.
    1208             :          */
    1209             :         uint16_t sid;
    1210             : 
    1211             :         /**
    1212             :          * This condition will be signaled by the network thread on packet
    1213             :          * received or sent for this session
    1214             :          */
    1215             :         tds_condition packet_cond;
    1216             : 
    1217             :         /**
    1218             :          * Packet we are trying to send to network.
    1219             :          * This field should be protected by conn->list_mtx
    1220             :          */
    1221             :         TDSPACKET *sending_packet;
    1222             :         TDS_UINT recv_seq;
    1223             :         TDS_UINT send_seq;
    1224             :         TDS_UINT recv_wnd;
    1225             :         TDS_UINT send_wnd;
    1226             : #endif
    1227             :         /* packet we received */
    1228             :         TDSPACKET *recv_packet;
    1229             :         /** packet we are preparing to send */
    1230             :         TDSPACKET *send_packet;
    1231             : 
    1232             :         /**
    1233             :          * Current query information. 
    1234             :          * Contains information in process, both normal and compute results.
    1235             :          * This pointer shouldn't be freed; it's just an alias to another structure.
    1236             :          */
    1237             :         TDSRESULTINFO *current_results;
    1238             :         TDSRESULTINFO *res_info;
    1239             :         TDS_UINT num_comp_info;
    1240             :         TDSCOMPUTEINFO **comp_info;
    1241             :         TDSPARAMINFO *param_info;
    1242             :         TDSCURSOR *cur_cursor;          /**< cursor in use */
    1243             :         bool bulk_query;                /**< true is query sent was a bulk query so we need to switch state to QUERYING */
    1244             :         bool has_status;                /**< true is ret_status is valid */
    1245             :         bool in_row;                    /**< true if we are getting rows */
    1246             :         volatile 
    1247             :         unsigned char in_cancel;        /**< indicate we are waiting a cancel reply; discard tokens till acknowledge; 
    1248             :         1 mean we have to send cancel packet, 2 already sent. */
    1249             :         TDS_INT ret_status;             /**< return status from store procedure */
    1250             :         TDS_STATE state;
    1251             : 
    1252             :         TDS_INT query_timeout;
    1253             :         TDS_INT8 rows_affected;         /**< rows updated/deleted/inserted/selected, TDS_NO_COUNT if not valid */
    1254             : 
    1255             :         TDSDYNAMIC *cur_dyn;            /**< dynamic structure in use */
    1256             : 
    1257             :         TDSLOGIN *login;        /**< config for login stuff. After login this field is NULL */
    1258             : 
    1259             :         void (*env_chg_func) (TDSSOCKET * tds, int type, char *oldval, char *newval);
    1260             :         TDS_OPERATION current_op;
    1261             : 
    1262             :         int option_value;
    1263             :         tds_mutex wire_mtx;
    1264             : };
    1265             : 
    1266             : #define tds_get_ctx(tds) ((tds)->conn->tds_ctx)
    1267             : #define tds_set_ctx(tds, val) do { ((tds)->conn->tds_ctx) = (val); } while(0)
    1268             : #define tds_get_parent(tds) ((tds)->parent)
    1269             : #define tds_set_parent(tds, val) do { ((tds)->parent) = (val); } while(0)
    1270             : #define tds_get_s(tds) ((tds)->conn->s)
    1271             : #define tds_set_s(tds, val) do { ((tds)->conn->s) = (val); } while(0)
    1272             : 
    1273             : typedef struct tds_tvp_row
    1274             : {
    1275             :         TDSPARAMINFO *params;
    1276             :         struct tds_tvp_row *next;
    1277             : } TDS_TVP_ROW;
    1278             : 
    1279             : typedef struct tds_tvp
    1280             : {
    1281             :         char *schema;
    1282             :         char *name;
    1283             :         TDSPARAMINFO *metadata;
    1284             :         TDS_TVP_ROW *row;
    1285             : } TDS_TVP;
    1286             : 
    1287             : 
    1288             : /* config.c */
    1289             : const TDS_COMPILETIME_SETTINGS *tds_get_compiletime_settings(void);
    1290             : typedef bool (*TDSCONFPARSE) (const char *option, const char *value, void *param);
    1291             : bool tds_read_conf_section(FILE * in, const char *section, TDSCONFPARSE tds_conf_parse, void *parse_param);
    1292             : bool tds_read_conf_file(TDSLOGIN * login, const char *server);
    1293             : bool tds_parse_conf_section(const char *option, const char *value, void *param);
    1294             : TDSLOGIN *tds_read_config_info(TDSSOCKET * tds, TDSLOGIN * login, TDSLOCALE * locale);
    1295             : void tds_fix_login(TDSLOGIN* login);
    1296             : TDS_USMALLINT * tds_config_verstr(const char *tdsver, TDSLOGIN* login);
    1297             : struct addrinfo *tds_lookup_host(const char *servername);
    1298             : TDSRET tds_lookup_host_set(const char *servername, struct addrinfo **addr);
    1299             : const char *tds_addrinfo2str(struct addrinfo *addr, char *name, int namemax);
    1300             : 
    1301             : TDSRET tds_set_interfaces_file_loc(const char *interfloc);
    1302             : extern const char STD_DATETIME_FMT[];
    1303             : int tds_parse_boolean(const char *value, int default_value);
    1304             : int tds_config_boolean(const char *option, const char *value, TDSLOGIN * login);
    1305             : 
    1306             : TDSLOCALE *tds_get_locale(void);
    1307             : TDSRET tds_alloc_row(TDSRESULTINFO * res_info);
    1308             : TDSRET tds_alloc_compute_row(TDSCOMPUTEINFO * res_info);
    1309             : BCPCOLDATA * tds_alloc_bcp_column_data(unsigned int column_size);
    1310             : TDSDYNAMIC *tds_lookup_dynamic(TDSCONNECTION * conn, const char *id);
    1311             : /*@observer@*/ const char *tds_prtype(int token);
    1312             : int tds_get_varint_size(TDSCONNECTION * conn, int datatype);
    1313             : TDS_SERVER_TYPE tds_get_cardinal_type(TDS_SERVER_TYPE datatype, int usertype);
    1314             : TDSRET tds8_adjust_login(TDSLOGIN *login);
    1315             : 
    1316             : 
    1317             : /* iconv.c */
    1318             : TDSRET tds_iconv_open(TDSCONNECTION * conn, const char *charset, int use_utf16);
    1319             : void tds_iconv_close(TDSCONNECTION * conn);
    1320             : void tds_srv_charset_changed(TDSCONNECTION * conn, const char *charset);
    1321             : void tds7_srv_charset_changed(TDSCONNECTION * conn, TDS_UCHAR collate[5]);
    1322             : int tds_iconv_alloc(TDSCONNECTION * conn);
    1323             : void tds_iconv_free(TDSCONNECTION * conn);
    1324             : TDSICONV *tds_iconv_from_collate(TDSCONNECTION * conn, TDS_UCHAR collate[5]);
    1325             : 
    1326             : 
    1327             : /* mem.c */
    1328             : void tds_free_socket(TDSSOCKET * tds);
    1329             : void tds_free_all_results(TDSSOCKET * tds);
    1330             : void tds_free_results(TDSRESULTINFO * res_info);
    1331             : void tds_free_param_results(TDSPARAMINFO * param_info);
    1332             : void tds_free_param_result(TDSPARAMINFO * param_info);
    1333             : void tds_free_msg(TDSMESSAGE * message);
    1334             : void tds_cursor_deallocated(TDSCONNECTION *conn, TDSCURSOR *cursor);
    1335             : void tds_release_cursor(TDSCURSOR **pcursor);
    1336             : void tds_free_bcp_column_data(BCPCOLDATA * coldata);
    1337             : TDSRESULTINFO *tds_alloc_results(TDS_USMALLINT num_cols);
    1338             : TDSCOMPUTEINFO **tds_alloc_compute_results(TDSSOCKET * tds, TDS_USMALLINT num_cols, TDS_USMALLINT by_cols);
    1339             : TDSCONTEXT *tds_alloc_context(void * parent);
    1340             : void tds_free_context(TDSCONTEXT * locale);
    1341             : TDSPARAMINFO *tds_alloc_param_result(TDSPARAMINFO * old_param);
    1342             : void tds_free_input_params(TDSDYNAMIC * dyn);
    1343             : void tds_release_dynamic(TDSDYNAMIC ** dyn);
    1344             : inline static void
    1345             : tds_release_cur_dyn(TDSSOCKET * tds)
    1346             : {
    1347       70530 :         tds_release_dynamic(&tds->cur_dyn);
    1348             : }
    1349             : void tds_dynamic_deallocated(TDSCONNECTION *conn, TDSDYNAMIC *dyn);
    1350             : void tds_set_cur_dyn(TDSSOCKET *tds, TDSDYNAMIC *dyn);
    1351             : TDSSOCKET *tds_realloc_socket(TDSSOCKET * tds, size_t bufsize);
    1352             : char *tds_alloc_client_sqlstate(int msgno);
    1353             : char *tds_alloc_lookup_sqlstate(TDSSOCKET * tds, int msgno);
    1354             : TDSLOGIN *tds_alloc_login(bool use_environment);
    1355             : TDSDYNAMIC *tds_alloc_dynamic(TDSCONNECTION * conn, const char *id);
    1356             : void tds_free_login(TDSLOGIN * login);
    1357             : TDSLOGIN *tds_init_login(TDSLOGIN * login, TDSLOCALE * locale);
    1358             : TDSLOCALE *tds_alloc_locale(void);
    1359             : void *tds_alloc_param_data(TDSCOLUMN * curparam);
    1360             : void tds_free_locale(TDSLOCALE * locale);
    1361             : TDSCURSOR * tds_alloc_cursor(TDSSOCKET * tds, const char *name, TDS_INT namelen, const char *query, TDS_INT querylen);
    1362             : void tds_free_row(TDSRESULTINFO * res_info, unsigned char *row);
    1363             : TDSSOCKET *tds_alloc_socket(TDSCONTEXT * context, unsigned int bufsize);
    1364             : TDSSOCKET *tds_alloc_additional_socket(TDSCONNECTION *conn);
    1365             : void tds_set_current_results(TDSSOCKET *tds, TDSRESULTINFO *info);
    1366             : void tds_detach_results(TDSRESULTINFO *info);
    1367             : void * tds_realloc(void **pp, size_t new_size);
    1368             : #define TDS_RESIZE(p, n_elem) \
    1369             :         tds_realloc((void **) &(p), sizeof(*(p)) * (size_t) (n_elem))
    1370             : 
    1371             : TDSPACKET *tds_alloc_packet(void *buf, unsigned len);
    1372             : TDSPACKET *tds_realloc_packet(TDSPACKET *packet, unsigned len);
    1373             : void tds_free_packets(TDSPACKET *packet);
    1374             : TDSBCPINFO *tds_alloc_bcpinfo(void);
    1375             : void tds_free_bcpinfo(TDSBCPINFO *bcpinfo);
    1376             : void tds_deinit_bcpinfo(TDSBCPINFO *bcpinfo);
    1377             : void tds_deinit_tvp(TDS_TVP *table);
    1378             : 
    1379             : 
    1380             : /* login.c */
    1381             : void tds_set_packet(TDSLOGIN * tds_login, int packet_size);
    1382             : void tds_set_port(TDSLOGIN * tds_login, int port);
    1383             : bool tds_set_passwd(TDSLOGIN * tds_login, const char *password) TDS_WUR;
    1384             : void tds_set_bulk(TDSLOGIN * tds_login, bool enabled);
    1385             : bool tds_set_user(TDSLOGIN * tds_login, const char *username) TDS_WUR;
    1386             : bool tds_set_app(TDSLOGIN * tds_login, const char *application) TDS_WUR;
    1387             : bool tds_set_host(TDSLOGIN * tds_login, const char *hostname) TDS_WUR;
    1388             : bool tds_set_library(TDSLOGIN * tds_login, const char *library) TDS_WUR;
    1389             : bool tds_set_server(TDSLOGIN * tds_login, const char *server) TDS_WUR;
    1390             : bool tds_set_client_charset(TDSLOGIN * tds_login, const char *charset) TDS_WUR;
    1391             : bool tds_set_language(TDSLOGIN * tds_login, const char *language) TDS_WUR;
    1392             : void tds_set_version(TDSLOGIN * tds_login, TDS_TINYINT major_ver, TDS_TINYINT minor_ver);
    1393             : TDSRET tds_connect_and_login(TDSSOCKET * tds, TDSLOGIN * login);
    1394             : 
    1395             : 
    1396             : /* query.c */
    1397             : void tds_start_query(TDSSOCKET *tds, unsigned char packet_type);
    1398             : 
    1399             : TDSRET tds_submit_query(TDSSOCKET * tds, const char *query);
    1400             : TDSRET tds_submit_query_params(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params, TDSHEADERS * head);
    1401             : TDSRET tds_submit_queryf(TDSSOCKET * tds, const char *queryf, ...);
    1402             : TDSRET tds_submit_prepare(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
    1403             : TDSRET tds_submit_execdirect(TDSSOCKET * tds, const char *query, TDSPARAMINFO * params, TDSHEADERS * head);
    1404             : TDSRET tds71_submit_prepexec(TDSSOCKET * tds, const char *query, const char *id, TDSDYNAMIC ** dyn_out, TDSPARAMINFO * params);
    1405             : TDSRET tds_submit_execute(TDSSOCKET * tds, TDSDYNAMIC * dyn);
    1406             : TDSRET tds_send_cancel(TDSSOCKET * tds);
    1407             : const char *tds_next_placeholder(const char *start);
    1408             : int tds_count_placeholders(const char *query);
    1409             : int tds_needs_unprepare(TDSCONNECTION * conn, TDSDYNAMIC * dyn);
    1410             : TDSRET tds_deferred_unprepare(TDSCONNECTION * conn, TDSDYNAMIC * dyn);
    1411             : TDSRET tds_submit_unprepare(TDSSOCKET * tds, TDSDYNAMIC * dyn);
    1412             : TDSRET tds_submit_rpc(TDSSOCKET * tds, const char *rpc_name, TDSPARAMINFO * params, TDSHEADERS * head);
    1413             : TDSRET tds_submit_optioncmd(TDSSOCKET * tds, TDS_OPTION_CMD command, TDS_OPTION option, TDS_OPTION_ARG *param, TDS_INT param_size);
    1414             : TDSRET tds_submit_begin_tran(TDSSOCKET *tds);
    1415             : TDSRET tds_submit_rollback(TDSSOCKET *tds, bool cont);
    1416             : TDSRET tds_submit_commit(TDSSOCKET *tds, bool cont);
    1417             : TDSRET tds_disconnect(TDSSOCKET * tds);
    1418             : size_t tds_quote_id(TDSSOCKET * tds, char *buffer, const char *id, int idlen);
    1419             : size_t tds_quote_id_rpc(TDSSOCKET * tds, char *buffer, const char *id, int idlen);
    1420             : size_t tds_quote_string(TDSSOCKET * tds, char *buffer, const char *str, int len);
    1421             : const char *tds_skip_comment(const char *s);
    1422             : const char *tds_skip_quoted(const char *s);
    1423             : size_t tds_fix_column_size(TDSSOCKET * tds, TDSCOLUMN * curcol);
    1424             : const char *tds_convert_string(TDSSOCKET * tds, TDSICONV * char_conv, const char *s, int len, size_t *out_len);
    1425             : void tds_convert_string_free(const char *original, const char *converted);
    1426             : #if !ENABLE_EXTRA_CHECKS
    1427             : #define tds_convert_string_free(original, converted) \
    1428             :         do { if (original != converted) free((char*) converted); } while(0)
    1429             : #endif
    1430             : TDSRET tds_get_column_declaration(TDSSOCKET * tds, TDSCOLUMN * curcol, char *out);
    1431             : 
    1432             : TDSRET tds_cursor_declare(TDSSOCKET * tds, TDSCURSOR * cursor, bool *send);
    1433             : TDSRET tds_cursor_setrows(TDSSOCKET * tds, TDSCURSOR * cursor, bool *send);
    1434             : TDSRET tds_cursor_open(TDSSOCKET * tds, TDSCURSOR * cursor, TDSPARAMINFO *params, bool *send);
    1435             : TDSRET tds_cursor_fetch(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_FETCH fetch_type, TDS_INT i_row);
    1436             : TDSRET tds_cursor_get_cursor_info(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_UINT * row_number, TDS_UINT * row_count);
    1437             : TDSRET tds_cursor_close(TDSSOCKET * tds, TDSCURSOR * cursor);
    1438             : TDSRET tds_cursor_dealloc(TDSSOCKET * tds, TDSCURSOR * cursor);
    1439             : TDSRET tds_deferred_cursor_dealloc(TDSCONNECTION *conn, TDSCURSOR * cursor);
    1440             : TDSRET tds_cursor_update(TDSSOCKET * tds, TDSCURSOR * cursor, TDS_CURSOR_OPERATION op, TDS_INT i_row, TDSPARAMINFO * params);
    1441             : TDSRET tds_cursor_setname(TDSSOCKET * tds, TDSCURSOR * cursor);
    1442             : 
    1443             : TDSRET tds_multiple_init(TDSSOCKET *tds, TDSMULTIPLE *multiple, TDS_MULTIPLE_TYPE type, TDSHEADERS * head);
    1444             : TDSRET tds_multiple_done(TDSSOCKET *tds, TDSMULTIPLE *multiple);
    1445             : TDSRET tds_multiple_query(TDSSOCKET *tds, TDSMULTIPLE *multiple, const char *query, TDSPARAMINFO * params);
    1446             : TDSRET tds_multiple_execute(TDSSOCKET *tds, TDSMULTIPLE *multiple, TDSDYNAMIC * dyn);
    1447             : 
    1448             : 
    1449             : /* token.c */
    1450             : TDSRET tds_process_cancel(TDSSOCKET * tds);
    1451             : TDSRET tds_process_login_tokens(TDSSOCKET * tds);
    1452             : TDSRET tds_process_simple_query(TDSSOCKET * tds);
    1453             : int tds5_send_optioncmd(TDSSOCKET * tds, TDS_OPTION_CMD tds_command, TDS_OPTION tds_option, TDS_OPTION_ARG * tds_argument,
    1454             :                         TDS_INT * tds_argsize);
    1455             : TDSRET tds_process_tokens(TDSSOCKET * tds, /*@out@*/ TDS_INT * result_type, /*@out@*/ int *done_flags, unsigned flag);
    1456             : 
    1457             : 
    1458             : /* data.c */
    1459             : void tds_set_param_type(TDSCONNECTION * conn, TDSCOLUMN * curcol, TDS_SERVER_TYPE type);
    1460             : void tds_set_column_type(TDSCONNECTION * conn, TDSCOLUMN * curcol, TDS_SERVER_TYPE type);
    1461             : #ifdef WORDS_BIGENDIAN
    1462             : void tds_swap_datatype(int coltype, void *b);
    1463             : #endif
    1464             : 
    1465             : 
    1466             : /* tds_convert.c */
    1467             : TDSRET tds_datecrack(TDS_INT datetype, const void *di, TDSDATEREC * dr);
    1468             : TDS_SERVER_TYPE tds_get_conversion_type(TDS_SERVER_TYPE srctype, int colsize);
    1469             : extern const char tds_hex_digits[];
    1470             : 
    1471             : 
    1472             : /* write.c */
    1473             : int tds_init_write_buf(TDSSOCKET * tds);
    1474             : int tds_put_n(TDSSOCKET * tds, const void *buf, size_t n);
    1475             : int tds_put_string(TDSSOCKET * tds, const char *buf, int len);
    1476             : int tds_put_int(TDSSOCKET * tds, TDS_INT i);
    1477             : int tds_put_int8(TDSSOCKET * tds, TDS_INT8 i);
    1478             : int tds_put_smallint(TDSSOCKET * tds, TDS_SMALLINT si);
    1479             : /** Output a tinyint value */
    1480             : #define tds_put_tinyint(tds, ti) tds_put_byte(tds,ti)
    1481             : int tds_put_byte(TDSSOCKET * tds, unsigned char c);
    1482             : TDSRET tds_flush_packet(TDSSOCKET * tds);
    1483             : int tds_put_buf(TDSSOCKET * tds, const unsigned char *buf, int dsize, int ssize);
    1484             : 
    1485             : 
    1486             : /* read.c */
    1487             : unsigned char tds_get_byte(TDSSOCKET * tds);
    1488             : void tds_unget_byte(TDSSOCKET * tds);
    1489             : unsigned char tds_peek(TDSSOCKET * tds);
    1490             : TDS_USMALLINT tds_get_usmallint(TDSSOCKET * tds);
    1491             : #define tds_get_smallint(tds) ((TDS_SMALLINT) tds_get_usmallint(tds))
    1492             : TDS_UINT tds_get_uint(TDSSOCKET * tds);
    1493             : #define tds_get_int(tds) ((TDS_INT) tds_get_uint(tds))
    1494             : TDS_UINT8 tds_get_uint8(TDSSOCKET * tds);
    1495             : #define tds_get_int8(tds) ((TDS_INT8) tds_get_uint8(tds))
    1496             : size_t tds_get_string(TDSSOCKET * tds, size_t string_len, char *dest, size_t dest_size);
    1497             : TDSRET tds_get_char_data(TDSSOCKET * tds, char *dest, size_t wire_size, TDSCOLUMN * curcol);
    1498             : bool tds_get_n(TDSSOCKET * tds, /*@out@*/ /*@null@*/ void *dest, size_t n);
    1499             : int tds_get_size_by_type(TDS_SERVER_TYPE servertype);
    1500             : DSTR* tds_dstr_get(TDSSOCKET * tds, DSTR * s, size_t len);
    1501             : 
    1502             : 
    1503             : /* util.c */
    1504             : int tdserror (const TDSCONTEXT * tds_ctx, TDSSOCKET * tds, int msgno, int errnum);
    1505             : TDS_STATE tds_set_state(TDSSOCKET * tds, TDS_STATE state);
    1506             : void tds_swap_bytes(void *buf, int bytes);
    1507             : unsigned int tds_gettime_ms(void);
    1508             : 
    1509             : 
    1510             : /* log.c */
    1511             : typedef struct tdsdump_off_item {
    1512             :         struct tdsdump_off_item *next;
    1513             :         tds_thread_id thread_id;
    1514             : } TDSDUMP_OFF_ITEM;
    1515             : void tdsdump_off(TDSDUMP_OFF_ITEM *off_item);
    1516             : void tdsdump_on(TDSDUMP_OFF_ITEM *off_item);
    1517             : int tdsdump_isopen(void);
    1518             : #include <freetds/popvis.h>
    1519             : int tdsdump_open(const tds_dir_char *filename);
    1520             : #include <freetds/pushvis.h>
    1521             : void tdsdump_close(void);
    1522             : void tdsdump_dump_buf(const char* file, unsigned int level_line, const char *msg, const void *buf, size_t length);
    1523             : void tdsdump_col(const TDSCOLUMN *col);
    1524             : #undef tdsdump_log
    1525             : void tdsdump_log(const char* file, unsigned int level_line, const char *fmt, ...)
    1526             : #if defined(__GNUC__) && __GNUC__ >= 2
    1527             : #if defined(__MINGW32__)
    1528             :         __attribute__ ((__format__ (ms_printf, 3, 4)))
    1529             : #else
    1530             :         __attribute__ ((__format__ (__printf__, 3, 4)))
    1531             : #endif
    1532             : #endif
    1533             : ;
    1534             : #define TDSDUMP_LOG_FAST if (TDS_UNLIKELY(tds_write_dump)) tdsdump_log
    1535             : #define tdsdump_log TDSDUMP_LOG_FAST
    1536             : #define TDSDUMP_BUF_FAST if (TDS_UNLIKELY(tds_write_dump)) tdsdump_dump_buf
    1537             : #define tdsdump_dump_buf TDSDUMP_BUF_FAST
    1538             : 
    1539             : extern bool tds_write_dump;
    1540             : extern int tds_debug_flags;
    1541             : extern int tds_append_mode;
    1542             : 
    1543             : 
    1544             : /* net.c */
    1545             : TDSERRNO tds_open_socket(TDSSOCKET * tds, struct addrinfo *ipaddr, unsigned int port, int timeout, int *p_oserr);
    1546             : void tds_close_socket(TDSSOCKET * tds);
    1547             : int tds7_get_instance_ports(FILE *output, struct addrinfo *addr);
    1548             : int tds7_get_instance_port(struct addrinfo *addr, const char *instance);
    1549             : char *tds_prwsaerror(int erc);
    1550             : void tds_prwsaerror_free(char *s);
    1551             : int tds_connection_read(TDSSOCKET * tds, unsigned char *buf, int buflen);
    1552             : int tds_connection_write(TDSSOCKET *tds, const unsigned char *buf, int buflen, int final);
    1553             : #define TDSSELREAD  POLLIN
    1554             : #define TDSSELWRITE POLLOUT
    1555             : int tds_select(TDSSOCKET * tds, unsigned tds_sel, int timeout_seconds);
    1556             : void tds_connection_close(TDSCONNECTION *conn);
    1557             : int tds_goodread(TDSSOCKET * tds, unsigned char *buf, int buflen);
    1558             : int tds_goodwrite(TDSSOCKET * tds, const unsigned char *buffer, size_t buflen);
    1559             : void tds_socket_flush(TDS_SYS_SOCKET sock);
    1560             : int tds_socket_set_nonblocking(TDS_SYS_SOCKET sock);
    1561             : int tds_wakeup_init(TDSPOLLWAKEUP *wakeup);
    1562             : void tds_wakeup_close(TDSPOLLWAKEUP *wakeup);
    1563             : void tds_wakeup_send(TDSPOLLWAKEUP *wakeup, char cancel);
    1564             : inline static TDS_SYS_SOCKET
    1565             : tds_wakeup_get_fd(const TDSPOLLWAKEUP *wakeup)
    1566             : {
    1567             :         return wakeup->s_signaled;
    1568             : }
    1569             : 
    1570             : 
    1571             : /* packet.c */
    1572             : int tds_read_packet(TDSSOCKET * tds);
    1573             : TDSRET tds_write_packet(TDSSOCKET * tds, unsigned char final);
    1574             : #if ENABLE_ODBC_MARS
    1575             : int tds_append_cancel(TDSSOCKET *tds);
    1576             : TDSRET tds_append_syn(TDSSOCKET *tds);
    1577             : TDSRET tds_append_fin(TDSSOCKET *tds);
    1578             : #else
    1579             : int tds_put_cancel(TDSSOCKET * tds);
    1580             : #endif
    1581             : 
    1582             : typedef struct tds_freeze {
    1583             :         /** which socket we refer to */
    1584             :         TDSSOCKET *tds;
    1585             :         /** first packet frozen */
    1586             :         TDSPACKET *pkt;
    1587             :         /** position in pkt */
    1588             :         unsigned pkt_pos;
    1589             :         /** length size (0, 1, 2 or 4) */
    1590             :         unsigned size_len;
    1591             : } TDSFREEZE;
    1592             : 
    1593             : void tds_freeze(TDSSOCKET *tds, TDSFREEZE *freeze, unsigned size_len);
    1594             : size_t tds_freeze_written(TDSFREEZE *freeze);
    1595             : TDSRET tds_freeze_abort(TDSFREEZE *freeze);
    1596             : TDSRET tds_freeze_close(TDSFREEZE *freeze);
    1597             : TDSRET tds_freeze_close_string(TDSFREEZE *freeze);
    1598             : TDSRET tds_freeze_close_len(TDSFREEZE *freeze, int32_t size);
    1599             : 
    1600             : inline static void
    1601             : tds_set_current_send_packet(TDSSOCKET *tds, TDSPACKET *pkt)
    1602             : {
    1603       46995 :         tds->send_packet = pkt;
    1604       46995 :         tds->out_buf = pkt->buf + tds_packet_get_data_start(pkt);
    1605             : }
    1606             : 
    1607             : /* Macros to allow some indentation of the packets.
    1608             :  *
    1609             :  * The 3 nested fake loops require some explanation:
    1610             :  * - first is to allows to declare variables;
    1611             :  * - second is to force using brackets;
    1612             :  * - third is to avoids that a break inside will skip the close.
    1613             :  */
    1614             : #define TDS_START_LEN_GENERIC(tds_socket, len) do { \
    1615             :         TDSFREEZE current_freeze[1]; \
    1616             :         tds_freeze((tds_socket), current_freeze, (len)); do { do
    1617             : #define TDS_END_LEN while(0); } while(tds_freeze_close(current_freeze), 0); } while(0);
    1618             : #define TDS_END_LEN_STRING while(0); } while(tds_freeze_close_string(current_freeze), 0); } while(0);
    1619             : 
    1620             : #define TDS_START_LEN_TINYINT(tds_socket) TDS_START_LEN_GENERIC(tds_socket, 1)
    1621             : #define TDS_START_LEN_USMALLINT(tds_socket) TDS_START_LEN_GENERIC(tds_socket, 2)
    1622             : #define TDS_START_LEN_UINT(tds_socket) TDS_START_LEN_GENERIC(tds_socket, 4)
    1623             : 
    1624             : /* vstrbuild.c */
    1625             : TDSRET tds_vstrbuild(char *buffer, int buflen, int *resultlen, const char *text, int textlen, const char *formats, int formatlen,
    1626             :                   va_list ap);
    1627             : 
    1628             : 
    1629             : /* numeric.c */
    1630             : char *tds_money_to_string(const TDS_MONEY * money, char *s, bool use_2_digits);
    1631             : TDS_INT tds_numeric_to_string(const TDS_NUMERIC * numeric, char *s);
    1632             : TDS_INT tds_numeric_change_prec_scale(TDS_NUMERIC * numeric, unsigned char new_prec, unsigned char new_scale);
    1633             : 
    1634             : 
    1635             : /* getmac.c */
    1636             : void tds_getmac(TDS_SYS_SOCKET s, unsigned char mac[6]);
    1637             : 
    1638             : 
    1639             : /* challenge.c */
    1640             : #ifndef HAVE_SSPI
    1641             : TDSAUTHENTICATION * tds_ntlm_get_auth(TDSSOCKET * tds);
    1642             : TDSAUTHENTICATION * tds_gss_get_auth(TDSSOCKET * tds);
    1643             : #else
    1644             : TDSAUTHENTICATION * tds_sspi_get_auth(TDSSOCKET * tds);
    1645             : #endif
    1646             : TDSRET tds5_gss_send(TDSSOCKET *tds);
    1647             : 
    1648             : 
    1649             : /* random.c */
    1650             : void tds_random_buffer(unsigned char *out, int len);
    1651             : 
    1652             : 
    1653             : /* sec_negotiate.c */
    1654             : TDSAUTHENTICATION * tds5_negotiate_get_auth(TDSSOCKET * tds);
    1655             : inline static void
    1656             : tds5_negotiate_set_msg_type(TDSAUTHENTICATION * tds_auth, unsigned msg_type)
    1657             : {
    1658           0 :         if (tds_auth)
    1659           0 :                 tds_auth->msg_type = msg_type;
    1660             : }
    1661             : 
    1662             : 
    1663             : /* bulk.c */
    1664             : 
    1665             : /** bcp direction */
    1666             : enum tds_bcp_directions
    1667             : {
    1668             :         TDS_BCP_IN = 1,
    1669             :         TDS_BCP_OUT = 2,
    1670             :         TDS_BCP_QUERYOUT = 3
    1671             : };
    1672             : 
    1673             : typedef struct tds5_colinfo
    1674             : {
    1675             :         TDS_TINYINT type;
    1676             :         TDS_TINYINT status;
    1677             :         TDS_SMALLINT offset;
    1678             :         TDS_INT length;
    1679             : } TDS5COLINFO;
    1680             : 
    1681             : struct tds_bcpinfo
    1682             : {
    1683             :         void *parent;
    1684             :         DSTR hint;
    1685             :         DSTR tablename;
    1686             :         TDS_CHAR *insert_stmt;
    1687             :         TDS_INT direction;
    1688             :         TDS_INT identity_insert_on;
    1689             :         TDS_INT xfer_init;
    1690             :         TDS_INT bind_count;
    1691             :         TDSRESULTINFO *bindinfo;
    1692             :         TDS5COLINFO *sybase_colinfo;
    1693             :         TDS_INT sybase_count;
    1694             : };
    1695             : 
    1696             : TDSRET tds_bcp_init(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
    1697             : typedef TDSRET (*tds_bcp_get_col_data) (TDSBCPINFO *bulk, TDSCOLUMN *bcpcol, int offset);
    1698             : typedef void (*tds_bcp_null_error)   (TDSBCPINFO *bulk, int index, int offset);
    1699             : TDSRET tds_bcp_send_record(TDSSOCKET *tds, TDSBCPINFO *bcpinfo, tds_bcp_get_col_data get_col_data, tds_bcp_null_error null_error, int offset);
    1700             : TDSRET tds_bcp_done(TDSSOCKET *tds, int *rows_copied);
    1701             : TDSRET tds_bcp_start(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
    1702             : TDSRET tds_bcp_start_copy_in(TDSSOCKET *tds, TDSBCPINFO *bcpinfo);
    1703             : 
    1704             : TDSRET tds_bcp_fread(TDSSOCKET * tds, TDSICONV * conv, FILE * stream,
    1705             :                      const char *terminator, size_t term_len, char **outbuf, size_t * outbytes);
    1706             : 
    1707             : TDSRET tds_writetext_start(TDSSOCKET *tds, const char *objname, const char *textptr, const char *timestamp, int with_log, TDS_UINT size);
    1708             : TDSRET tds_writetext_continue(TDSSOCKET *tds, const TDS_UCHAR *text, TDS_UINT size);
    1709             : TDSRET tds_writetext_end(TDSSOCKET *tds);
    1710             : 
    1711             : 
    1712             : inline static bool
    1713             : tds_capability_enabled(const TDS_CAPABILITY_TYPE *cap, unsigned cap_num)
    1714             : {
    1715        1982 :         return (cap->values[sizeof(cap->values)-1-(cap_num>>3)] >> (cap_num&7)) & 1;
    1716             : }
    1717             : #define tds_capability_has_req(conn, cap) \
    1718             :         tds_capability_enabled(&conn->capabilities.types[0], cap)
    1719             : #define tds_capability_has_res(conn, cap) \
    1720             :         tds_capability_enabled(&conn->capabilities.types[1], cap)
    1721             : 
    1722             : #define IS_TDS42(x) (x->tds_version==0x402)
    1723             : #define IS_TDS46(x) (x->tds_version==0x406)
    1724             : #define IS_TDS50(x) (x->tds_version==0x500)
    1725             : #define IS_TDS70(x) (x->tds_version==0x700)
    1726             : #define IS_TDS71(x) (x->tds_version==0x701)
    1727             : #define IS_TDS72(x) (x->tds_version==0x702)
    1728             : #define IS_TDS73(x) (x->tds_version==0x703)
    1729             : 
    1730             : #define IS_TDS50_PLUS(x) ((x)->tds_version>=0x500)
    1731             : #define IS_TDS7_PLUS(x)  ((x)->tds_version>=0x700)
    1732             : #define IS_TDS71_PLUS(x) ((x)->tds_version>=0x701)
    1733             : #define IS_TDS72_PLUS(x) ((x)->tds_version>=0x702)
    1734             : #define IS_TDS73_PLUS(x) ((x)->tds_version>=0x703)
    1735             : #define IS_TDS74_PLUS(x) ((x)->tds_version>=0x704)
    1736             : #define IS_TDS80_PLUS(x) ((x)->tds_version>=0x800)
    1737             : 
    1738             : #define TDS_MAJOR(x) ((x)->tds_version >> 8)
    1739             : #define TDS_MINOR(x) ((x)->tds_version & 0xff)
    1740             : 
    1741             : #define IS_TDSDEAD(x) (((x) == NULL) || (x)->state == TDS_DEAD)
    1742             : 
    1743             : /** Check if product is Sybase (such as Adaptive Server Enterprise). x should be a TDSSOCKET*. */
    1744             : #define TDS_IS_SYBASE(x) (!((x)->conn->product_version & 0x80000000u))
    1745             : /** Check if product is Microsoft SQL Server. x should be a TDSSOCKET*. */
    1746             : #define TDS_IS_MSSQL(x) (((x)->conn->product_version & 0x80000000u)!=0)
    1747             : 
    1748             : /** Calc a version number for mssql. Use with TDS_MS_VER(7,0,842).
    1749             :  * For test for a range of version you can use check like
    1750             :  * if (tds->product_version >= TDS_MS_VER(7,0,0) && tds->product_version < TDS_MS_VER(8,0,0)) */
    1751             : #define TDS_MS_VER(maj,min,x) (0x80000000u|((maj)<<24)|((min)<<16)|(x))
    1752             : 
    1753             : /* TODO test if not similar to ms one*/
    1754             : /** Calc a version number for Sybase. */
    1755             : #define TDS_SYB_VER(maj,min,x) (((maj)<<24)|((min)<<16)|(x)<<8)
    1756             : 
    1757             : #ifdef __cplusplus
    1758             : #if 0
    1759             : {
    1760             : #endif
    1761             : }
    1762             : #endif
    1763             : 
    1764             : #include <freetds/popvis.h>
    1765             : 
    1766             : #define TDS_PUT_INT(tds,v) tds_put_int((tds), ((TDS_INT)(v)))
    1767             : #define TDS_PUT_SMALLINT(tds,v) tds_put_smallint((tds), ((TDS_SMALLINT)(v)))
    1768             : #define TDS_PUT_BYTE(tds,v) tds_put_byte((tds), ((unsigned char)(v)))
    1769             : 
    1770             : #endif /* _tdsguard_hfOrWb5znoUCWdBPoNQvqN_ */

Generated by: LCOV version 1.13