ct.c
上传用户:yhdzpy8989
上传日期:2007-06-13
资源大小:13604k
文件大小:39k
源码类别:

生物技术

开发平台:

C/C++

  1. /*
  2.  * ===========================================================================
  3.  * PRODUCTION $Log: ct.c,v $
  4.  * PRODUCTION Revision 1000.0  2003/10/29 20:33:11  gouriano
  5.  * PRODUCTION PRODUCTION: IMPORTED [ORIGINAL] Dev-tree R1.1
  6.  * PRODUCTION
  7.  * ===========================================================================
  8.  */
  9. /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
  10.  * Copyright (C) 1998-1999  Brian Bruns
  11.  *
  12.  * This library is free software; you can redistribute it and/or
  13.  * modify it under the terms of the GNU Library General Public
  14.  * License as published by the Free Software Foundation; either
  15.  * version 2 of the License, or (at your option) any later version.
  16.  *
  17.  * This library is distributed in the hope that it will be useful,
  18.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  19.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  20.  * Library General Public License for more details.
  21.  *
  22.  * You should have received a copy of the GNU Library General Public
  23.  * License along with this library; if not, write to the
  24.  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  25.  * Boston, MA 02111-1307, USA.
  26.  */
  27. #include <tds_config.h>
  28. #include <stdlib.h>
  29. #include <unistd.h>
  30. #include <ctpublic.h>
  31. #include <ctlib.h>
  32. #include "tdsutil.h"
  33. static char  software_version[]   = "$Id: ct.c,v 1000.0 2003/10/29 20:33:11 gouriano Exp $";
  34. static void *no_unused_var_warn[] = {software_version,
  35.                                      no_unused_var_warn};
  36. /**
  37.  * Read a row of data
  38.  * @return 0 on success
  39.  */
  40. static int _ct_bind_data(CS_COMMAND *cmd);
  41. static int _ct_get_client_type(int datatype, int size);
  42. CS_RETCODE ct_exit(CS_CONTEXT *ctx, CS_INT unused)
  43. {
  44. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_exit()n");
  45. return CS_SUCCEED;
  46. }
  47. CS_RETCODE ct_init(CS_CONTEXT *ctx, CS_INT version)
  48. {
  49. /* uncomment the next line to get pre-login trace */
  50. /* tdsdump_open("/tmp/tds2.log"); */
  51. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_init()n");
  52. ctx->tds_ctx->msg_handler = ctlib_handle_info_message;
  53. ctx->tds_ctx->err_handler = ctlib_handle_err_message;
  54. return CS_SUCCEED;
  55. }
  56. CS_RETCODE ct_con_alloc(CS_CONTEXT *ctx, CS_CONNECTION **con)
  57. {
  58. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_con_alloc()n");
  59. *con = (CS_CONNECTION *) malloc(sizeof(CS_CONNECTION));
  60. memset(*con,'',sizeof(CS_CONNECTION));
  61. (*con)->tds_login = (void *) tds_alloc_login();
  62. /* so we know who we belong to */
  63. (*con)->ctx = ctx;
  64. /* set default values */
  65. tds_set_library((*con)->tds_login, "CT-Library");
  66. /* tds_set_charset((*con)->tds_login, "iso_1"); */
  67. /* tds_set_packet((*con)->tds_login, TDS_DEF_BLKSZ); */
  68. return CS_SUCCEED;
  69. }
  70. CS_RETCODE ct_callback(CS_CONTEXT *ctx, CS_CONNECTION *con, CS_INT action, CS_INT type, CS_VOID *func)
  71. {
  72. int (*funcptr)(void*,void*,void*)=(int (*)(void*,void*,void*))func;
  73. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_callback() action = %sn",
  74. CS_GET ? "CS_GET" : "CS_SET");
  75. /* one of these has to be defined */
  76. if (!ctx && !con) 
  77. return CS_FAIL;
  78. if (action==CS_GET) {
  79. switch(type) {
  80. case CS_CLIENTMSG_CB:
  81. *(void **)func = (CS_VOID *) (con ? con->_clientmsg_cb : ctx->_clientmsg_cb);
  82. return CS_SUCCEED;
  83. case CS_SERVERMSG_CB:
  84. *(void **)func = (CS_VOID *) (con ? con->_servermsg_cb : ctx->_servermsg_cb);
  85. return CS_SUCCEED;
  86. default:
  87. fprintf(stderr,"Unknown callback %dn",type);
  88. *(void **)func = (CS_VOID *) NULL;
  89. return CS_SUCCEED;
  90. }
  91. }
  92. /* CS_SET */
  93. switch(type) {
  94. case CS_CLIENTMSG_CB:
  95. if (con) 
  96. con->_clientmsg_cb = funcptr;
  97. else 
  98. ctx->_clientmsg_cb = funcptr;
  99. break;
  100. case CS_SERVERMSG_CB:
  101. if (con) 
  102. con->_servermsg_cb = funcptr;
  103. else 
  104. ctx->_servermsg_cb = funcptr;
  105. break;
  106. }
  107. return CS_SUCCEED;
  108. }
  109. CS_RETCODE ct_con_props(CS_CONNECTION *con, CS_INT action, CS_INT property,
  110. CS_VOID *buffer, CS_INT buflen, CS_INT *out_len)
  111. {
  112. CS_INT intval = 0, maxcp;
  113. TDSSOCKET *tds;
  114. TDSLOGIN *tds_login;
  115. char *set_buffer = NULL;
  116. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_con_props() action = %s property = %dn",
  117. CS_GET ? "CS_GET" : "CS_SET", property);
  118. tds = con->tds_socket;
  119. tds_login = con->tds_login;
  120. if (action==CS_SET) {
  121. if (property == CS_USERNAME || property == CS_PASSWORD
  122.  || property == CS_APPNAME  || property == CS_HOSTNAME) {
  123. if (buflen == CS_NULLTERM) {
  124. maxcp = strlen(buffer);
  125. set_buffer = (char *)malloc(maxcp + 1);
  126. strcpy(set_buffer, buffer);
  127. } else if (buflen == CS_UNUSED) {
  128. return CS_SUCCEED;
  129. } else {
  130. set_buffer = (char *)malloc(buflen + 1);
  131. strncpy(set_buffer, buffer, buflen);
  132. set_buffer[buflen] = '';
  133. }
  134. }
  135. /* XXX "login" properties shouldn't be set after
  136.  * login.  I don't know if it should fail silently
  137.  * or return an error.
  138.  */
  139. switch (property) {
  140. case CS_USERNAME:
  141. tds_set_user(tds_login, set_buffer);
  142. break;
  143. case CS_PASSWORD:
  144. tds_set_passwd(tds_login, set_buffer);
  145. break;
  146. case CS_APPNAME:
  147. tds_set_app(tds_login, set_buffer);
  148. break;
  149. case CS_HOSTNAME:
  150. tds_set_host(tds_login, set_buffer);
  151. break;
  152. case CS_LOC_PROP:
  153. con->locale = (CS_LOCALE *)buffer;
  154. break;
  155. case CS_USERDATA:
  156. if (con->userdata) {
  157. free(con->userdata);
  158. }
  159. con->userdata = (void *)malloc(buflen+1);
  160. tdsdump_log(TDS_DBG_INFO2, "%L setting userdata orig %d new %dn",buffer,con->userdata);
  161. con->userdata_len = buflen;
  162. memcpy(con->userdata, buffer, buflen);
  163. break;
  164. case CS_BULK_LOGIN:
  165. memcpy(&intval, buffer, sizeof(intval));
  166. if (intval) 
  167. tds_set_bulk(tds_login,1);
  168. else 
  169. tds_set_bulk(tds_login,0);
  170. break;
  171. case CS_PACKETSIZE:
  172. memcpy(&intval, buffer, sizeof(intval));
  173. tds_set_packet(tds_login, (short)intval);
  174. break;
  175. case CS_TDS_VERSION:
  176. /* FIX ME
  177.  * (a) We don't support all versions in tds/login.c -
  178.  *     I tried to pick reasonable versions.
  179.  * (b) Might need support outside of tds/login.c
  180.  * (c) It's a "negotiated" property so probably
  181.  *     needs tds_process_env_chg() support
  182.  * (d) Minor - we don't check against context
  183.  *     which should limit the acceptable values
  184.  */
  185. if (*(int *)buffer == CS_TDS_40) {
  186. tds_set_version(tds_login, 4, 2);
  187. } else if (*(int *)buffer == CS_TDS_42) {
  188. tds_set_version(tds_login, 4, 2);
  189. } else if (*(int *)buffer == CS_TDS_46) {
  190. tds_set_version(tds_login, 4, 6);
  191. } else if (*(int *)buffer == CS_TDS_495) {
  192. tds_set_version(tds_login, 4, 6);
  193. } else if (*(int *)buffer == CS_TDS_50) {
  194. tds_set_version(tds_login, 5, 0);
  195. } else if (*(int *)buffer == CS_TDS_70) {
  196. tds_set_version(tds_login, 7, 0);
  197. } else {
  198. return CS_FAIL;
  199. }
  200. break;
  201. default:
  202. tdsdump_log(TDS_DBG_ERROR, "%L Unknown property %dn",property);
  203. break;
  204. }
  205. if (set_buffer) free(set_buffer);
  206. } else if (action==CS_GET) {
  207. switch (property) {
  208. case CS_USERNAME:
  209. maxcp = strlen(tds_login->user_name);
  210. if (out_len) *out_len=maxcp;
  211. if (maxcp>=buflen) maxcp = buflen-1;
  212. strncpy(buffer,tds_login->user_name,maxcp);
  213. ((char *)buffer)[maxcp]='';
  214. break;
  215. case CS_PASSWORD:
  216. maxcp = strlen(tds_login->password);
  217. if (out_len) *out_len=maxcp;
  218. if (maxcp>=buflen) maxcp = buflen-1;
  219. strncpy(buffer,tds_login->password,maxcp);
  220. ((char *)buffer)[maxcp]='';
  221. break;
  222. case CS_APPNAME:
  223. maxcp = strlen(tds_login->app_name);
  224. if (out_len) *out_len=maxcp;
  225. if (maxcp>=buflen) maxcp = buflen-1;
  226. strncpy(buffer,tds_login->app_name,maxcp);
  227. ((char *)buffer)[maxcp]='';
  228. break;
  229. case CS_HOSTNAME:
  230. maxcp = strlen(tds_login->host_name);
  231. if (out_len) *out_len=maxcp;
  232. if (maxcp>=buflen) maxcp = buflen-1;
  233. strncpy(buffer,tds_login->host_name,maxcp);
  234. ((char *)buffer)[maxcp]='';
  235. break;
  236. case CS_LOC_PROP:
  237. buffer = (CS_VOID *)con->locale;
  238. break;
  239. case CS_USERDATA:
  240. tdsdump_log(TDS_DBG_INFO2, "%L fetching userdata %dn",con->userdata);
  241. maxcp = con->userdata_len;
  242. if (out_len) *out_len=maxcp;
  243. if (maxcp>buflen) maxcp = buflen;
  244. memcpy(buffer, con->userdata, maxcp);
  245. break;
  246. case CS_CON_STATUS:
  247. if (tds && tds->s) 
  248. intval |= CS_CONSTAT_CONNECTED;
  249. else 
  250. intval &= ~CS_CONSTAT_CONNECTED;
  251. if (tds && tds->state==TDS_DEAD) 
  252. intval |= CS_CONSTAT_DEAD;
  253. else
  254. intval &= ~CS_CONSTAT_DEAD;
  255. memcpy(buffer, &intval, sizeof(intval));
  256. break;
  257. case CS_BULK_LOGIN:
  258. if (tds_login->bulk_copy)
  259. intval=CS_FALSE;
  260. else 
  261. intval=CS_TRUE;
  262. memcpy(buffer, &intval, sizeof(intval));
  263. break;
  264. case CS_PACKETSIZE:
  265. if (tds && tds->env)
  266. intval = tds->env->block_size;
  267. else
  268. intval = tds_login->block_size;
  269. memcpy(buffer, &intval, sizeof(intval));
  270. if (out_len) *out_len=sizeof(intval);
  271. break;
  272. default:
  273. tdsdump_log(TDS_DBG_ERROR, "%L Unknown property %dn",property);
  274. break;
  275. }
  276. }
  277. return CS_SUCCEED;
  278. }
  279. CS_RETCODE ct_connect(CS_CONNECTION *con, CS_CHAR *servername, CS_INT snamelen)
  280. {
  281. char *server;
  282. int needfree=0;
  283. CS_CONTEXT *ctx;
  284. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_connect() servername = %sn", servername);
  285. if (snamelen==0 || snamelen==CS_UNUSED) {
  286. server=NULL;
  287. } else if (snamelen==CS_NULLTERM) {
  288. server=(char *)servername;
  289. } else {
  290. server = (char *) malloc(snamelen+1);
  291. needfree++;
  292. strncpy(server,servername,snamelen);
  293. server[snamelen]='';
  294. }
  295.         tds_set_server(con->tds_login,server);
  296.    ctx = con->ctx;
  297.         if (!(con->tds_socket = (void *) tds_connect(con->tds_login, ctx->tds_ctx, (void *) con))) {
  298. if (needfree) free(server);
  299. tdsdump_log(TDS_DBG_FUNC, "%L leaving ct_connect() returning %dn", CS_FAIL);
  300. return CS_FAIL;
  301. }
  302.         /* tds_set_parent( con->tds_socket, con); */
  303. if (needfree) free(server);
  304. tdsdump_log(TDS_DBG_FUNC, "%L leaving ct_connect() returning %dn", CS_SUCCEED);
  305. return CS_SUCCEED;
  306. }
  307. CS_RETCODE ct_cmd_alloc(CS_CONNECTION *con, CS_COMMAND **cmd)
  308. {
  309. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cmd_alloc()n");
  310. *cmd = (CS_COMMAND *) malloc(sizeof(CS_COMMAND));
  311. memset(*cmd,'',sizeof(CS_COMMAND));
  312. /* so we know who we belong to */
  313. (*cmd)->con = con;
  314. return CS_SUCCEED;
  315. }
  316. CS_RETCODE ct_command(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT option)
  317. {
  318. int query_len;
  319. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_command()n");
  320. /* FIX ME -- will only work for type CS_LANG_CMD */
  321. if (buflen==CS_NULLTERM) {
  322. query_len = strlen(buffer);
  323. } else {
  324. query_len = buflen;
  325. }
  326. if (cmd->query) free(cmd->query);
  327. cmd->query = (char *) malloc(query_len + 1);
  328. strncpy(cmd->query,(char *)buffer,query_len);
  329. cmd->query[query_len]='';
  330. return CS_SUCCEED;
  331. }
  332. CS_RETCODE ct_send_dyn(CS_COMMAND *cmd)
  333. {
  334. if (cmd->dynamic_cmd==CS_PREPARE) {
  335. cmd->dynamic_cmd=0;
  336. if (tds_submit_prepare(cmd->con->tds_socket, cmd->query, cmd->dyn_id)==TDS_FAIL)
  337. return CS_FAIL;
  338. else 
  339. return CS_SUCCEED;
  340. } else if (cmd->dynamic_cmd==CS_EXECUTE) {
  341. cmd->dynamic_cmd=0;
  342. if (tds_submit_execute(cmd->con->tds_socket, cmd->dyn_id)==TDS_FAIL)
  343. return CS_FAIL;
  344. else 
  345. return CS_SUCCEED;
  346. }
  347. return CS_FAIL;
  348. }
  349. CS_RETCODE ct_send(CS_COMMAND *cmd)
  350. {
  351. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_send()n");
  352. if (cmd->dynamic_cmd) 
  353. return ct_send_dyn(cmd);
  354. if (tds_submit_query(cmd->con->tds_socket, cmd->query)==TDS_FAIL) {
  355. tdsdump_log(TDS_DBG_WARN, "%L ct_send() failedn");
  356. return CS_FAIL;
  357. } else {
  358. tdsdump_log(TDS_DBG_INFO2, "%L ct_send() succeededn");
  359. return CS_SUCCEED;
  360. }
  361. }
  362. CS_RETCODE ct_results_dyn(CS_COMMAND *cmd, CS_INT *result_type)
  363. {
  364. TDSRESULTINFO *resinfo;
  365. TDSSOCKET *tds;
  366. TDSDYNAMIC *dyn;
  367. tds = cmd->con->tds_socket;
  368. if (cmd->dynamic_cmd==CS_DESCRIBE_INPUT) {
  369. dyn = tds->dyns[tds->cur_dyn_elem];
  370. if (dyn->dyn_state) {
  371. dyn->dyn_state = 0;
  372. return CS_END_RESULTS;
  373. } else {
  374. dyn->dyn_state++;
  375. *result_type = CS_DESCRIBE_RESULT;
  376. return CS_SUCCEED;
  377. }
  378. }
  379. return CS_FAIL;
  380. }
  381. CS_RETCODE ct_results(CS_COMMAND *cmd, CS_INT *result_type)
  382. {
  383. TDSRESULTINFO *resinfo;
  384. TDSSOCKET *tds;
  385. int ret;
  386. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_results()n");
  387. if (cmd->dynamic_cmd) {
  388. return ct_results_dyn(cmd, result_type);
  389. }
  390. if (cmd->cmd_done) {
  391. cmd->cmd_done = 0;
  392. *result_type = CS_CMD_DONE;
  393. return CS_SUCCEED;
  394. tds = cmd->con->tds_socket;
  395. switch (ret = tds_process_result_tokens(tds)) {
  396. case TDS_SUCCEED:
  397. resinfo = tds->res_info;
  398. if (resinfo->rows_exist) {
  399. *result_type = CS_ROW_RESULT;
  400. cmd->cmd_done = 1;
  401. } else {
  402. *result_type = CS_CMD_SUCCEED;
  403. }
  404. return CS_SUCCEED;
  405. case TDS_NO_MORE_RESULTS:
  406. if (! tds->res_info) {
  407. if (cmd->empty_res_hack) {
  408. cmd->empty_res_hack=0;
  409. *result_type = CS_CMD_DONE;
  410. return CS_END_RESULTS;
  411. } else {
  412. cmd->empty_res_hack=1;
  413. *result_type = CS_CMD_SUCCEED;
  414. return CS_SUCCEED;
  415. }
  416. }
  417. if (tds->res_info && !tds->res_info->rows_exist) {
  418. if (cmd->empty_res_hack) {
  419. cmd->empty_res_hack=0;
  420. *result_type = CS_CMD_DONE;
  421. return CS_END_RESULTS;
  422. } else {
  423. cmd->empty_res_hack=1;
  424. *result_type = CS_ROW_RESULT;
  425. return CS_SUCCEED;
  426. }
  427. } else {
  428. *result_type = CS_CMD_DONE;
  429. return CS_END_RESULTS;
  430. }
  431. case TDS_FAIL:
  432. if (tds->state == TDS_DEAD) {
  433. return CS_FAIL;
  434. } else {
  435. *result_type = CS_CMD_FAIL;
  436. return CS_SUCCEED;
  437. }
  438. default:
  439. return CS_FAIL;
  440. }
  441. return CS_FAIL;
  442. }
  443. CS_RETCODE ct_bind(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt, CS_VOID *buffer, CS_INT *copied, CS_SMALLINT *indicator)
  444. {
  445. TDSCOLINFO * colinfo;
  446. CT_COLINFO *ctcolinfo; /* additional information about columns used by ctlib */
  447. TDSRESULTINFO * resinfo;
  448. TDSSOCKET * tds;
  449.    tdsdump_log(TDS_DBG_FUNC, "%L inside ct_bind()n");
  450.    tds = (TDSSOCKET *) cmd->con->tds_socket;
  451.    resinfo = tds->res_info;
  452.    /* FIXME check item value */
  453.    colinfo = resinfo->columns[item-1];
  454.    colinfo->varaddr = (char *)buffer;
  455.    colinfo->column_bindtype = datafmt->datatype;
  456.    colinfo->column_bindfmt = datafmt->format;
  457.    tdsdump_log(TDS_DBG_INFO1, "%L inside ct_bind() item = %d datafmt->datatype = %dn", item, datafmt->datatype);
  458.    colinfo->column_bindlen = datafmt->maxlength;
  459.    if (indicator) {
  460.     colinfo->column_nullbind = (TDS_CHAR *) indicator;
  461.    }
  462.    if (copied) {
  463.     colinfo->column_lenbind = (TDS_CHAR *) copied;
  464.    }
  465.    return CS_SUCCEED;
  466. }
  467. CS_RETCODE ct_fetch(CS_COMMAND *cmd, CS_INT type, CS_INT offset, CS_INT option, CS_INT *rows_read)
  468. {
  469.    tdsdump_log(TDS_DBG_FUNC, "%L inside ct_fetch()n");
  470.    if (rows_read) *rows_read = 0;
  471.    switch (tds_process_row_tokens(cmd->con->tds_socket)) {
  472.       case TDS_SUCCEED:
  473. if (_ct_bind_data(cmd))
  474. return CS_ROW_FAIL;
  475.        if (rows_read) *rows_read = 1;
  476.        return TDS_SUCCEED;
  477.       case TDS_NO_MORE_ROWS:
  478.        return CS_END_DATA;
  479.       default:
  480.        return CS_FAIL;
  481.    }
  482.    return CS_SUCCEED;
  483. }
  484. static int _ct_bind_data(CS_COMMAND *cmd)
  485. {
  486. int i;
  487. TDSCOLINFO *curcol;
  488. TDSSOCKET *tds = cmd->con->tds_socket;
  489. TDSRESULTINFO *resinfo = tds->res_info;
  490. unsigned char *src;
  491. unsigned char *dest;
  492. int result = 0;
  493. TDS_INT srctype, srclen, desttype, destlen, len;
  494. CS_CONTEXT *ctx = cmd->con->ctx;
  495. CS_DATAFMT srcfmt, destfmt;
  496.    tdsdump_log(TDS_DBG_FUNC, "%L inside _ct_bind_data()n");
  497.    for (i=0; i<resinfo->num_cols; i++) {
  498.       curcol = resinfo->columns[i];
  499.       if (curcol->column_nullbind) {
  500.        if (tds_get_null(resinfo->current_row,i)) {
  501.           *((CS_SMALLINT *)curcol->column_nullbind) = -1;
  502.        } else {
  503.           *((CS_SMALLINT *)curcol->column_nullbind) = 0;
  504.        }
  505.  }
  506.       /* printf("%d %sn",i,resinfo->columns[i]->column_value); */
  507.    
  508.       srctype = curcol->column_type;
  509.       desttype = _ct_get_server_type(curcol->column_bindtype);
  510.       dest = (unsigned char *)curcol->varaddr;
  511.   
  512.       if (dest && !tds_get_null(resinfo->current_row,i)) {
  513.          srctype = _ct_get_client_type(curcol->column_type, curcol->column_size);
  514.          if (is_blob_type(curcol->column_type)) {
  515.             src = (unsigned char *)curcol->column_textvalue;
  516.             srclen = curcol->column_textsize;
  517.          } else {
  518.             src = &(resinfo->current_row[curcol->column_offset]);
  519.     srclen = curcol->cur_row_size;
  520.          }
  521.          tdsdump_log(TDS_DBG_INFO1, "%L inside _ct_bind_data() setting source length for %d = %d destlen = %dn", i, srclen, curcol->column_bindlen);
  522.          srcfmt.datatype  = srctype;
  523.          srcfmt.maxlength = srclen;
  524.          srcfmt.locale    = cmd->con->locale;
  525.          destfmt.datatype  = curcol->column_bindtype;
  526.          destfmt.maxlength = curcol->column_bindlen;
  527.          destfmt.locale    = cmd->con->locale;
  528.          destfmt.format    = curcol->column_bindfmt;
  529.  /* if convert return FAIL mark error but process other columns */
  530.          if (cs_convert(ctx, &srcfmt, (CS_VOID *)src, &destfmt, (CS_VOID *)dest, &len) != CS_SUCCEED) {
  531.  result = 1;
  532.  len = 0;
  533.  }
  534.          if (curcol->column_lenbind) {
  535.             tdsdump_log(TDS_DBG_INFO1, "%L inside _ct_bind_data() length binding len = %dn", len);
  536.             *((CS_INT *)curcol->column_lenbind) = len;
  537.          }
  538.       }
  539.    }
  540.    return result;
  541. }
  542. CS_RETCODE ct_cmd_drop(CS_COMMAND *cmd)
  543. {
  544. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cmd_drop()n");
  545. if (cmd) {
  546. if (cmd->query) free(cmd->query);
  547. free(cmd);
  548. }
  549. return CS_SUCCEED;
  550. }
  551. CS_RETCODE ct_close(CS_CONNECTION *con, CS_INT option)
  552. {
  553. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_close()n");
  554. tds_free_socket(con->tds_socket);
  555. return CS_SUCCEED;
  556. }
  557. CS_RETCODE ct_con_drop(CS_CONNECTION *con)
  558. {
  559.    tdsdump_log(TDS_DBG_FUNC, "%L inside ct_con_drop()n");
  560.    if (con) {
  561.       if (con->userdata)   free(con->userdata);
  562.       if (con->tds_login)  tds_free_login(con->tds_login);
  563.       free(con);
  564.    }
  565.    return CS_SUCCEED;
  566. }
  567. static int _ct_get_client_type(int datatype, int size)
  568. {
  569.    tdsdump_log(TDS_DBG_FUNC, "%L inside _ct_get_client_type(type %d, size %d)n",
  570.                              datatype, size);
  571.    switch (datatype) {
  572.          case SYBBIT:
  573.          case SYBBITN:
  574. return CS_BIT_TYPE;
  575. break;
  576.          case SYBCHAR:
  577.          case SYBVARCHAR:
  578. return CS_CHAR_TYPE;
  579. break;
  580.          case SYBINT4:
  581.        return CS_INT_TYPE;
  582. break;
  583.          case SYBINT2:
  584.        return CS_SMALLINT_TYPE;
  585. break;
  586.          case SYBINT1:
  587.        return CS_TINYINT_TYPE;
  588. break;
  589.  case SYBINTN:
  590. if (size==4) {
  591. return CS_INT_TYPE;
  592. } else if (size==2) {
  593.        return CS_SMALLINT_TYPE;
  594. } else if (size==1) {
  595.        return CS_TINYINT_TYPE;
  596. } else {
  597. fprintf(stderr,"Unknown size %d for SYBINTNn", size);
  598. }
  599. break;
  600.          case SYBREAL:
  601.        return CS_REAL_TYPE;
  602. break;
  603.          case SYBFLT8:
  604.        return CS_FLOAT_TYPE;
  605. break;
  606.  case SYBFLTN:
  607.        if (size==4) {
  608. return CS_REAL_TYPE;
  609. } else if (size==8) {
  610. return CS_FLOAT_TYPE;
  611. } else {
  612. fprintf(stderr,"Error! unknown float size of %dn",size);
  613. }
  614.          case SYBMONEY:
  615.        return CS_MONEY_TYPE;
  616. break;
  617.          case SYBMONEY4:
  618.        return CS_MONEY4_TYPE;
  619. break;
  620.  case SYBMONEYN:
  621.        if (size==4) {
  622. return CS_MONEY4_TYPE;
  623. } else if (size==8) {
  624. return CS_MONEY_TYPE;
  625. } else {
  626. fprintf(stderr,"Error! unknown money size of %dn",size);
  627. }
  628.          case SYBDATETIME:
  629.        return CS_DATETIME_TYPE;
  630. break;
  631.          case SYBDATETIME4:
  632.        return CS_DATETIME4_TYPE;
  633. break;
  634.  case SYBDATETIMN:
  635.        if (size==4) {
  636. return CS_DATETIME4_TYPE;
  637. } else if (size==8) {
  638. return CS_DATETIME_TYPE;
  639. } else {
  640. fprintf(stderr,"Error! unknown date size of %dn",size);
  641. }
  642. break;
  643.          case SYBNUMERIC:
  644.        return CS_NUMERIC_TYPE;
  645. break;
  646.          case SYBDECIMAL:
  647.        return CS_DECIMAL_TYPE;
  648. break;
  649.          case SYBBINARY:
  650.        return CS_BINARY_TYPE;
  651. break;
  652.          case SYBIMAGE:
  653.        return CS_IMAGE_TYPE;
  654. break;
  655.          case SYBVARBINARY:
  656.        return CS_VARBINARY_TYPE;
  657. break;
  658.          case SYBTEXT:
  659.        return CS_TEXT_TYPE;
  660. break;
  661.          case SYBUNIQUE:
  662.        return CS_UNIQUE_TYPE;
  663. break;
  664.    }
  665.    return CS_FAIL;
  666. }
  667. int _ct_get_server_type(int datatype)
  668. {
  669.    tdsdump_log(TDS_DBG_FUNC, "%L inside _ct_get_server_type(%d)n", datatype);
  670.    switch (datatype) {
  671.       case CS_IMAGE_TYPE:
  672.  return SYBIMAGE;
  673.  break;
  674.       case CS_BINARY_TYPE:
  675.  return SYBBINARY;
  676.  break;
  677.       case CS_BIT_TYPE:
  678.          return SYBBIT;
  679.          break;
  680.       case CS_CHAR_TYPE:
  681.          return SYBCHAR;
  682.          break;
  683.       case CS_INT_TYPE:
  684.          return SYBINT4;
  685.          break;
  686.       case CS_SMALLINT_TYPE:
  687.          return SYBINT2;
  688.          break;
  689.       case CS_TINYINT_TYPE:
  690.          return SYBINT1;
  691.          break;
  692.       case CS_REAL_TYPE:
  693.          return SYBREAL;
  694.          break;
  695.       case CS_FLOAT_TYPE:
  696.          return SYBFLT8;
  697.          break;
  698.       case CS_MONEY_TYPE:
  699.          return SYBMONEY;
  700.          break;
  701.       case CS_MONEY4_TYPE:
  702.          return SYBMONEY4;
  703.          break;
  704.       case CS_DATETIME_TYPE:
  705.          return SYBDATETIME;
  706.          break;
  707.       case CS_DATETIME4_TYPE:
  708.          return SYBDATETIME4;
  709.          break;
  710.       case CS_NUMERIC_TYPE:
  711.          return SYBNUMERIC;
  712.          break;
  713.       case CS_DECIMAL_TYPE:
  714.          return SYBDECIMAL;
  715.          break;
  716.       case CS_VARBINARY_TYPE:
  717.          return SYBVARBINARY;
  718.  break;
  719.       case CS_TEXT_TYPE:
  720.          return SYBTEXT;
  721.  break;
  722.       case CS_UNIQUE_TYPE:
  723.          return SYBUNIQUE;
  724.  break;
  725.       default:
  726.          return -1;
  727.          break;
  728.    }
  729. }
  730. CS_RETCODE ct_cancel(CS_CONNECTION *conn, CS_COMMAND *cmd, CS_INT type)
  731. {
  732.    CS_RETCODE ret;
  733.    tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cancel()n");
  734.    if (type == CS_CANCEL_CURRENT) {
  735.       if (conn || !cmd)  return CS_FAIL;
  736.       while (1) {
  737.          ret = ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, NULL);
  738.          if ((ret != CS_SUCCEED) && (ret != CS_ROW_FAIL)) {
  739.             break;
  740.          }
  741.       }
  742.       if (cmd->con->tds_socket) {
  743.          tds_free_all_results(cmd->con->tds_socket);
  744.       }
  745.       return ret;
  746.    }
  747.    if ((conn && cmd) || (!conn && !cmd)) {
  748.       return CS_FAIL;
  749.    }
  750.    if (cmd)  conn = cmd->con;
  751.    tds_send_cancel(conn->tds_socket);
  752.    tds_process_cancel(conn->tds_socket);
  753.    return CS_SUCCEED;
  754. }
  755. CS_RETCODE ct_describe(CS_COMMAND *cmd, CS_INT item, CS_DATAFMT *datafmt)
  756. {
  757. TDSSOCKET *tds;
  758. TDSRESULTINFO *resinfo;
  759. TDSCOLINFO *curcol;
  760. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_describe()n");
  761. tds = cmd->con->tds_socket;
  762. if (cmd->dynamic_cmd) {
  763. resinfo = tds->dyns[tds->cur_dyn_elem]->res_info;
  764. } else {
  765.   resinfo = cmd->con->tds_socket->res_info;
  766. }
  767. if (item<1 || item>resinfo->num_cols) return CS_FAIL;
  768. curcol=resinfo->columns[item-1];
  769. strncpy(datafmt->name, curcol->column_name, CS_MAX_NAME);
  770. datafmt->namelen = strlen(curcol->column_name);
  771. /* need to turn the SYBxxx into a CS_xxx_TYPE */
  772. datafmt->datatype = _ct_get_client_type(curcol->column_type, curcol->column_size); 
  773. tdsdump_log(TDS_DBG_INFO1, "%L inside ct_describe() datafmt->datatype = %d server type %dn", datafmt->datatype, curcol->column_type);
  774. datafmt->maxlength = curcol->column_size;
  775. datafmt->usertype = curcol->column_usertype; 
  776. datafmt->precision = curcol->column_prec; 
  777. datafmt->scale = curcol->column_scale; 
  778. /* FIX ME -- TDS 5.0 has status information in the results 
  779. ** however, this will work for 4.2 as well */
  780. if (is_nullable_type(curcol->column_type)) 
  781. datafmt->status |= CS_CANBENULL;
  782. datafmt->count = 1;
  783. datafmt->locale = NULL;
  784. return CS_SUCCEED;
  785. }
  786. CS_RETCODE ct_res_info_dyn(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *out_len)
  787. {
  788. TDSSOCKET *tds = cmd->con->tds_socket;
  789. TDSDYNAMIC *dyn;
  790. CS_INT int_val;
  791. switch(type) {
  792. case CS_NUMDATA:
  793. dyn = tds->dyns[tds->cur_dyn_elem];
  794. int_val = dyn->res_info->num_cols;
  795. memcpy(buffer, &int_val, sizeof(CS_INT));
  796. break;
  797. default:
  798. fprintf(stderr,"Unknown type in ct_res_info_dyn: %dn",type);
  799. return CS_FAIL;
  800. }
  801. return CS_SUCCEED;
  802. }
  803. CS_RETCODE ct_res_info(CS_COMMAND *cmd, CS_INT type, CS_VOID *buffer, CS_INT buflen, CS_INT *out_len)
  804. {
  805. TDSSOCKET *tds = cmd->con->tds_socket;
  806. TDSRESULTINFO *resinfo = tds->res_info;
  807. CS_INT int_val;
  808. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_res_info()n");
  809. if (cmd->dynamic_cmd) {
  810. return ct_res_info_dyn(cmd, type, buffer, buflen, out_len);
  811. }
  812. switch(type) {
  813. case CS_NUMDATA:
  814. if (!resinfo) {
  815. int_val = 0;
  816. } else {
  817. int_val = resinfo->num_cols;
  818. }
  819. memcpy(buffer, &int_val, sizeof(CS_INT));
  820. break;
  821. case CS_ROW_COUNT:
  822. /* resinfo check by kostya@warmcat.excom.spb.su */
  823. if (resinfo) {
  824. int_val = resinfo->row_count;
  825. } else {
  826. int_val = tds->rows_affected;
  827. }
  828. memcpy(buffer, &int_val, sizeof(CS_INT));
  829. break;
  830. default:
  831. fprintf(stderr,"Unknown type in ct_res_info: %dn",type);
  832. return CS_FAIL;
  833. break;
  834. }
  835. return CS_SUCCEED;
  836. }
  837. CS_RETCODE ct_config(CS_CONTEXT *ctx, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  838. {
  839. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_config() action = %s property = %dn",
  840. CS_GET ? "CS_GET" : "CS_SET", property);
  841. return CS_SUCCEED;
  842. }
  843. CS_RETCODE ct_cmd_props(CS_COMMAND *cmd, CS_INT action, CS_INT property, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  844. {
  845. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_cmd_props() action = %s property = %dn",
  846. CS_GET ? "CS_GET" : "CS_SET", property);
  847. return CS_SUCCEED;
  848. }
  849. CS_RETCODE ct_compute_info(CS_COMMAND *cmd, CS_INT type, CS_INT colnum, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  850. {
  851. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_compute_info()n");
  852. return CS_SUCCEED;
  853. }
  854. CS_RETCODE ct_get_data(CS_COMMAND *cmd, CS_INT item, CS_VOID *buffer, CS_INT buflen, CS_INT *outlen)
  855. {
  856. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_get_data()n");
  857. return CS_SUCCEED;
  858. }
  859. CS_RETCODE ct_send_data(CS_COMMAND *cmd, CS_VOID *buffer, CS_INT buflen)
  860. {
  861. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_send_data()n");
  862. return CS_SUCCEED;
  863. }
  864. CS_RETCODE ct_data_info(CS_COMMAND *cmd, CS_INT action, CS_INT colnum,
  865. CS_IODESC *iodesc)
  866. {
  867. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_data_info()n");
  868. return CS_SUCCEED;
  869. }
  870. CS_RETCODE ct_capability(CS_CONNECTION *con, CS_INT action, CS_INT type, CS_INT capability, CS_VOID *value)
  871. {
  872. TDSLOGIN *login;
  873. unsigned char *mask;
  874. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_capability()n");
  875. login = (TDSLOGIN *) con->tds_login;
  876. mask = login->capabilities;
  877. if (action==CS_SET && type==CS_CAP_RESPONSE) {
  878. if (*((CS_BOOL *)value)==CS_TRUE) {
  879. switch(capability) {
  880. case CS_DATA_NOBOUNDARY:
  881. mask[13]|=0x01;break;
  882. case CS_DATA_NOTDSDEBUG:
  883. mask[13]|=0x02;break;
  884. case CS_RES_NOSTRIPBLANKS:
  885. mask[13]|=0x04;break;
  886. case CS_DATA_NOINT8:
  887. mask[13]|=0x08;break;
  888. case CS_DATA_NOINTN:
  889. mask[14]|=0x01;break;
  890. case CS_DATA_NODATETIMEN:
  891. mask[14]|=0x02;break;
  892. case CS_DATA_NOMONEYN:
  893. mask[14]|=0x04;break;
  894. case CS_CON_NOOOB:
  895. mask[14]|=0x08;break;
  896. case CS_CON_NOINBAND:
  897. mask[14]|=0x10;break;
  898. case CS_PROTO_NOTEXT:
  899. mask[14]|=0x20;break;
  900. case CS_PROTO_NOBULK:
  901. mask[14]|=0x40;break;
  902. case CS_DATA_NOSENSITIVITY:
  903. mask[14]|=0x80;break;
  904. case CS_DATA_NOFLT4:
  905. mask[15]|=0x01;break;
  906. case CS_DATA_NOFLT8:
  907. mask[15]|=0x02;break;
  908. case CS_DATA_NONUM:
  909. mask[15]|=0x04;break;
  910. case CS_DATA_NOTEXT:
  911. mask[15]|=0x08;break;
  912. case CS_DATA_NOIMAGE:
  913. mask[15]|=0x10;break;
  914. case CS_DATA_NODEC:
  915. mask[15]|=0x20;break;
  916. case CS_DATA_NOLCHAR:
  917. mask[15]|=0x40;break;
  918. case CS_DATA_NOLBIN:
  919. mask[15]|=0x80;break;
  920. case CS_DATA_NOCHAR:
  921. mask[16]|=0x01;break;
  922. case CS_DATA_NOVCHAR:
  923. mask[16]|=0x02;break;
  924. case CS_DATA_NOBIN:
  925. mask[16]|=0x04;break;
  926. case CS_DATA_NOVBIN:
  927. mask[16]|=0x08;break;
  928. case CS_DATA_NOMNY8:
  929. mask[16]|=0x10;break;
  930. case CS_DATA_NOMNY4:
  931. mask[16]|=0x20;break;
  932. case CS_DATA_NODATE8:
  933. mask[16]|=0x40;break;
  934. case CS_DATA_NODATE4:
  935. mask[16]|=0x80;break;
  936. case CS_RES_NOMSG:
  937. mask[17]|=0x02;break;
  938. case CS_RES_NOEED:
  939. mask[17]|=0x04;break;
  940. case CS_RES_NOPARAM:
  941. mask[17]|=0x08;break;
  942. case CS_DATA_NOINT1:
  943. mask[17]|=0x10;break;
  944. case CS_DATA_NOINT2:
  945. mask[17]|=0x20;break;
  946. case CS_DATA_NOINT4:
  947. mask[17]|=0x40;break;
  948. case CS_DATA_NOBIT:
  949. mask[17]|=0x80;break;
  950. }
  951. } else {
  952. switch(capability) {
  953. case CS_DATA_NOBOUNDARY:
  954. mask[13]&=(!0x01);break;
  955. case CS_DATA_NOTDSDEBUG:
  956. mask[13]&=(!0x02);break;
  957. case CS_RES_NOSTRIPBLANKS:
  958. mask[13]&=(!0x04);break;
  959. case CS_DATA_NOINT8:
  960. mask[13]&=(!0x08);break;
  961. case CS_DATA_NOINTN:
  962. mask[14]&=(!0x01);break;
  963. case CS_DATA_NODATETIMEN:
  964. mask[14]&=(!0x02);break;
  965. case CS_DATA_NOMONEYN:
  966. mask[14]&=(!0x04);break;
  967. case CS_CON_NOOOB:
  968. mask[14]&=(!0x08);break;
  969. case CS_CON_NOINBAND:
  970. mask[14]&=(!0x10);break;
  971. case CS_PROTO_NOTEXT:
  972. mask[14]&=(!0x20);break;
  973. case CS_PROTO_NOBULK:
  974. mask[14]&=(!0x40);break;
  975. case CS_DATA_NOSENSITIVITY:
  976. mask[14]&=(!0x80);break;
  977. case CS_DATA_NOFLT4:
  978. mask[15]&=(!0x01);break;
  979. case CS_DATA_NOFLT8:
  980. mask[15]&=(!0x02);break;
  981. case CS_DATA_NONUM:
  982. mask[15]&=(!0x04);break;
  983. case CS_DATA_NOTEXT:
  984. mask[15]&=(!0x08);break;
  985. case CS_DATA_NOIMAGE:
  986. mask[15]&=(!0x10);break;
  987. case CS_DATA_NODEC:
  988. mask[15]&=(!0x20);break;
  989. case CS_DATA_NOLCHAR:
  990. mask[15]&=(!0x40);break;
  991. case CS_DATA_NOLBIN:
  992. mask[15]&=(!0x80);break;
  993. case CS_DATA_NOCHAR:
  994. mask[16]&=(!0x01);break;
  995. case CS_DATA_NOVCHAR:
  996. mask[16]&=(!0x02);break;
  997. case CS_DATA_NOBIN:
  998. mask[16]&=(!0x04);break;
  999. case CS_DATA_NOVBIN:
  1000. mask[16]&=(!0x08);break;
  1001. case CS_DATA_NOMNY8:
  1002. mask[16]&=(!0x10);break;
  1003. case CS_DATA_NOMNY4:
  1004. mask[16]&=(!0x20);break;
  1005. case CS_DATA_NODATE8:
  1006. mask[16]&=(!0x40);break;
  1007. case CS_DATA_NODATE4:
  1008. mask[16]&=(!0x80);break;
  1009. case CS_RES_NOMSG:
  1010. mask[17]&=(!0x02);break;
  1011. case CS_RES_NOEED:
  1012. mask[17]&=(!0x04);break;
  1013. case CS_RES_NOPARAM:
  1014. mask[17]&=(!0x08);break;
  1015. case CS_DATA_NOINT1:
  1016. mask[17]&=(!0x10);break;
  1017. case CS_DATA_NOINT2:
  1018. mask[17]&=(!0x20);break;
  1019. case CS_DATA_NOINT4:
  1020. mask[17]&=(!0x40);break;
  1021. case CS_DATA_NOBIT:
  1022. mask[17]&=(!0x80);break;
  1023. }
  1024. }
  1025. } else if (action==CS_GET && type==CS_CAP_RESPONSE) {
  1026. switch (capability) {
  1027. case CS_DATA_NOBOUNDARY:
  1028. *((CS_BOOL *)value)=mask[13]&0x01 ? CS_TRUE : CS_FALSE;break;
  1029. case CS_DATA_NOTDSDEBUG:
  1030. *((CS_BOOL *)value)=mask[13]&0x02 ? CS_TRUE : CS_FALSE;break;
  1031. case CS_RES_NOSTRIPBLANKS:
  1032. *((CS_BOOL *)value)=mask[13]&0x04 ? CS_TRUE : CS_FALSE;break;
  1033. case CS_DATA_NOINT8:
  1034. *((CS_BOOL *)value)=mask[13]&0x08 ? CS_TRUE : CS_FALSE;break;
  1035. case CS_DATA_NOINTN:
  1036. *((CS_BOOL *)value)=mask[14]&0x01 ? CS_TRUE : CS_FALSE;break;
  1037. case CS_DATA_NODATETIMEN:
  1038. *((CS_BOOL *)value)=mask[14]&0x02 ? CS_TRUE : CS_FALSE;break;
  1039. case CS_DATA_NOMONEYN:
  1040. *((CS_BOOL *)value)=mask[14]&0x04 ? CS_TRUE : CS_FALSE;break;
  1041. case CS_CON_NOOOB:
  1042. *((CS_BOOL *)value)=mask[14]&0x08 ? CS_TRUE : CS_FALSE;break;
  1043. case CS_CON_NOINBAND:
  1044. *((CS_BOOL *)value)=mask[14]&0x10 ? CS_TRUE : CS_FALSE;break;
  1045. case CS_PROTO_NOTEXT:
  1046. *((CS_BOOL *)value)=mask[14]&0x20 ? CS_TRUE : CS_FALSE;break;
  1047. case CS_PROTO_NOBULK:
  1048. *((CS_BOOL *)value)=mask[14]&0x40 ? CS_TRUE : CS_FALSE;break;
  1049. case CS_DATA_NOSENSITIVITY:
  1050. *((CS_BOOL *)value)=mask[14]&0x80 ? CS_TRUE : CS_FALSE;break;
  1051. case CS_DATA_NOFLT4:
  1052. *((CS_BOOL *)value)=mask[15]&0x01 ? CS_TRUE : CS_FALSE;break;
  1053. case CS_DATA_NOFLT8:
  1054. *((CS_BOOL *)value)=mask[15]&0x02 ? CS_TRUE : CS_FALSE;break;
  1055. case CS_DATA_NONUM:
  1056. *((CS_BOOL *)value)=mask[15]&0x04 ? CS_TRUE : CS_FALSE;break;
  1057. case CS_DATA_NOTEXT:
  1058. *((CS_BOOL *)value)=mask[15]&0x08 ? CS_TRUE : CS_FALSE;break;
  1059. case CS_DATA_NOIMAGE:
  1060. *((CS_BOOL *)value)=mask[15]&0x10 ? CS_TRUE : CS_FALSE;break;
  1061. case CS_DATA_NODEC:
  1062. *((CS_BOOL *)value)=mask[15]&0x20 ? CS_TRUE : CS_FALSE;break;
  1063. case CS_DATA_NOLCHAR:
  1064. *((CS_BOOL *)value)=mask[15]&0x40 ? CS_TRUE : CS_FALSE;break;
  1065. case CS_DATA_NOLBIN:
  1066. *((CS_BOOL *)value)=mask[15]&0x80 ? CS_TRUE : CS_FALSE;break;
  1067. case CS_DATA_NOCHAR:
  1068. *((CS_BOOL *)value)=mask[16]&0x01 ? CS_TRUE : CS_FALSE;break;
  1069. case CS_DATA_NOVCHAR:
  1070. *((CS_BOOL *)value)=mask[16]&0x02 ? CS_TRUE : CS_FALSE;break;
  1071. case CS_DATA_NOBIN:
  1072. *((CS_BOOL *)value)=mask[16]&0x04 ? CS_TRUE : CS_FALSE;break;
  1073. case CS_DATA_NOVBIN:
  1074. *((CS_BOOL *)value)=mask[16]&0x08 ? CS_TRUE : CS_FALSE;break;
  1075. case CS_DATA_NOMNY8:
  1076. *((CS_BOOL *)value)=mask[16]&0x10 ? CS_TRUE : CS_FALSE;break;
  1077. case CS_DATA_NOMNY4:
  1078. *((CS_BOOL *)value)=mask[16]&0x20 ? CS_TRUE : CS_FALSE;break;
  1079. case CS_DATA_NODATE8:
  1080. *((CS_BOOL *)value)=mask[16]&0x40 ? CS_TRUE : CS_FALSE;break;
  1081. case CS_DATA_NODATE4:
  1082. *((CS_BOOL *)value)=mask[16]&0x80 ? CS_TRUE : CS_FALSE;break;
  1083. case CS_RES_NOMSG:
  1084. *((CS_BOOL *)value)=mask[17]&0x02 ? CS_TRUE : CS_FALSE;break;
  1085. case CS_RES_NOEED:
  1086. *((CS_BOOL *)value)=mask[17]&0x04 ? CS_TRUE : CS_FALSE;break;
  1087. case CS_RES_NOPARAM:
  1088. *((CS_BOOL *)value)=mask[17]&0x08 ? CS_TRUE : CS_FALSE;break;
  1089. case CS_DATA_NOINT1:
  1090. *((CS_BOOL *)value)=mask[17]&0x10 ? CS_TRUE : CS_FALSE;break;
  1091. case CS_DATA_NOINT2:
  1092. *((CS_BOOL *)value)=mask[17]&0x20 ? CS_TRUE : CS_FALSE;break;
  1093. case CS_DATA_NOINT4:
  1094. *((CS_BOOL *)value)=mask[17]&0x40 ? CS_TRUE : CS_FALSE;break;
  1095. case CS_DATA_NOBIT:
  1096. *((CS_BOOL *)value)=mask[17]&0x80 ? CS_TRUE : CS_FALSE;break;
  1097. }
  1098. } else if (action==CS_GET && type==CS_CAP_REQUEST) {
  1099. switch (capability) {
  1100. case CS_PROTO_DYNPROC:
  1101. *((CS_BOOL *)value)=mask[2]&0x01 ? CS_TRUE : CS_FALSE;break;
  1102. case CS_DATA_FLTN:
  1103. *((CS_BOOL *)value)=mask[2]&0x02 ? CS_TRUE : CS_FALSE;break;
  1104. case CS_DATA_BITN:
  1105. *((CS_BOOL *)value)=mask[2]&0x04 ? CS_TRUE : CS_FALSE;break;
  1106. case CS_DATA_INT8:
  1107. *((CS_BOOL *)value)=mask[2]&0x08 ? CS_TRUE : CS_FALSE;break;
  1108. case CS_DATA_VOID:
  1109. *((CS_BOOL *)value)=mask[2]&0x10 ? CS_TRUE : CS_FALSE;break;
  1110. case CS_CON_INBAND:
  1111. *((CS_BOOL *)value)=mask[3]&0x01 ? CS_TRUE : CS_FALSE;break;
  1112. case CS_CON_LOGICAL:
  1113. *((CS_BOOL *)value)=mask[3]&0x02 ? CS_TRUE : CS_FALSE;break;
  1114. case CS_PROTO_TEXT:
  1115. *((CS_BOOL *)value)=mask[3]&0x04 ? CS_TRUE : CS_FALSE;break;
  1116. case CS_PROTO_BULK:
  1117. *((CS_BOOL *)value)=mask[3]&0x08 ? CS_TRUE : CS_FALSE;break;
  1118. case CS_REQ_URGNOTIF:
  1119. *((CS_BOOL *)value)=mask[3]&0x10 ? CS_TRUE : CS_FALSE;break;
  1120. case CS_DATA_SENSITIVITY:
  1121. *((CS_BOOL *)value)=mask[3]&0x20 ? CS_TRUE : CS_FALSE;break;
  1122. case CS_DATA_BOUNDARY:
  1123. *((CS_BOOL *)value)=mask[3]&0x40 ? CS_TRUE : CS_FALSE;break;
  1124. case CS_PROTO_DYNAMIC:
  1125. *((CS_BOOL *)value)=mask[3]&0x80 ? CS_TRUE : CS_FALSE;break;
  1126. case CS_DATA_MONEYN:
  1127. *((CS_BOOL *)value)=mask[4]&0x01 ? CS_TRUE : CS_FALSE;break;
  1128. case CS_CSR_PREV:
  1129. *((CS_BOOL *)value)=mask[4]&0x02 ? CS_TRUE : CS_FALSE;break;
  1130. case CS_CSR_FIRST:
  1131. *((CS_BOOL *)value)=mask[4]&0x04 ? CS_TRUE : CS_FALSE;break;
  1132. case CS_CSR_LAST:
  1133. *((CS_BOOL *)value)=mask[4]&0x08 ? CS_TRUE : CS_FALSE;break;
  1134. case CS_CSR_ABS:
  1135. *((CS_BOOL *)value)=mask[4]&0x10 ? CS_TRUE : CS_FALSE;break;
  1136. case CS_CSR_REL:
  1137. *((CS_BOOL *)value)=mask[4]&0x20 ? CS_TRUE : CS_FALSE;break;
  1138. case CS_CSR_MULTI:
  1139. *((CS_BOOL *)value)=mask[4]&0x40 ? CS_TRUE : CS_FALSE;break;
  1140. case CS_CON_OOB:
  1141. *((CS_BOOL *)value)=mask[4]&0x80 ? CS_TRUE : CS_FALSE;break;
  1142. case CS_DATA_NUM:
  1143. *((CS_BOOL *)value)=mask[5]&0x01 ? CS_TRUE : CS_FALSE;break;
  1144. case CS_DATA_TEXT:
  1145. *((CS_BOOL *)value)=mask[5]&0x02 ? CS_TRUE : CS_FALSE;break;
  1146. case CS_DATA_IMAGE:
  1147. *((CS_BOOL *)value)=mask[5]&0x04 ? CS_TRUE : CS_FALSE;break;
  1148. case CS_DATA_DEC:
  1149. *((CS_BOOL *)value)=mask[5]&0x08 ? CS_TRUE : CS_FALSE;break;
  1150. case CS_DATA_LCHAR:
  1151. *((CS_BOOL *)value)=mask[5]&0x10 ? CS_TRUE : CS_FALSE;break;
  1152. case CS_DATA_LBIN:
  1153. *((CS_BOOL *)value)=mask[5]&0x20 ? CS_TRUE : CS_FALSE;break;
  1154. case CS_DATA_INTN:
  1155. *((CS_BOOL *)value)=mask[5]&0x40 ? CS_TRUE : CS_FALSE;break;
  1156. case CS_DATA_DATETIMEN:
  1157. *((CS_BOOL *)value)=mask[5]&0x80 ? CS_TRUE : CS_FALSE;break;
  1158. case CS_DATA_BIN:
  1159. *((CS_BOOL *)value)=mask[6]&0x01 ? CS_TRUE : CS_FALSE;break;
  1160. case CS_DATA_VBIN:
  1161. *((CS_BOOL *)value)=mask[6]&0x02 ? CS_TRUE : CS_FALSE;break;
  1162. case CS_DATA_MNY8:
  1163. *((CS_BOOL *)value)=mask[6]&0x04 ? CS_TRUE : CS_FALSE;break;
  1164. case CS_DATA_MNY4:
  1165. *((CS_BOOL *)value)=mask[6]&0x08 ? CS_TRUE : CS_FALSE;break;
  1166. case CS_DATA_DATE8:
  1167. *((CS_BOOL *)value)=mask[6]&0x10 ? CS_TRUE : CS_FALSE;break;
  1168. case CS_DATA_DATE4:
  1169. *((CS_BOOL *)value)=mask[6]&0x20 ? CS_TRUE : CS_FALSE;break;
  1170. case CS_DATA_FLT4:
  1171. *((CS_BOOL *)value)=mask[6]&0x40 ? CS_TRUE : CS_FALSE;break;
  1172. case CS_DATA_FLT8:
  1173. *((CS_BOOL *)value)=mask[6]&0x80 ? CS_TRUE : CS_FALSE;break;
  1174. case CS_REQ_MSG:
  1175. *((CS_BOOL *)value)=mask[7]&0x01 ? CS_TRUE : CS_FALSE;break;
  1176. case CS_REQ_PARAM:
  1177. *((CS_BOOL *)value)=mask[7]&0x02 ? CS_TRUE : CS_FALSE;break;
  1178. case CS_DATA_INT1:
  1179. *((CS_BOOL *)value)=mask[7]&0x04 ? CS_TRUE : CS_FALSE;break;
  1180. case CS_DATA_INT2:
  1181. *((CS_BOOL *)value)=mask[7]&0x08 ? CS_TRUE : CS_FALSE;break;
  1182. case CS_DATA_INT4:
  1183. *((CS_BOOL *)value)=mask[7]&0x10 ? CS_TRUE : CS_FALSE;break;
  1184. case CS_DATA_BIT:
  1185. *((CS_BOOL *)value)=mask[7]&0x20 ? CS_TRUE : CS_FALSE;break;
  1186. case CS_DATA_CHAR:
  1187. *((CS_BOOL *)value)=mask[7]&0x40 ? CS_TRUE : CS_FALSE;break;
  1188. case CS_DATA_VCHAR:
  1189. *((CS_BOOL *)value)=mask[7]&0x80 ? CS_TRUE : CS_FALSE;break;
  1190. case CS_REQ_LANG:
  1191. *((CS_BOOL *)value)=mask[8]&0x02 ? CS_TRUE : CS_FALSE;break;
  1192. case CS_REQ_RPC:
  1193. *((CS_BOOL *)value)=mask[8]&0x04 ? CS_TRUE : CS_FALSE;break;
  1194. case CS_REQ_NOTIF:
  1195. *((CS_BOOL *)value)=mask[8]&0x08 ? CS_TRUE : CS_FALSE;break;
  1196. case CS_REQ_MSTMT:
  1197. *((CS_BOOL *)value)=mask[8]&0x10 ? CS_TRUE : CS_FALSE;break;
  1198. case CS_REQ_BCP:
  1199. *((CS_BOOL *)value)=mask[8]&0x20 ? CS_TRUE : CS_FALSE;break;
  1200. case CS_REQ_CURSOR:
  1201. *((CS_BOOL *)value)=mask[8]&0x40 ? CS_TRUE : CS_FALSE;break;
  1202. case CS_REQ_DYN:
  1203. *((CS_BOOL *)value)=mask[8]&0x80 ? CS_TRUE : CS_FALSE;break;
  1204. /* *((CS_BOOL *)value)=CS_FALSE; */
  1205. }
  1206. } else {
  1207. /* bad values */
  1208. return CS_FAIL;
  1209. }
  1210. return CS_SUCCEED;
  1211. }
  1212. CS_RETCODE ct_dynamic(CS_COMMAND *cmd, CS_INT type, CS_CHAR *id, CS_INT idlen, CS_CHAR *buffer, CS_INT buflen)
  1213. {
  1214. static int stmt_no=1;
  1215. int query_len, id_len;
  1216. TDSDYNAMIC *dyn;
  1217. TDSSOCKET *tds;
  1218. int elem;
  1219. cmd->dynamic_cmd=type;
  1220. switch(type) {
  1221. case CS_PREPARE:
  1222. /* store away the id */
  1223.      if (idlen==CS_NULLTERM) {
  1224. id_len = strlen(id);
  1225.          } else {
  1226. id_len = idlen;
  1227. }
  1228. if (cmd->dyn_id) free(cmd->dyn_id);
  1229. cmd->dyn_id = (char *) malloc(id_len + 1);
  1230. strncpy(cmd->dyn_id,(char *)id,id_len);
  1231. cmd->dyn_id[id_len]='';
  1232. /* now the query */
  1233.         if (buflen==CS_NULLTERM) {
  1234. query_len = strlen(buffer);
  1235.          } else {
  1236. query_len = buflen;
  1237. }
  1238. if (cmd->query) free(cmd->query);
  1239. cmd->query = (char *) malloc(query_len + 1);
  1240. strncpy(cmd->query,(char *)buffer,query_len);
  1241. cmd->query[query_len]='';
  1242. break;
  1243. case CS_DEALLOC:
  1244. break;
  1245. case CS_DESCRIBE_INPUT:
  1246. break;
  1247. case CS_EXECUTE:
  1248. /* store away the id */
  1249.      if (idlen==CS_NULLTERM) {
  1250. id_len = strlen(id);
  1251.          } else {
  1252. id_len = idlen;
  1253. }
  1254. if (cmd->dyn_id) free(cmd->dyn_id);
  1255. cmd->dyn_id = (char *) malloc(id_len + 1);
  1256. strncpy(cmd->dyn_id,(char *)id,id_len);
  1257. cmd->dyn_id[id_len]='';
  1258. /* free any input parameters */
  1259. tds = cmd->con->tds_socket;
  1260. elem = tds_lookup_dynamic(tds, cmd->dyn_id);
  1261. dyn = tds->dyns[elem];
  1262. break;
  1263. }
  1264. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_dynamic()n");
  1265. return CS_SUCCEED;
  1266. }
  1267. CS_RETCODE ct_param(CS_COMMAND *cmd, CS_DATAFMT *datafmt, CS_VOID *data, CS_INT datalen, CS_SMALLINT indicator)
  1268. {
  1269. TDSSOCKET *tds;
  1270. TDSDYNAMIC *dyn;
  1271. TDSINPUTPARAM *param;
  1272. int elem;
  1273. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_param()n");
  1274. tdsdump_log(TDS_DBG_INFO1, "%L ct_param() data addr = %d data length = %dn", data, datalen);
  1275. tds = cmd->con->tds_socket;
  1276. elem = tds_lookup_dynamic(tds, cmd->dyn_id);
  1277. dyn = tds->dyns[elem];
  1278. param = tds_add_input_param(dyn);
  1279. param->column_type = _ct_get_server_type(datafmt->datatype);
  1280. param->varaddr = data;
  1281. if (datalen==CS_NULLTERM) {
  1282. param->column_bindlen = 0;
  1283. } else {
  1284. param->column_bindlen = datalen;
  1285. }
  1286. param->is_null = indicator;
  1287. return CS_SUCCEED;
  1288. }
  1289. CS_RETCODE ct_options(CS_CONNECTION *con, CS_INT action, CS_INT option, CS_VOID *param, CS_INT paramlen, CS_INT *outlen)
  1290. {
  1291. tdsdump_log(TDS_DBG_FUNC, "%L inside ct_options() action = %s option = %dn",
  1292. CS_GET ? "CS_GET" : "CS_SET", option);
  1293. return CS_SUCCEED;
  1294. }