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

Generated by: LCOV version 1.13