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