NCBI C++ ToolKit
mem.c
Go to the documentation of this file.

Go to the SVN repository for this file.

1 /* FreeTDS - Library of routines accessing Sybase and Microsoft databases
2  * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005 Brian Bruns
3  * Copyright (C) 2005-2015 Frediano Ziglio
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Library General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Library General Public License for more details.
14  *
15  * You should have received a copy of the GNU Library General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20 
21 #include <config.h>
22 
23 #include <stdlib.h>
24 
25 #if HAVE_UNISTD_H
26 #include <unistd.h>
27 #endif /* HAVE_UNISTD_H */
28 
29 #include <assert.h>
30 
31 #include <freetds/tds.h>
32 #include <freetds/iconv.h>
33 #include <freetds/tls.h>
34 #include <freetds/checks.h>
35 #include <freetds/string.h>
36 #include "replacements.h"
37 #include <freetds/enum_cap.h>
38 
39 #if HAVE_SYS_SOCKET_H
40 #include <sys/socket.h>
41 #endif
42 
43 #ifdef HAVE_STRING_H
44 #include <string.h>
45 #endif
46 
47 #ifdef HAVE_LOCALE_H
48 #include <locale.h>
49 #endif /* HAVE_LOCALE_H */
50 
51 #ifdef HAVE_LANGINFO_H
52 #include <langinfo.h>
53 #endif /* HAVE_LANGINFO_H */
54 
55 static void tds_free_env(TDSCONNECTION * conn);
57 static void tds_free_compute_result(TDSCOMPUTEINFO * comp_info);
58 
59 #undef TEST_MALLOC
60 #define TEST_MALLOC(dest,type) \
61  {if (!(dest = (type*)calloc(1, sizeof(type)))) goto Cleanup;}
62 
63 #undef TEST_CALLOC
64 #define TEST_CALLOC(dest,type,n) \
65  {if (!(dest = (type*)calloc((n), sizeof(type)))) goto Cleanup;}
66 
67 /**
68  * \ingroup libtds
69  * \defgroup mem Memory allocation
70  * Allocate or free resources. Allocation can fail only on out of memory.
71  * In such case they return NULL and leave the state as before call.
72  * Mainly function names are in the form tds_alloc_XX or tds_free_XXX.
73  * tds_alloc_XXX functions allocate structures and return pointer to allocated
74  * data while tds_free_XXX take structure pointers and free them. Some functions
75  * require additional parameters to initialize structure correctly.
76  * The main exception are structures that use reference counting. These structures
77  * have tds_alloc_XXX functions but instead of tds_free_XXX use tds_release_XXX.
78  */
79 
80 /**
81  * \addtogroup mem
82  * @{
83  */
84 
85 static volatile unsigned int inc_num = 1;
86 
87 /**
88  * Get an id for dynamic query based on TDS information
89  * \param conn state information for the connection and the TDS protocol
90  * \return TDS_FAIL or TDS_SUCCESS
91  */
92 static char *
94 {
95  unsigned long n;
96  int i;
97  char *p;
98  char c;
99 
101 
102  inc_num = (inc_num + 1) & 0xffff;
103  /* some version of Sybase require length <= 10, so we code id */
104  n = (unsigned long) (TDS_INTPTR) conn;
105  p = id;
106  *p++ = (char) ('a' + (n % 26u));
107  n /= 26u;
108  for (i = 0; i < 9; ++i) {
109  c = (char) ('0' + (n % 36u));
110  *p++ = (c < ('0' + 10)) ? c : c + ('a' - '0' - 10);
111  /* tdsdump_log(TDS_DBG_FUNC,"%d -> %d(%c)\n",n%36u,p[-1],p[-1]); */
112  n /= 36u;
113  if (i == 4)
114  n += 3u * inc_num;
115  }
116  *p = 0;
117  return id;
118 }
119 
120 extern const TDSCOLUMNFUNCS tds_invalid_funcs;
121 
122 static TDSCOLUMN *
124 {
125  TDSCOLUMN *col;
126 
127  TEST_MALLOC(col, TDSCOLUMN);
128  tds_dstr_init(&col->table_name);
129  tds_dstr_init(&col->column_name);
131  col->funcs = &tds_invalid_funcs;
132 
133  Cleanup:
134  return col;
135 }
136 
137 static void
139 {
140  tds_dstr_free(&col->table_name);
141  tds_dstr_free(&col->column_name);
143  if (col->column_default)
144  free(col->column_default);
145  free(col);
146 }
147 
148 
149 /**
150  * \fn TDSDYNAMIC *tds_alloc_dynamic(TDSCONNECTION *conn, const char *id)
151  * \brief Allocate a dynamic statement.
152  * \param conn the connection within which to allocate the statement.
153  * \param id a character label identifying the statement.
154  * \return a pointer to the allocated structure (NULL on failure).
155  *
156  * tds_alloc_dynamic is used to implement placeholder code under TDS 5.0
157  */
158 TDSDYNAMIC *
160 {
161  TDSDYNAMIC *dyn;
162  char tmp_id[30];
163 
164  if (id) {
165  /* check to see if id already exists (shouldn't) */
166  if (tds_lookup_dynamic(conn, id))
167  return NULL;
168  } else {
169  unsigned int n;
170  id = tmp_id;
171 
172  for (n = 0;;) {
173  if (!tds_lookup_dynamic(conn, tds_get_dynid(conn, tmp_id)))
174  break;
175  if (++n == 256)
176  return NULL;
177  }
178  }
179 
180  TEST_MALLOC(dyn, TDSDYNAMIC);
181 
182  /* take into account pointer in list */
183  dyn->ref_count = 2;
184 
185  /* insert into list */
186  dyn->next = conn->dyns;
187  conn->dyns = dyn;
188 
189  strlcpy(dyn->id, id, TDS_MAX_DYNID_LEN);
190 
191  return dyn;
192 
193  Cleanup:
194  return NULL;
195 }
196 
197 /**
198  * \fn void tds_free_input_params(TDSDYNAMIC *dyn)
199  * \brief Frees all allocated input parameters of a dynamic statement.
200  * \param dyn the dynamic statement whose input parameter are to be freed
201  *
202  * tds_free_input_params frees all parameters for the give dynamic statement
203  */
204 void
206 {
208 
209  info = dyn->params;
210  if (info) {
212  dyn->params = NULL;
213  }
214 }
215 
216 /*
217  * Called when dynamic got deallocated from server
218  */
219 void
221 {
222  TDSDYNAMIC **victim;
223 
224  tdsdump_log(TDS_DBG_FUNC, "tds_dynamic_deallocated() : freeing dynamic_id %s\n", dyn->id);
225 
226  victim = &conn->dyns;
227  while (*victim != dyn) {
228  if (*victim == NULL) {
229  tdsdump_log(TDS_DBG_FUNC, "tds_dynamic_deallocated() : cannot find id %s\n", dyn->id);
230  return;
231  }
232  victim = &(*victim)->next;
233  }
234 
235  /* remove from list */
236  *victim = dyn->next;
237  dyn->next = NULL;
238 
239  /* assure there is no id left */
240  dyn->num_id = 0;
241 
242  tds_release_dynamic(&dyn);
243 }
244 
245 
246 /**
247  * \fn void tds_release_dynamic(TDSDYNAMIC **pdyn)
248  * \brief Frees dynamic statement
249  * \param pdyn pointer to dynamic statement to be freed.
250  */
251 void
253 {
254  TDSDYNAMIC *dyn;
255 
256  dyn = *pdyn;
257  *pdyn = NULL;
258  if (!dyn || --dyn->ref_count > 0)
259  return;
260 
262 
265  free(dyn->query);
266  free(dyn);
267 }
268 
269 /**
270  * \fn TDSPARAMINFO *tds_alloc_param_result(TDSPARAMINFO *old_param)
271  * \brief Adds a output parameter to TDSPARAMINFO.
272  * \param old_param a pointer to the TDSPARAMINFO structure containing the
273  * current set of output parameter, or NULL if none exists.
274  * \return a pointer to the new TDSPARAMINFO structure.
275  *
276  * tds_alloc_param_result() works a bit differently than the other alloc result
277  * functions. Output parameters come in individually with no total number
278  * given in advance, so we simply call this func every time with get a
279  * TDS_PARAM_TOKEN and let it realloc the columns struct one bigger.
280  * tds_free_all_results() usually cleans up after us.
281  */
282 TDSPARAMINFO *
284 {
285  TDSPARAMINFO *param_info;
286  TDSCOLUMN *colinfo;
287 
288  /* parameters cannot have row associated */
289  if (old_param && (old_param->current_row || old_param->row_free))
290  return NULL;
291 
292  colinfo = tds_alloc_column();
293  if (!colinfo)
294  return NULL;
295 
296  param_info = old_param;
297  if (!param_info) {
298  TEST_MALLOC(param_info, TDSPARAMINFO);
299  param_info->ref_count = 1;
300  }
301 
302  if (!TDS_RESIZE(param_info->columns, param_info->num_cols + 1u))
303  goto Cleanup;
304 
305  param_info->columns[param_info->num_cols++] = colinfo;
306  return param_info;
307 
308  Cleanup:
309  if (!old_param)
310  free(param_info);
311  free(colinfo);
312  return NULL;
313 }
314 
315 /**
316  * Delete latest parameter
317  */
318 void
320 {
321  TDSCOLUMN *col;
322 
323  if (!param_info || param_info->num_cols <= 0)
324  return;
325 
326  col = param_info->columns[--param_info->num_cols];
327  if (col->column_data && col->column_data_free)
328  col->column_data_free(col);
329 
330  if (param_info->num_cols == 0)
331  TDS_ZERO_FREE(param_info->columns);
332 
333  /*
334  * NOTE some informations should be freed too but when this function
335  * is called are not used. I hope to remove the need for this
336  * function ASAP
337  * A better way is to support different way to allocate and get
338  * parameters
339  * -- freddy77
340  */
341  tds_free_column(col);
342 }
343 
344 static void
346 {
347  if (!col->column_data)
348  return;
349 
350  if (is_blob_col(col)) {
351  TDSBLOB *blob = (TDSBLOB *) col->column_data;
352  free(blob->textvalue);
353  }
355 }
356 
357 /**
358  * Allocate data for a parameter.
359  * @param curparam parameter to retrieve size information
360  * @return NULL on failure or new data
361  */
362 void *
364 {
365  TDS_INT data_size;
366  void *data;
367 
368  CHECK_COLUMN_EXTRA(curparam);
369 
370  data_size = curparam->funcs->row_len(curparam);
371 
372  /* allocate data */
373  if (curparam->column_data && curparam->column_data_free)
374  curparam->column_data_free(curparam);
375  curparam->column_data_free = tds_param_free;
376 
377  data = malloc(data_size);
378  curparam->column_data = (unsigned char*) data;
379  if (!data)
380  return NULL;
381  /* if is a blob reset buffer */
382  if (is_blob_col(curparam))
383  memset(data, 0, sizeof(TDSBLOB));
384 
385  return data;
386 }
387 
388 /**
389  * Allocate memory for storing compute info
390  * return NULL on out of memory
391  */
392 
393 static TDSCOMPUTEINFO *
395 {
396  TDS_USMALLINT col;
398 
400  info->ref_count = 1;
401 
402  TEST_CALLOC(info->columns, TDSCOLUMN *, num_cols);
403 
404  info->num_cols = num_cols;
405  for (col = 0; col < num_cols; col++)
406  if (!(info->columns[col] = tds_alloc_column()))
407  goto Cleanup;
408 
409  if (by_cols) {
410  TEST_CALLOC(info->bycolumns, TDS_SMALLINT, by_cols);
411  info->by_cols = by_cols;
412  }
413 
414  return info;
415  Cleanup:
417  return NULL;
418 }
419 
422 {
423  TDS_UINT n;
424  TDSCOMPUTEINFO **comp_info;
425  TDSCOMPUTEINFO *cur_comp_info;
426 
427  tdsdump_log(TDS_DBG_FUNC, "alloc_compute_result. num_cols = %d bycols = %d\n", num_cols, by_cols);
428  tdsdump_log(TDS_DBG_FUNC, "alloc_compute_result. num_comp_info = %d\n", tds->num_comp_info);
429 
430  cur_comp_info = tds_alloc_compute_result(num_cols, by_cols);
431  if (!cur_comp_info)
432  return NULL;
433 
434  n = tds->num_comp_info;
435  comp_info = (TDSCOMPUTEINFO **) TDS_RESIZE(tds->comp_info, n + 1u);
436  if (!comp_info) {
437  tds_free_compute_result(cur_comp_info);
438  return NULL;
439  }
440 
441  tds->comp_info = comp_info;
442  comp_info[n] = cur_comp_info;
443  tds->num_comp_info = n + 1u;
444 
445  tdsdump_log(TDS_DBG_FUNC, "alloc_compute_result. num_comp_info = %d\n", tds->num_comp_info);
446 
447  return comp_info;
448 }
449 
452 {
453  TDSRESULTINFO *res_info;
454  TDS_USMALLINT col;
455 
456  TEST_MALLOC(res_info, TDSRESULTINFO);
457  res_info->ref_count = 1;
458  if (num_cols)
459  TEST_CALLOC(res_info->columns, TDSCOLUMN *, num_cols);
460  for (col = 0; col < num_cols; col++)
461  if (!(res_info->columns[col] = tds_alloc_column()))
462  goto Cleanup;
463  res_info->num_cols = num_cols;
464  res_info->row_size = 0;
465  return res_info;
466  Cleanup:
467  tds_free_results(res_info);
468  return NULL;
469 }
470 
471 void
473 {
475  if (tds->current_results)
477  if (info)
478  info->attached_to = tds;
479  tds->in_row = (info != NULL);
481 }
482 
483 /**
484  * Detach result info from it current socket
485  */
486 void
488 {
489  if (info && info->attached_to) {
490  info->attached_to->current_results = NULL;
491  info->attached_to->in_row = false;
492  info->attached_to = NULL;
493  }
494 }
495 
496 static void
497 tds_row_free(TDSRESULTINFO *res_info, unsigned char *row)
498 {
499  int i;
500  const TDSCOLUMN *col;
501 
502  if (!res_info || !row)
503  return;
504 
505  for (i = 0; i < res_info->num_cols; ++i) {
506  col = res_info->columns[i];
507 
508  if (is_blob_col(col)) {
509  TDSBLOB *blob = (TDSBLOB *) &row[col->column_data - res_info->current_row];
510  if (blob->textvalue)
511  TDS_ZERO_FREE(blob->textvalue);
512  }
513  }
514 
515  free(row);
516 }
517 
518 /**
519  * Allocate space for row store
520  * return NULL on out of memory
521  */
522 TDSRET
524 {
525  int i, num_cols = res_info->num_cols;
526  unsigned char *ptr;
527  TDSCOLUMN *col;
528  TDS_UINT row_size;
529 
530  /* compute row size */
531  row_size = 0;
532  for (i = 0; i < num_cols; ++i) {
533  col = res_info->columns[i];
534 
535  col->column_data_free = NULL;
536 
537  row_size += col->funcs->row_len(col);
538  row_size += (TDS_ALIGN_SIZE - 1);
539  row_size -= row_size % TDS_ALIGN_SIZE;
540  }
541  res_info->row_size = row_size;
542 
543  ptr = tds_new0(unsigned char, row_size ? row_size : 1);
544  res_info->current_row = ptr;
545  if (!ptr)
546  return TDS_FAIL;
547  res_info->row_free = tds_row_free;
548 
549  /* fill column_data */
550  row_size = 0;
551  for (i = 0; i < num_cols; ++i) {
552  col = res_info->columns[i];
553 
554  col->column_data = ptr + row_size;
555 
556  row_size += col->funcs->row_len(col);
557  row_size += (TDS_ALIGN_SIZE - 1);
558  row_size -= row_size % TDS_ALIGN_SIZE;
559  }
560 
561  return TDS_SUCCESS;
562 }
563 
564 TDSRET
566 {
567  return tds_alloc_row(res_info);
568 }
569 
570 void
572 {
573  tds_free_results(param_info);
574 }
575 
576 static void
578 {
579  tds_free_results(comp_info);
580 }
581 
582 static void
584 {
585  TDSCOMPUTEINFO ** comp_info = tds->comp_info;
586  TDS_UINT i, num_comp = tds->num_comp_info;
587 
588  tds->comp_info = NULL;
589  tds->num_comp_info = 0;
590 
591  for (i = 0; i < num_comp; i++) {
592  if (comp_info && comp_info[i]) {
593  tds_detach_results(comp_info[i]);
594  tds_free_compute_result(comp_info[i]);
595  }
596  }
597  if (num_comp)
598  free(comp_info);
599 }
600 
601 void
602 tds_free_row(TDSRESULTINFO * res_info, unsigned char *row)
603 {
604  assert(res_info);
605  if (!row || !res_info->row_free)
606  return;
607 
608  res_info->row_free(res_info, row);
609 }
610 
611 void
613 {
614  int i;
615  TDSCOLUMN *curcol;
616 
617  if (!res_info)
618  return;
619 
620  if (--res_info->ref_count != 0)
621  return;
622 
623  tds_detach_results(res_info);
624 
625  if (res_info->num_cols && res_info->columns) {
626  for (i = 0; i < res_info->num_cols; i++)
627  if ((curcol = res_info->columns[i]) != NULL) {
628  if (curcol->bcp_terminator)
629  TDS_ZERO_FREE(curcol->bcp_terminator);
631  curcol->bcp_column_data = NULL;
632  if (curcol->column_data && curcol->column_data_free)
633  curcol->column_data_free(curcol);
634  }
635  }
636 
637  if (res_info->current_row && res_info->row_free)
638  res_info->row_free(res_info, res_info->current_row);
639 
640  if (res_info->num_cols && res_info->columns) {
641  for (i = 0; i < res_info->num_cols; i++)
642  if ((curcol = res_info->columns[i]) != NULL)
643  tds_free_column(curcol);
644  free(res_info->columns);
645  }
646 
647  free(res_info->bycolumns);
648 
649  free(res_info);
650 }
651 
652 void
654 {
655  tdsdump_log(TDS_DBG_FUNC, "tds_free_all_results()\n");
658  tds->res_info = NULL;
661  tds->param_info = NULL;
663  tds->has_status = 0;
664  tds->in_row = false;
665  tds->ret_status = 0;
666  if (tds->cur_dyn)
668 }
669 
670 /*
671  * Return 1 if winsock is initialized, else 0.
672  */
673 static int
675 {
676 #if defined(_WIN32) || defined(_WIN64)
677  static bool initialized = false;
679 
680  WSADATA wsa_data;
681  int erc;
682 
683  if (initialized)
684  return 1;
685 
687  /* same check inside the mutex */
688  if (initialized) {
690  return 1;
691  }
692 
693  /* initialize the socket layer */
694  erc = WSAStartup(MAKEWORD(2, 2), &wsa_data);
695  initialized = (erc == 0);
697 
698  if (erc != 0) {
699  char *errstr = sock_strerror(erc);
700  tdsdump_log(TDS_DBG_ERROR, "tds_init_winsock: WSAStartup failed with %d (%s)\n", erc, errstr);
701  sock_strerror_free(errstr);
702  return 0;
703  }
704 #endif
705  return 1;
706 }
707 
708 TDSCONTEXT *
709 tds_alloc_context(void * parent)
710 {
712  TDSLOCALE *locale;
713 
714  if (!winsock_initialized())
715  return NULL;
716 
717  if ((locale = tds_get_locale()) == NULL)
718  return NULL;
719 
720  if ((context = tds_new0(TDSCONTEXT, 1)) == NULL) {
722  return NULL;
723  }
724  context->locale = locale;
725  context->parent = parent;
726 
727  return context;
728 }
729 
730 void
732 {
733  if (!context)
734  return;
735 
736  tds_free_locale(context->locale);
737  free(context);
738 }
739 
740 TDSLOCALE *
742 {
743  TDSLOCALE *locale;
744 
746 
747  return locale;
748 
749  Cleanup:
751  return NULL;
752 }
753 
754 /*
755  * Default capabilities.
756  */
757 #undef REQ
758 #define SUPPORTED_REQ_CAP(i) \
759  REQ(i,LANG) REQ(i,RPC) REQ(i,EVT) REQ(i,MSTMT) REQ(i,BCP) REQ(i,CURSOR) REQ(i,DYNF) \
760  REQ(i,MSG) REQ(i,PARAM) REQ(i,DATA_INT1) REQ(i,DATA_INT2) REQ(i,DATA_INT4) REQ(i,DATA_BIT) \
761  REQ(i,DATA_CHAR) REQ(i,DATA_VCHAR) REQ(i,DATA_BIN) REQ(i,DATA_VBIN) REQ(i,DATA_MNY8) \
762  REQ(i,DATA_MNY4) REQ(i,DATA_DATE8) REQ(i,DATA_DATE4) REQ(i,DATA_FLT4) REQ(i,DATA_FLT8) \
763  REQ(i,DATA_NUM) REQ(i,DATA_TEXT) REQ(i,DATA_IMAGE) REQ(i,DATA_DEC) REQ(i,DATA_LCHAR) \
764  REQ(i,DATA_LBIN) REQ(i,DATA_INTN) REQ(i,DATA_DATETIMEN) REQ(i,DATA_MONEYN) \
765  REQ(i,CSR_PREV) REQ(i,CSR_FIRST) REQ(i,CSR_LAST) REQ(i,CSR_ABS) REQ(i,CSR_REL) \
766  REQ(i,CSR_MULTI) REQ(i,CON_INBAND) REQ(i,PROTO_TEXT) REQ(i,PROTO_BULK) \
767  REQ(i,DATA_SENSITIVITY) REQ(i,DATA_BOUNDARY) REQ(i,PROTO_DYNPROC) REQ(i,DATA_FLTN) \
768  REQ(i,DATA_BITN) REQ(i,DATA_INT8) REQ(i,WIDETABLE) \
769  REQ(i,DATA_UINT2) REQ(i,DATA_UINT4) REQ(i,DATA_UINT8) REQ(i,DATA_UINTN) REQ(i,LARGEIDENT) \
770  REQ(i,SRVPKTSIZE) REQ(i,DATA_DATE) REQ(i,DATA_TIME) REQ(i,DATA_BIGTIME) REQ(i,DATA_BIGDATETIME)
771 #define REQ(i,n) |(((TDS_REQ_ ## n / 8) == i)?(1<<(TDS_REQ_ ## n & 7)):0)
772 #define REQB(i) 0 SUPPORTED_REQ_CAP(i)
773 
774 #undef RES
775 #define SUPPORTED_RES_CAP(i) \
776  RES(i,CON_NOOOB) RES(i,PROTO_NOTEXT) RES(i,PROTO_NOBULK) RES(i,NOTDSDEBUG)
777 #define RES(i,n) |(((TDS_RES_ ## n / 8) == i)?(1<<(TDS_RES_ ## n & 7)):0)
778 #define RESB(i) 0 SUPPORTED_RES_CAP(i)
779 
780 static const TDS_CAPABILITIES defaultcaps = { {
781  /* type, len, data, data, data, data, data, data, data, data, data, data, data, data, data, data (14 bytes) */
782  { 1, 14, { REQB(13), REQB(12), REQB(11), REQB(10), REQB(9), REQB(8), REQB(7),
783  REQB(6), REQB(5), REQB(4), REQB(3), REQB(2), REQB(1), REQB(0) } },
784  { 2, 14, { RESB(13), RESB(12), RESB(11), RESB(10), RESB(9), RESB(8), RESB(7),
785  RESB(6), RESB(5), RESB(4), RESB(3), RESB(2), RESB(1), RESB(0) } }
786 } };
787 /* check we match the values size */
788 TDS_COMPILE_CHECK(tds_values_len, sizeof(defaultcaps.types[0].values) == 14);
789 /* check we match the default size */
791 
792 /**
793  * Initialize login structure with locale information and other stuff for connection
794  * @param locale locale information (copied to configuration information)
795  * @result login structure or NULL if initialization error
796  */
797 TDSLOGIN*
799 {
800  char hostname[128];
801 #if HAVE_NL_LANGINFO && defined(CODESET)
802  const char *charset;
803 #else
804  char *lc_all, *tok = NULL;
805 #endif
806 
807  /*
808  * TDS 7.0:
809  * 0x02 indicates ODBC driver
810  * 0x01 means change to initial language must succeed
811  */
812  login->option_flag2 = 0x03;
813  login->tds_version = 0 /* was TDS_DEFAULT_VERSION */;
814  login->block_size = 0;
815 
816 #if HAVE_NL_LANGINFO && defined(CODESET)
817  charset = nl_langinfo(CODESET);
818  if (strcmp(tds_canonical_charset_name(charset), "US-ASCII") == 0)
819  charset = "ISO-8859-1";
820  if (!tds_dstr_copy(&login->client_charset, charset))
821  return NULL;
822 #else
823  if (!tds_dstr_copy(&login->client_charset, "ISO-8859-1"))
824  return NULL;
825 
826  if ((lc_all = strdup(setlocale(LC_ALL, NULL))) == NULL)
827  return NULL;
828 
829  if (strtok_r(lc_all, ".", &tok)) {
830  char *encoding = strtok_r(NULL, "@", &tok);
831 #ifdef _WIN32
832  /* windows give numeric codepage*/
833  if (encoding && atoi(encoding) > 0) {
834  char *p;
835  if (asprintf(&p, "CP%s", encoding) >= 0) {
836  free(lc_all);
837  lc_all = encoding = p;
838  }
839  }
840 #endif
841  if (encoding) {
842  if (!tds_dstr_copy(&login->client_charset, encoding)) {
843  free(lc_all);
844  return NULL;
845  }
846  }
847  }
848  free(lc_all);
849 #endif
850 
851  if (locale) {
852  if (locale->language)
853  if (!tds_dstr_copy(&login->language, locale->language))
854  return NULL;
855  if (locale->server_charset)
856  if (!tds_dstr_copy(&login->server_charset, locale->server_charset))
857  return NULL;
858  }
861  return NULL;
862  }
863  memset(hostname, '\0', sizeof(hostname));
864  gethostname(hostname, sizeof(hostname));
865  hostname[sizeof(hostname) - 1] = '\0'; /* make sure it's terminated */
866  if (!tds_dstr_copy(&login->client_host_name, hostname))
867  return NULL;
868 
871  login->use_utf16 = 1;
872 
873  return login;
874 }
875 
876 TDSCURSOR *
877 tds_alloc_cursor(TDSSOCKET *tds, const char *name, size_t namelen,
878  const char *query, size_t querylen)
879 {
880  TDSCURSOR *cursor;
881  TDSCURSOR *pcursor;
882 
883  TEST_MALLOC(cursor, TDSCURSOR);
884  cursor->ref_count = 1;
885 
886  cursor->type = TDS_CUR_TYPE_KEYSET;
888 
889  TEST_CALLOC(cursor->cursor_name, char, namelen + 1);
890  memcpy(cursor->cursor_name, name, namelen);
891 
892  TEST_CALLOC(cursor->query, char, querylen + 1);
893  memcpy(cursor->query, query, querylen);
894 
895  if (tds->conn->cursors == NULL) {
896  tds->conn->cursors = cursor;
897  } else {
898  for (pcursor = tds->conn->cursors; pcursor->next; pcursor = pcursor->next)
899  continue;
900  pcursor->next = cursor;
901  }
902  /* take into account reference in connection list */
903  ++cursor->ref_count;
904 
905  return cursor;
906 
907  Cleanup:
908  tds_release_cursor(&cursor);
909  return NULL;
910 }
911 
912 /*
913  * Called when cursor got deallocated from server
914  */
915 void
917 {
918  TDSCURSOR **victim;
919 
920  tdsdump_log(TDS_DBG_FUNC, "tds_cursor_deallocated() : freeing cursor_id %d\n", cursor->cursor_id);
921 
922  victim = &conn->cursors;
923  while (*victim != cursor) {
924  if (*victim == NULL) {
925  tdsdump_log(TDS_DBG_FUNC, "tds_cursor_deallocated() : cannot find cursor_id %d\n", cursor->cursor_id);
926  return;
927  }
928  victim = &(*victim)->next;
929  }
930 
931  /* remove from list */
932  *victim = cursor->next;
933  cursor->next = NULL;
934 
935  tds_release_cursor(&cursor);
936 }
937 
938 /*
939  * Decrement reference counter and free if necessary.
940  * Called internally by libTDS and by upper library when you don't need
941  * cursor reference anymore
942  */
943 void
945 {
946  TDSCURSOR *cursor = *pcursor;
947  *pcursor = NULL;
948  if (!cursor || --cursor->ref_count > 0)
949  return;
950 
951  tdsdump_log(TDS_DBG_FUNC, "tds_release_cursor() : freeing cursor_id %d\n", cursor->cursor_id);
952 
953  tdsdump_log(TDS_DBG_FUNC, "tds_release_cursor() : freeing cursor results\n");
954  tds_detach_results(cursor->res_info);
955  tds_free_results(cursor->res_info);
956 
957  if (cursor->cursor_name) {
958  tdsdump_log(TDS_DBG_FUNC, "tds_release_cursor() : freeing cursor name\n");
959  free(cursor->cursor_name);
960  }
961 
962  if (cursor->query) {
963  tdsdump_log(TDS_DBG_FUNC, "tds_release_cursor() : freeing cursor query\n");
964  free(cursor->query);
965  }
966 
967  tdsdump_log(TDS_DBG_FUNC, "tds_release_cursor() : cursor_id %d freed\n", cursor->cursor_id);
968  free(cursor);
969 }
970 
971 TDSLOGIN *
972 tds_alloc_login(int use_environment)
973 {
974  TDSLOGIN *login = NULL;
975  const char *server_name = TDS_DEF_SERVER;
976 
979  login->use_utf16 = 1;
980  login->bulk_copy = 1;
991 
992  login->ip_addrs = NULL;
994 
1006 
1007  if (use_environment) {
1008  const char *s;
1009  if ((s=getenv("DSQUERY")) != NULL)
1010  server_name = s;
1011 
1012  if ((s=getenv("TDSQUERY")) != NULL)
1013  server_name = s;
1014  }
1015 
1016  if (!tds_dstr_copy(&login->server_name, server_name)) {
1017  free(login);
1018  return NULL;
1019  }
1020 
1022 
1023  Cleanup:
1024  return login;
1025 }
1026 
1027 void
1029 {
1030  if (!login)
1031  return;
1032 
1033  /* for security reason clear memory */
1047 
1048  if (login->ip_addrs != NULL)
1050 
1061  free(login);
1062 }
1063 
1064 TDSPACKET *
1065 tds_alloc_packet(void *buf, unsigned len)
1066 {
1067  TDSPACKET *packet = (TDSPACKET *) malloc(len + TDS_OFFSET(TDSPACKET, buf));
1068  if (TDS_LIKELY(packet)) {
1069  packet->len = 0;
1070  packet->capacity = len;
1071  packet->sid = 0;
1072  packet->next = NULL;
1073  if (buf) {
1074  memcpy(packet->buf, buf, len);
1075  packet->len = len;
1076  }
1077  }
1078  return packet;
1079 }
1080 
1081 TDSPACKET *
1083 {
1084  if (packet->capacity < len) {
1085  packet = (TDSPACKET *) realloc(packet, len + TDS_OFFSET(TDSPACKET, buf));
1086  if (TDS_LIKELY(packet))
1087  packet->capacity = len;
1088  }
1089  return packet;
1090 }
1091 
1092 void
1094 {
1095  TDSPACKET *next;
1096  for (; packet; packet = next) {
1097  next = packet->next;
1098  free(packet);
1099  }
1100 }
1101 
1102 static void
1104 {
1105  if (conn->authentication)
1106  conn->authentication->free(conn, conn->authentication);
1107  conn->authentication = NULL;
1108  while (conn->dyns)
1110  while (conn->cursors)
1111  tds_cursor_deallocated(conn, conn->cursors);
1113  /* close connection and free inactive sockets */
1115  tds_wakeup_close(&conn->wakeup);
1117  free(conn->product_name);
1118  free(conn->server);
1119  tds_free_env(conn);
1120 #if ENABLE_ODBC_MARS
1121  tds_mutex_free(&conn->list_mtx);
1122  tds_free_packets(conn->packets);
1123  tds_free_packets(conn->recv_packet);
1124  tds_free_packets(conn->send_packets);
1125  tds_free_packets(conn->packet_cache);
1126  free(conn->sessions);
1127 #endif
1128 }
1129 
1130 static TDSCONNECTION *
1132 {
1133  conn->env.block_size = bufsize;
1134  conn->s = INVALID_SOCKET;
1135  conn->use_iconv = 1;
1136  conn->tds_ctx = context;
1137 
1138  if (tds_wakeup_init(&conn->wakeup))
1139  goto Cleanup;
1140 
1141  if (tds_iconv_alloc(conn))
1142  goto Cleanup;
1143 
1144 #if ENABLE_ODBC_MARS
1145  if (tds_mutex_init(&conn->list_mtx))
1146  goto Cleanup;
1147  TEST_CALLOC(conn->sessions, TDSSOCKET*, 64);
1148  conn->num_sessions = 64;
1149 #endif
1150  return conn;
1151 
1152 Cleanup:
1153  tds_wakeup_close(&conn->wakeup);
1155  return NULL;
1156 }
1157 
1158 static TDSSOCKET *
1160 {
1161  tds_socket->parent = NULL;
1162 
1164  if (!tds_socket->recv_packet)
1165  goto Cleanup;
1167 
1169  if (!tds_socket->send_packet)
1170  goto Cleanup;
1172 
1174 
1175  /* Jeff's hack, init to no timeout */
1181  goto Cleanup;
1182 
1183 #ifdef ENABLE_ODBC_MARS
1184  tds_socket->sid = 0;
1185  if (tds_cond_init(&tds_socket->packet_cond))
1186  goto Cleanup;
1187 #endif
1188  return tds_socket;
1189 
1190  Cleanup:
1193  return NULL;
1194 }
1195 
1196 
1197 #if ENABLE_ODBC_MARS
1198 static void
1199 tds_free_connection(TDSCONNECTION *conn)
1200 {
1201  if (!conn) return;
1202  assert(conn->in_net_tds == NULL);
1204  free(conn);
1205 }
1206 
1207 static TDSCONNECTION *
1208 tds_alloc_connection(TDSCONTEXT *context, unsigned int bufsize)
1209 {
1211 
1214  goto Cleanup;
1215  return conn;
1216 
1217 Cleanup:
1218  tds_free_connection(conn);
1219  return NULL;
1220 }
1221 
1222 static TDSSOCKET *
1223 tds_alloc_socket_base(unsigned int bufsize)
1224 {
1226 
1229  goto Cleanup;
1230  return tds_socket;
1231 
1232  Cleanup:
1234  return NULL;
1235 }
1236 
1237 TDSSOCKET *
1238 tds_alloc_socket(TDSCONTEXT * context, unsigned int bufsize)
1239 {
1240  TDSCONNECTION *conn = tds_alloc_connection(context, bufsize);
1241  TDSSOCKET *tds;
1242 
1243  if (!conn)
1244  return NULL;
1245 
1246  tds = tds_alloc_socket_base(bufsize);
1247  if (tds) {
1248  conn->sessions[0] = tds;
1249  tds->conn = conn;
1250  return tds;
1251  }
1252  tds_free_connection(conn);
1253  return NULL;
1254 }
1255 
1256 TDSSOCKET *
1258 {
1259  TDSSOCKET *tds;
1260  if (!IS_TDS72_PLUS(conn) || !conn->mars)
1261  return NULL;
1262 
1263  tds = tds_alloc_socket_base(conn->env.block_size);
1264  if (!tds)
1265  return NULL;
1266 
1267  tds->sid = -1;
1268  tds->conn = conn;
1269  tds->state = TDS_IDLE;
1270  return tds;
1271 }
1272 #else /* !ENABLE_ODBC_MARS */
1273 TDSSOCKET *
1275 {
1277 
1280  goto Cleanup;
1282  goto Cleanup;
1283  return tds_socket;
1284 
1285  Cleanup:
1287  return NULL;
1288 }
1289 #endif /* !ENABLE_ODBC_MARS */
1290 
1291 TDSSOCKET *
1293 {
1294  TDSPACKET *packet;
1295 
1296  assert(tds && tds->out_buf && tds->send_packet);
1297 
1298  if (bufsize < 512)
1299  bufsize = 512;
1300 
1302 
1303  if (tds->out_pos > bufsize)
1304  return NULL;
1305 
1307  if (packet == NULL)
1308  return NULL;
1309 
1310  tds->out_buf = packet->buf;
1311  tds->out_buf_max = bufsize;
1312  tds->send_packet = packet;
1313  return tds;
1314 }
1315 
1316 #if ENABLE_ODBC_MARS
1317 static void
1319 {
1320  unsigned n;
1321  int must_free = 1;
1322  tds_mutex_lock(&conn->list_mtx);
1323  if (tds->sid >= 0 && tds->sid < conn->num_sessions)
1324  conn->sessions[tds->sid] = NULL;
1325  for (n = 0; n < conn->num_sessions; ++n)
1326  if (TDSSOCKET_VALID(conn->sessions[n])) {
1327  must_free = 0;
1328  break;
1329  }
1330  if (!must_free) {
1331  /* tds use connection member so must be valid */
1333  }
1334  tds_mutex_unlock(&conn->list_mtx);
1335 
1336  /* detach entirely */
1337  tds->sid = -1;
1338  tds->conn = NULL;
1339 
1340  if (must_free)
1341  tds_free_connection(conn);
1342 }
1343 #else
1344 static void inline
1346 {
1348 }
1349 #endif
1350 
1351 void
1353 {
1354 #if ENABLE_EXTRA_CHECKS
1355  TDSDYNAMIC *dyn;
1356  TDSCURSOR *cur;
1357 #endif
1358 
1359  if (!tds)
1360  return;
1361 
1362  /* detach this socket */
1366 #if ENABLE_EXTRA_CHECKS
1367  for (dyn = tds->conn->dyns; dyn; dyn = dyn->next) {
1368  if (dyn->res_info && dyn->res_info->attached_to == tds) {
1369  assert(0);
1370  }
1371  }
1372  for (cur = tds->conn->cursors; cur; cur = cur->next) {
1373  if (cur->res_info && cur->res_info->attached_to == tds) {
1374  assert(0);
1375  }
1376  }
1377 #endif
1379 #if ENABLE_ODBC_MARS
1380  tds_cond_destroy(&tds->packet_cond);
1381 #endif
1382 
1386  free(tds);
1387 }
1388 
1389 void
1391 {
1392  if (!locale)
1393  return;
1394 
1395  free(locale->language);
1396  free(locale->server_charset);
1397  free(locale->date_fmt);
1398  free(locale);
1399 }
1400 
1401 static void
1403 {
1404  if (conn->env.language)
1405  TDS_ZERO_FREE(conn->env.language);
1406  if (conn->env.charset)
1407  TDS_ZERO_FREE(conn->env.charset);
1408  if (conn->env.database)
1409  TDS_ZERO_FREE(conn->env.database);
1410 }
1411 
1412 void
1414 {
1415  if (message) {
1416  message->priv_msg_type = 0;
1417  message->msgno = 0;
1418  message->state = 0;
1419  message->severity = 0;
1420  message->line_number = 0;
1421  TDS_ZERO_FREE(message->message);
1422  TDS_ZERO_FREE(message->server);
1423  TDS_ZERO_FREE(message->proc_name);
1424  TDS_ZERO_FREE(message->sql_state);
1425  }
1426 }
1427 
1428 #define SQLS_ENTRY(number,state) case number: p = state; break
1429 
1430 char *
1432 {
1433  const char *p = NULL;
1434 
1435  switch (msgno) {
1436  SQLS_ENTRY(17000, "S1T00"); /* timeouts ??? */
1437  SQLS_ENTRY(20004, "08S01"); /* Communication link failure */
1438  SQLS_ENTRY(20006, "08S01");
1439  SQLS_ENTRY(20009, "08S01");
1440  SQLS_ENTRY(20020, "08S01");
1441  SQLS_ENTRY(20019, "24000"); /* Invalid cursor state */
1442  SQLS_ENTRY(20014, "28000"); /* Invalid authorization specification */
1443  SQLS_ENTRY(2400, "42000"); /* Syntax error or access violation */
1444  SQLS_ENTRY(2401, "42000");
1445  SQLS_ENTRY(2403, "42000");
1446  SQLS_ENTRY(2404, "42000");
1447  SQLS_ENTRY(2402, "S1000"); /* General error */
1448  }
1449 
1450  if (p != NULL)
1451  return strdup(p);
1452  else
1453  return NULL;
1454 }
1455 
1456 char *
1458 {
1459  const char *p = NULL;
1460  char *q = NULL;
1461 
1462  if (TDS_IS_MSSQL(tds)) {
1463  switch (msgno) { /* MSSQL Server */
1464 
1465  SQLS_ENTRY(3621,"01000");
1466  SQLS_ENTRY(8153,"01003"); /* Null in aggregate */
1467  SQLS_ENTRY(911, "08004"); /* Server rejected connection */
1468  SQLS_ENTRY(512, "21000"); /* Subquery returns more than one value */
1469  SQLS_ENTRY(213, "21S01"); /* Insert column list mismatch */
1470  SQLS_ENTRY(109, "21S01");
1471  SQLS_ENTRY(110, "21S01");
1472  SQLS_ENTRY(1774,"21S02"); /* Ref column mismatch */
1473  SQLS_ENTRY(8152,"22001"); /* String data would be truncated */
1474  SQLS_ENTRY(5146,"22003"); /* Numeric value out of range */
1475  SQLS_ENTRY(168, "22003"); /* Arithmetic overflow */
1476  SQLS_ENTRY(220, "22003");
1477  SQLS_ENTRY(232, "22003");
1478  SQLS_ENTRY(234, "22003");
1479  SQLS_ENTRY(236, "22003");
1480  SQLS_ENTRY(238, "22003");
1481  SQLS_ENTRY(244, "22003");
1482  SQLS_ENTRY(246, "22003");
1483  SQLS_ENTRY(248, "22003");
1484  SQLS_ENTRY(519, "22003");
1485  SQLS_ENTRY(520, "22003");
1486  SQLS_ENTRY(521, "22003");
1487  SQLS_ENTRY(522, "22003");
1488  SQLS_ENTRY(523, "22003");
1489  SQLS_ENTRY(524, "22003");
1490  SQLS_ENTRY(1007,"22003");
1491  SQLS_ENTRY(3606,"22003");
1492  SQLS_ENTRY(8115,"22003");
1493  SQLS_ENTRY(206, "22005"); /* Error in assignment */
1494  SQLS_ENTRY(235, "22005");
1495  SQLS_ENTRY(247, "22005");
1496  SQLS_ENTRY(249, "22005");
1497  SQLS_ENTRY(256, "22005");
1498  SQLS_ENTRY(257, "22005");
1499  SQLS_ENTRY(305, "22005");
1500  SQLS_ENTRY(409, "22005");
1501  SQLS_ENTRY(518, "22005");
1502  SQLS_ENTRY(529, "22005");
1503  SQLS_ENTRY(210, "22007"); /* Invalid datetime format */
1504  SQLS_ENTRY(241, "22007");
1505  SQLS_ENTRY(295, "22007");
1506  SQLS_ENTRY(242, "22008"); /* Datetime out of range */
1507  SQLS_ENTRY(296, "22008");
1508  SQLS_ENTRY(298, "22008");
1509  SQLS_ENTRY(535, "22008");
1510  SQLS_ENTRY(542, "22008");
1511  SQLS_ENTRY(517, "22008");
1512  SQLS_ENTRY(3607, "22012"); /* Div by zero */
1513  SQLS_ENTRY(8134, "22012");
1514  SQLS_ENTRY(245, "22018"); /* Syntax error? */
1515  SQLS_ENTRY(2627, "23000"); /* Constraint violation */
1516  SQLS_ENTRY(515, "23000");
1517  SQLS_ENTRY(233, "23000");
1518  SQLS_ENTRY(273, "23000");
1519  SQLS_ENTRY(530, "23000");
1520  SQLS_ENTRY(2601,"23000");
1521  SQLS_ENTRY(2615,"23000");
1522  SQLS_ENTRY(2626,"23000");
1523  SQLS_ENTRY(3604,"23000");
1524  SQLS_ENTRY(3605,"23000");
1525  SQLS_ENTRY(544, "23000");
1526  SQLS_ENTRY(547, "23000");
1527  SQLS_ENTRY(550, "23000");
1528  SQLS_ENTRY(4415, "23000");
1529  SQLS_ENTRY(1505, "23000");
1530  SQLS_ENTRY(1508, "23000");
1531  SQLS_ENTRY(3725, "23000");
1532  SQLS_ENTRY(3726, "23000");
1533  SQLS_ENTRY(4712, "23000");
1534  SQLS_ENTRY(10055, "23000");
1535  SQLS_ENTRY(10065, "23000");
1536  SQLS_ENTRY(11011, "23000");
1537  SQLS_ENTRY(11040, "23000");
1538  SQLS_ENTRY(16999, "24000"); /* Invalid cursor state */
1539  SQLS_ENTRY(16905, "24000");
1540  SQLS_ENTRY(16917, "24000");
1541  SQLS_ENTRY(16946, "24000");
1542  SQLS_ENTRY(16950, "24000");
1543  SQLS_ENTRY(266, "25000"); /* Invalid transaction state */
1544  SQLS_ENTRY(277,"25000");
1545  SQLS_ENTRY(611,"25000");
1546  SQLS_ENTRY(3906,"25000");
1547  SQLS_ENTRY(3908,"25000");
1548  SQLS_ENTRY(6401,"25000");
1549  SQLS_ENTRY(626, "25000");
1550  SQLS_ENTRY(627, "25000");
1551  SQLS_ENTRY(628, "25000");
1552  SQLS_ENTRY(3902, "25000");
1553  SQLS_ENTRY(3903, "25000");
1554  SQLS_ENTRY(3916, "25000");
1555  SQLS_ENTRY(3918, "25000");
1556  SQLS_ENTRY(3919, "25000");
1557  SQLS_ENTRY(3921, "25000");
1558  SQLS_ENTRY(3922, "25000");
1559  SQLS_ENTRY(3926, "25000");
1560  SQLS_ENTRY(7969, "25000");
1561  SQLS_ENTRY(8506, "25000");
1562  SQLS_ENTRY(15626, "25000");
1563  SQLS_ENTRY(18456, "28000"); /* Login failed? */
1564  SQLS_ENTRY(6104, "37000"); /* Syntax error or access violation */
1565  SQLS_ENTRY(8114, "37000");
1566  SQLS_ENTRY(131, "37000");
1567  SQLS_ENTRY(137, "37000");
1568  SQLS_ENTRY(170, "37000");
1569  SQLS_ENTRY(174, "37000");
1570  SQLS_ENTRY(201, "37000");
1571  SQLS_ENTRY(2812, "37000");
1572  SQLS_ENTRY(2526, "37000");
1573  SQLS_ENTRY(8144, "37000");
1574  SQLS_ENTRY(17308, "42000"); /* Syntax/Access violation */
1575  SQLS_ENTRY(17571, "42000");
1576  SQLS_ENTRY(18002, "42000");
1577  SQLS_ENTRY(229, "42000");
1578  SQLS_ENTRY(230, "42000");
1579  SQLS_ENTRY(262, "42000");
1580  SQLS_ENTRY(2557, "42000");
1581  SQLS_ENTRY(2571, "42000");
1582  SQLS_ENTRY(2760, "42000");
1583  SQLS_ENTRY(3110, "42000");
1584  SQLS_ENTRY(3704, "42000");
1585  SQLS_ENTRY(4613, "42000");
1586  SQLS_ENTRY(4618, "42000");
1587  SQLS_ENTRY(4834, "42000");
1588  SQLS_ENTRY(5011, "42000");
1589  SQLS_ENTRY(5116, "42000");
1590  SQLS_ENTRY(5812, "42000");
1591  SQLS_ENTRY(6004, "42000");
1592  SQLS_ENTRY(6102, "42000");
1593  SQLS_ENTRY(7956, "42000");
1594  SQLS_ENTRY(11010, "42000");
1595  SQLS_ENTRY(11045, "42000");
1596  SQLS_ENTRY(14126, "42000");
1597  SQLS_ENTRY(15247, "42000");
1598  SQLS_ENTRY(15622, "42000");
1599  SQLS_ENTRY(20604, "42000");
1600  SQLS_ENTRY(21049, "42000");
1601  SQLS_ENTRY(113, "42000");
1602  SQLS_ENTRY(2714, "42S01"); /* Table or view already exists */
1603  SQLS_ENTRY(208, "42S02"); /* Table or view not found */
1604  SQLS_ENTRY(3701, "42S02");
1605  SQLS_ENTRY(1913, "42S11"); /* Index already exists */
1606  SQLS_ENTRY(15605, "42S11");
1607  SQLS_ENTRY(307, "42S12"); /* Index not found */
1608  SQLS_ENTRY(308, "42S12");
1609  SQLS_ENTRY(10033, "42S12");
1610  SQLS_ENTRY(15323, "42S12");
1611  SQLS_ENTRY(18833, "42S12");
1612  SQLS_ENTRY(4925, "42S21"); /* Column already exists */
1613  SQLS_ENTRY(21255, "42S21");
1614  SQLS_ENTRY(1911, "42S22"); /* Column not found */
1615  SQLS_ENTRY(207, "42S22");
1616  SQLS_ENTRY(4924, "42S22");
1617  SQLS_ENTRY(4926, "42S22");
1618  SQLS_ENTRY(15645, "42S22");
1619  SQLS_ENTRY(21166, "42S22");
1620  }
1621  } else {
1622  switch (msgno) { /* Sybase */
1623  SQLS_ENTRY(3621, "01000");
1624  SQLS_ENTRY(9501, "01003"); /* Null in aggregate */
1625  SQLS_ENTRY(911, "08004"); /* Server rejected connection */
1626  SQLS_ENTRY(512, "21000"); /* Subquery returns more than one value */
1627  SQLS_ENTRY(213, "21S01"); /* Insert column list mismatch */
1628  SQLS_ENTRY(109, "21S01");
1629  SQLS_ENTRY(110, "21S01");
1630  SQLS_ENTRY(1715, "21S02"); /* Ref column mismatch */
1631  SQLS_ENTRY(9502, "22001"); /* String data would be truncated */
1632  SQLS_ENTRY(220, "22003"); /* Arithmetic overflow */
1633  SQLS_ENTRY(168, "22003");
1634  SQLS_ENTRY(227, "22003");
1635  SQLS_ENTRY(232, "22003");
1636  SQLS_ENTRY(234, "22003");
1637  SQLS_ENTRY(236, "22003");
1638  SQLS_ENTRY(238, "22003");
1639  SQLS_ENTRY(244, "22003");
1640  SQLS_ENTRY(246, "22003");
1641  SQLS_ENTRY(247, "22003");
1642  SQLS_ENTRY(248, "22003");
1643  SQLS_ENTRY(519, "22003");
1644  SQLS_ENTRY(520, "22003");
1645  SQLS_ENTRY(521, "22003");
1646  SQLS_ENTRY(522, "22003");
1647  SQLS_ENTRY(523, "22003");
1648  SQLS_ENTRY(524, "22003");
1649  SQLS_ENTRY(3606, "22003");
1650  SQLS_ENTRY(206, "22005"); /* Error in assignment */
1651  SQLS_ENTRY(235, "22005");
1652  SQLS_ENTRY(249, "22005");
1653  SQLS_ENTRY(256, "22005");
1654  SQLS_ENTRY(305, "22005");
1655  SQLS_ENTRY(409, "22005");
1656  SQLS_ENTRY(518, "22005");
1657  SQLS_ENTRY(529, "22005");
1658  SQLS_ENTRY(535, "22008"); /* Datetime out of range */
1659  SQLS_ENTRY(542, "22008");
1660  SQLS_ENTRY(517, "22008");
1661  SQLS_ENTRY(3607, "22012"); /* Div by zero */
1662  SQLS_ENTRY(245, "22018"); /* Syntax error? */
1663  SQLS_ENTRY(544, "23000"); /* Constraint violation */
1664  SQLS_ENTRY(233, "23000");
1665  SQLS_ENTRY(273, "23000");
1666  SQLS_ENTRY(530, "23000");
1667  SQLS_ENTRY(2601,"23000");
1668  SQLS_ENTRY(2615,"23000");
1669  SQLS_ENTRY(2626,"23000");
1670  SQLS_ENTRY(3604,"23000");
1671  SQLS_ENTRY(3605,"23000");
1672  SQLS_ENTRY(545, "23000");
1673  SQLS_ENTRY(546, "23000");
1674  SQLS_ENTRY(547, "23000");
1675  SQLS_ENTRY(548, "23000");
1676  SQLS_ENTRY(549, "23000");
1677  SQLS_ENTRY(550, "23000");
1678  SQLS_ENTRY(1505, "23000");
1679  SQLS_ENTRY(1508, "23000");
1680  SQLS_ENTRY(565, "24000"); /* Invalid cursor state */
1681  SQLS_ENTRY(558, "24000");
1682  SQLS_ENTRY(559, "24000");
1683  SQLS_ENTRY(6235, "24000");
1684  SQLS_ENTRY(583, "24000");
1685  SQLS_ENTRY(6259, "24000");
1686  SQLS_ENTRY(6260, "24000");
1687  SQLS_ENTRY(562, "24000");
1688  SQLS_ENTRY(277, "25000"); /* Invalid transaction state */
1689  SQLS_ENTRY(611,"25000");
1690  SQLS_ENTRY(3906,"25000");
1691  SQLS_ENTRY(3908,"25000");
1692  SQLS_ENTRY(6401,"25000");
1693  SQLS_ENTRY(627, "25000");
1694  SQLS_ENTRY(628, "25000");
1695  SQLS_ENTRY(641, "25000");
1696  SQLS_ENTRY(642, "25000");
1697  SQLS_ENTRY(1276, "25000");
1698  SQLS_ENTRY(3902, "25000");
1699  SQLS_ENTRY(3903, "25000");
1700  SQLS_ENTRY(6104, "37000"); /* Syntax error or access violation */
1701  SQLS_ENTRY(102, "37000");
1702  SQLS_ENTRY(137, "37000");
1703  SQLS_ENTRY(7327, "37000");
1704  SQLS_ENTRY(201, "37000");
1705  SQLS_ENTRY(257, "37000");
1706  SQLS_ENTRY(2812, "37000");
1707  SQLS_ENTRY(2526, "37000");
1708  SQLS_ENTRY(11021, "37000");
1709  SQLS_ENTRY(229, "42000"); /* Syntax/Access violation */
1710  SQLS_ENTRY(230, "42000");
1711  SQLS_ENTRY(262, "42000");
1712  SQLS_ENTRY(4602, "42000");
1713  SQLS_ENTRY(4603, "42000");
1714  SQLS_ENTRY(4608, "42000");
1715  SQLS_ENTRY(10306, "42000");
1716  SQLS_ENTRY(10323, "42000");
1717  SQLS_ENTRY(10330, "42000");
1718  SQLS_ENTRY(10331, "42000");
1719  SQLS_ENTRY(10332, "42000");
1720  SQLS_ENTRY(11110, "42000");
1721  SQLS_ENTRY(11113, "42000");
1722  SQLS_ENTRY(11118, "42000");
1723  SQLS_ENTRY(11121, "42000");
1724  SQLS_ENTRY(17222, "42000");
1725  SQLS_ENTRY(17223, "42000");
1726  SQLS_ENTRY(18350, "42000");
1727  SQLS_ENTRY(18351, "42000");
1728  SQLS_ENTRY(113, "42000");
1729  SQLS_ENTRY(2714, "42S01"); /* Table or view already exists */
1730  SQLS_ENTRY(208, "42S02"); /* Table or view not found */
1731  SQLS_ENTRY(3701, "42S02");
1732  SQLS_ENTRY(1913, "42S11"); /* Index already exists */
1733  SQLS_ENTRY(307, "42S12"); /* Index not found */
1734  SQLS_ENTRY(7010, "42S12");
1735  SQLS_ENTRY(18091, "42S12");
1736  SQLS_ENTRY(1921, "42S21"); /* Column already exists */
1737  SQLS_ENTRY(1720, "42S22"); /* Column not found */
1738  SQLS_ENTRY(207, "42S22");
1739  SQLS_ENTRY(4934, "42S22");
1740  SQLS_ENTRY(18117, "42S22");
1741  }
1742  }
1743 
1744  if (p != NULL && (q = strdup(p)) != NULL) {
1745  /* FIXME correct here ?? */
1746  /* Convert known ODBC 3.x states listed above to 2.x */
1747  if (memcmp(q, "42S", 3) == 0)
1748  memcpy(q, "S00", 3);
1749 
1750  return q;
1751  }
1752  return NULL;
1753 }
1754 
1755 BCPCOLDATA *
1756 tds_alloc_bcp_column_data(unsigned int column_size)
1757 {
1758  BCPCOLDATA *coldata;
1759 
1760  TEST_MALLOC(coldata, BCPCOLDATA);
1761 
1762  if (column_size > 4 * 1024)
1763  column_size = 4 * 1024;
1764  TEST_CALLOC(coldata->data, unsigned char, column_size);
1765 
1766  return coldata;
1767 Cleanup:
1768  tds_free_bcp_column_data(coldata);
1769  return NULL;
1770 }
1771 
1772 void
1774 {
1775  if (!coldata)
1776  return;
1777 
1778  free(coldata->data);
1779  free(coldata);
1780 }
1781 
1782 TDSBCPINFO *
1784 {
1785  TDSBCPINFO *bcpinfo;
1786 
1787  TEST_MALLOC(bcpinfo, TDSBCPINFO);
1788 
1789  tds_dstr_init(&bcpinfo->tablename);
1790 
1791  return bcpinfo;
1792 Cleanup:
1793  return NULL;
1794 }
1795 
1796 void
1798 {
1799  /*
1800  * Historically done for all TDS 5.0 transfers, but the protocol
1801  * version isn't available here, or even in blk_done anymore.
1802  */
1803  if (bcpinfo->direction == TDS_BCP_IN && bcpinfo->bindinfo != NULL
1804  && bcpinfo->bindinfo->current_row != NULL) {
1805  TDS_ZERO_FREE(bcpinfo->bindinfo->current_row);
1806  }
1807  tds_dstr_free(&bcpinfo->tablename);
1808  TDS_ZERO_FREE(bcpinfo->insert_stmt);
1809  tds_free_results(bcpinfo->bindinfo);
1810  bcpinfo->bindinfo = NULL;
1811 }
1812 
1813 void
1815 {
1816  if (bcpinfo) {
1817  tds_deinit_bcpinfo(bcpinfo);
1818  free(bcpinfo);
1819  }
1820 }
1821 
1822 /**
1823  * Reallocate a pointer and update it if success
1824  * \param pp pointer to pointer to be reallocated
1825  * \param new_size new size to be allocated
1826  * \return new pointer allocated, NULL on failure
1827  */
1828 void *
1829 tds_realloc(void **pp, size_t new_size)
1830 {
1831  void *p;
1832 
1833  /* some implementation of malloc/realloc does not like size==0 */
1834  if (!new_size)
1835  new_size = 1;
1836 
1837  /* use malloc if not allocated before, some implementation require it */
1838  if (*pp)
1839  p = realloc(*pp, new_size);
1840  else
1841  p = malloc(new_size);
1842 
1843  /* update pointer only on success */
1844  if (p)
1845  *pp = p;
1846 
1847  return p;
1848 }
1849 
1850 /** @} */
static CS_CONNECTION * conn
Definition: ct_dynamic.c:25
#define CHECK_COLUMN_EXTRA(column)
Definition: checks.h:34
#define CHECK_CONN_EXTRA(conn)
Definition: checks.h:39
static DLIST_TYPE *DLIST_NAME() next(DLIST_LIST_TYPE *list, DLIST_TYPE *item)
Definition: dlist.tmpl.h:56
@ TDS_CUR_TYPE_KEYSET
Definition: proto.h:451
@ TDS_CUR_CONCUR_OPTIMISTIC
Definition: proto.h:463
#define INVALID_SOCKET
#define TDS_ADDITIONAL_SPACE
#define sock_strerror(n)
#define sock_strerror_free(s)
#define TDS_FAIL
Definition: tds.h:204
#define TDS_IS_MSSQL(x)
Check if product is Microsft SQL Server.
Definition: tds.h:1722
#define TDS_OFFSET(str, field)
Definition: tds.h:364
#define TDS_ALIGN_SIZE
Definition: tds.h:568
tds_sysdep_int32_type TDS_INT
Definition: tds.h:149
#define TDS_LIKELY(x)
Definition: tds.h:371
#define tdsdump_log
Definition: tds.h:1561
#define TDS_DEF_SERVER
Definition: tds.h:475
static void tds_release_cur_dyn(TDSSOCKET *tds)
Definition: tds.h:1366
tds_sysdep_intptr_type TDS_INTPTR
Definition: tds.h:155
#define TDS_MAX_DYNID_LEN
Definition: tds.h:472
#define is_blob_col(x)
Definition: tds.h:445
#define IS_TDS72_PLUS(x)
Definition: tds.h:1710
@ TDS_IDLE
no data expected
Definition: tds.h:863
@ TDS_DEAD
no connection
Definition: tds.h:868
tds_sysdep_int16_type TDS_SMALLINT
Definition: tds.h:147
#define tds_new0(type, n)
Definition: tds.h:1393
int TDSRET
Definition: tds.h:201
tds_sysdep_uint16_type TDS_USMALLINT
Definition: tds.h:148
#define TDS_DBG_ERROR
Definition: tds.h:903
#define TDS_SUCCESS
Definition: tds.h:203
#define TDS_RESIZE(p, n_elem)
Definition: tds.h:1390
@ TDS_BCP_IN
Definition: tds.h:1654
#define TDS_ZERO_FREE(x)
Definition: tds.h:359
tds_sysdep_uint32_type TDS_UINT
Definition: tds.h:150
#define TDS_MAX_CAPABILITY
Definition: tds.h:469
#define TDS_DEF_LANG
Definition: tds.h:478
#define TDS_DBG_FUNC
Definition: tds.h:898
#define tds_mutex_free(x)
Definition: thread.h:419
#define tds_mutex_lock(x)
Definition: thread.h:421
#define tds_mutex_unlock(x)
Definition: thread.h:423
#define tds_mutex_init(x)
Definition: thread.h:420
static void tds_ssl_deinit(TDSCONNECTION *conn)
Definition: tls.h:94
static tds_mutex mtx
Definition: condition.c:43
#define asprintf
Definition: replacements.h:54
#define strlcpy(d, s, l)
Definition: replacements.h:80
#define strtok_r
Definition: replacements.h:68
#define freeaddrinfo(a)
Definition: replacements.h:101
#define TEST_CALLOC(dest, type, n)
Definition: mem.c:64
#define TEST_MALLOC(dest, type)
Definition: mem.c:60
static TDSSOCKET * tds
Definition: collations.c:37
static TDSLOGIN * login
Definition: dataread.c:31
#define tds_connection_close
#define tds_iconv_alloc
#define tds_iconv_free
#define tds_get_locale
#define tds_wakeup_init
#define tds_init_write_buf
#define tds_wakeup_close
#define tds_lookup_dynamic
#define tds_canonical_charset_name
#define tds_cond_destroy
Definition: thread.h:332
#define TDS_MUTEX_INITIALIZER
Definition: thread.h:335
#define tds_cond_init
Definition: thread.h:331
#define tds_mutex
Definition: thread.h:336
char data[12]
Definition: iconv.c:80
#define tds_alloc_additional_socket
#define tds_append_fin
#define NULL
Definition: ncbistd.hpp:225
void tds_dstr_zero(DSTR *s)
clear all string filling with zeroes (mainly for security reason)
Definition: tdsstring.c:56
static void tds_dstr_init(DSTR *s)
init a string with empty
Definition: string.h:41
void tds_dstr_free(DSTR *s)
free string
Definition: tdsstring.c:63
DSTR * tds_dstr_copy(DSTR *s, const char *src) TDS_WUR
copy a string from another
Definition: tdsstring.c:123
static int tds_dstr_isempty(DSTR *s)
test if string is empty
Definition: string.h:48
static TDSSOCKET * tds_init_socket(TDSSOCKET *tds_socket, unsigned int bufsize)
Definition: mem.c:1159
static TDSCONNECTION * tds_init_connection(TDSCONNECTION *conn, TDSCONTEXT *context, unsigned int bufsize)
Definition: mem.c:1131
TDSRESULTINFO * tds_alloc_results(TDS_USMALLINT num_cols)
Definition: mem.c:451
TDSRET tds_alloc_compute_row(TDSCOMPUTEINFO *res_info)
Definition: mem.c:565
void tds_free_bcp_column_data(BCPCOLDATA *coldata)
Definition: mem.c:1773
TDSRET tds_alloc_row(TDSRESULTINFO *res_info)
Allocate space for row store return NULL on out of memory.
Definition: mem.c:523
TDSLOGIN * tds_alloc_login(int use_environment)
Definition: mem.c:972
static volatile unsigned int inc_num
Definition: mem.c:85
void tds_detach_results(TDSRESULTINFO *info)
Detach result info from it current socket.
Definition: mem.c:487
TDSPACKET * tds_realloc_packet(TDSPACKET *packet, unsigned len)
Definition: mem.c:1082
void * tds_alloc_param_data(TDSCOLUMN *curparam)
Allocate data for a parameter.
Definition: mem.c:363
static void tds_deinit_connection(TDSCONNECTION *conn)
Definition: mem.c:1103
static void tds_free_env(TDSCONNECTION *conn)
Definition: mem.c:1402
TDSLOGIN * tds_init_login(TDSLOGIN *login, TDSLOCALE *locale)
Initialize login structure with locale information and other stuff for connection.
Definition: mem.c:798
TDSDYNAMIC * tds_alloc_dynamic(TDSCONNECTION *conn, const char *id)
Allocate a dynamic statement.
Definition: mem.c:159
static void tds_row_free(TDSRESULTINFO *res_info, unsigned char *row)
Definition: mem.c:497
static TDSCOLUMN * tds_alloc_column(void)
Definition: mem.c:123
TDSSOCKET * tds_realloc_socket(TDSSOCKET *tds, unsigned int bufsize)
Definition: mem.c:1292
char * tds_alloc_lookup_sqlstate(TDSSOCKET *tds, int msgno)
Definition: mem.c:1457
static char * tds_get_dynid(TDSCONNECTION *conn, char *id)
Get an id for dynamic query based on TDS information.
Definition: mem.c:93
static void tds_free_compute_result(TDSCOMPUTEINFO *comp_info)
Definition: mem.c:577
TDSPACKET * tds_alloc_packet(void *buf, unsigned len)
Definition: mem.c:1065
#define RESB(i)
Definition: mem.c:778
TDSCONTEXT * tds_alloc_context(void *parent)
Definition: mem.c:709
#define SQLS_ENTRY(number, state)
Definition: mem.c:1428
static int winsock_initialized(void)
Definition: mem.c:674
void tds_free_param_results(TDSPARAMINFO *param_info)
Definition: mem.c:571
void tds_free_param_result(TDSPARAMINFO *param_info)
Delete latest parameter.
Definition: mem.c:319
TDSLOCALE * tds_alloc_locale(void)
Definition: mem.c:741
static void tds_param_free(TDSCOLUMN *col)
Definition: mem.c:345
static const TDS_CAPABILITIES defaultcaps
Definition: mem.c:780
const TDSCOLUMNFUNCS tds_invalid_funcs
Definition: data.h:104
TDSPARAMINFO * tds_alloc_param_result(TDSPARAMINFO *old_param)
Adds a output parameter to TDSPARAMINFO.
Definition: mem.c:283
void tds_set_current_results(TDSSOCKET *tds, TDSRESULTINFO *info)
Definition: mem.c:472
void tds_free_all_results(TDSSOCKET *tds)
Definition: mem.c:653
TDSBCPINFO * tds_alloc_bcpinfo(void)
Definition: mem.c:1783
void * tds_realloc(void **pp, size_t new_size)
Reallocate a pointer and update it if success.
Definition: mem.c:1829
void tds_free_context(TDSCONTEXT *context)
Definition: mem.c:731
void tds_release_cursor(TDSCURSOR **pcursor)
Definition: mem.c:944
void tds_cursor_deallocated(TDSCONNECTION *conn, TDSCURSOR *cursor)
Definition: mem.c:916
TDSCURSOR * tds_alloc_cursor(TDSSOCKET *tds, const char *name, size_t namelen, const char *query, size_t querylen)
Definition: mem.c:877
void tds_free_row(TDSRESULTINFO *res_info, unsigned char *row)
Definition: mem.c:602
BCPCOLDATA * tds_alloc_bcp_column_data(unsigned int column_size)
Definition: mem.c:1756
TDS_COMPILE_CHECK(tds_values_len, sizeof(defaultcaps.types[0].values)==14)
TDSSOCKET * tds_alloc_socket(TDSCONTEXT *context, unsigned int bufsize)
Definition: mem.c:1274
void tds_free_input_params(TDSDYNAMIC *dyn)
Frees all allocated input parameters of a dynamic statement.
Definition: mem.c:205
void tds_release_dynamic(TDSDYNAMIC **pdyn)
Frees dynamic statement.
Definition: mem.c:252
static void tds_free_compute_results(TDSSOCKET *tds)
Definition: mem.c:583
void tds_dynamic_deallocated(TDSCONNECTION *conn, TDSDYNAMIC *dyn)
Definition: mem.c:220
void tds_free_bcpinfo(TDSBCPINFO *bcpinfo)
Definition: mem.c:1814
void tds_free_login(TDSLOGIN *login)
Definition: mem.c:1028
void tds_free_msg(TDSMESSAGE *message)
Definition: mem.c:1413
void tds_free_locale(TDSLOCALE *locale)
Definition: mem.c:1390
static void tds_free_column(TDSCOLUMN *col)
Definition: mem.c:138
#define REQB(i)
Definition: mem.c:772
char * tds_alloc_client_sqlstate(int msgno)
Definition: mem.c:1431
void tds_deinit_bcpinfo(TDSBCPINFO *bcpinfo)
Definition: mem.c:1797
static TDSCOMPUTEINFO * tds_alloc_compute_result(TDS_USMALLINT num_cols, TDS_USMALLINT by_cols)
Allocate memory for storing compute info return NULL on out of memory.
Definition: mem.c:394
void tds_free_packets(TDSPACKET *packet)
Definition: mem.c:1093
void tds_free_results(TDSRESULTINFO *res_info)
Definition: mem.c:612
static void tds_connection_remove_socket(TDSCONNECTION *conn, TDSSOCKET *tds)
Definition: mem.c:1345
TDSCOMPUTEINFO ** tds_alloc_compute_results(TDSSOCKET *tds, TDS_USMALLINT num_cols, TDS_USMALLINT by_cols)
Definition: mem.c:421
void tds_free_socket(TDSSOCKET *tds)
Definition: mem.c:1352
char * buf
int i
if(yy_accept[yy_current_state])
yy_size_t n
int len
static MDB_envinfo info
Definition: mdb_load.c:37
int strcmp(const char *str1, const char *str2)
Definition: odbc_utils.hpp:160
#define strdup
Definition: ncbi_ansi_ext.h:70
static const char * locale
Definition: pcre2grep.c:212
static PCRE2_SIZE bufsize
Definition: pcre2grep.c:237
#define assert(x)
Definition: srv_diag.hpp:58
#define row(bind, expected)
Definition: string_bind.c:73
static string query
TDS_UCHAR * data
Definition: tds.h:694
TDSRESULTINFO * bindinfo
Definition: tds.h:1669
TDS_CHAR * insert_stmt
Definition: tds.h:1664
DSTR tablename
Definition: tds.h:1663
TDS_INT direction
Definition: tds.h:1665
Information about blobs (e.g.
Definition: tds.h:658
TDS_CHAR * textvalue
Definition: tds.h:659
TDS_CAPABILITY_TYPE types[2]
Definition: tds.h:579
unsigned char values[32/2-2]
Definition: tds.h:574
tds_func_row_len * row_len
Definition: tds.h:712
Metadata about columns in regular and compute rows.
Definition: tds.h:761
DSTR column_name
Definition: tds.h:787
BCPCOLDATA * bcp_column_data
Definition: tds.h:825
void(* column_data_free)(struct tds_column *column)
Definition: tds.h:794
const TDSCOLUMNFUNCS * funcs
Definition: tds.h:762
DSTR table_column_name
Definition: tds.h:788
DSTR table_name
Definition: tds.h:786
unsigned char * column_data
Definition: tds.h:793
unsigned char * column_default
Definition: tds.h:791
TDS_CHAR * bcp_terminator
Definition: tds.h:836
TDSENV env
environment is shared between all sessions
Definition: tds.h:1147
TDSCURSOR * cursors
linked list of cursors allocated for this connection contains only cursors allocated on the server
Definition: tds.h:1153
TDSDYNAMIC * dyns
list of dynamic allocated for this connection contains only dynamic allocated on the server
Definition: tds.h:1158
Holds informations about a cursor.
Definition: tds.h:1007
char * query
SQL query.
Definition: tds.h:1017
char * cursor_name
name of the cursor
Definition: tds.h:1010
TDS_INT ref_count
reference counter so client can retain safely a pointer
Definition: tds.h:1009
TDS_INT cursor_id
cursor id returned by the server after cursor declare
Definition: tds.h:1011
TDS_INT type
row fetched from this cursor
Definition: tds.h:1026
TDS_INT concurrency
Definition: tds.h:1026
TDSRESULTINFO * res_info
Definition: tds.h:1025
struct tds_cursor * next
next in linked list, keep first
Definition: tds.h:1008
Holds information for a dynamic (also called prepared) query.
Definition: tds.h:1047
struct tds_dynamic * next
next in linked list, keep first
Definition: tds.h:1048
TDS_INT ref_count
reference counter so client can retain safely a pointer
Definition: tds.h:1049
char id[30]
id of dynamic.
Definition: tds.h:1057
char * query
saved query, we need to know original query if prepare is impossible
Definition: tds.h:1079
TDSPARAMINFO * params
query parameters.
Definition: tds.h:1077
TDSPARAMINFO * res_info
query results
Definition: tds.h:1069
TDS_INT num_id
numeric id for mssql7+
Definition: tds.h:1051
int block_size
packet size (512-65535)
Definition: tds.h:1035
Definition: tds.h:584
DSTR crlfile
certificate revocation file
Definition: tds.h:598
unsigned int check_ssl_hostname
Definition: tds.h:634
DSTR server_realm_name
server realm name (in freetds.conf)
Definition: tds.h:594
DSTR database
Definition: tds.h:611
DSTR client_charset
Definition: tds.h:610
DSTR user_name
account for login
Definition: tds.h:601
struct addrinfo * ip_addrs
ip(s) of server
Definition: tds.h:613
DSTR password
password of account login
Definition: tds.h:602
DSTR db_filename
database filename to attach (MSSQL)
Definition: tds.h:596
TDS_CAPABILITIES capabilities
Definition: tds.h:609
DSTR routing_address
Definition: tds.h:619
unsigned char option_flag2
Definition: tds.h:622
DSTR client_host_name
Definition: tds.h:592
DSTR dump_file
Definition: tds.h:616
unsigned int valid_configuration
Definition: tds.h:633
DSTR server_name
server name (in freetds.conf)
Definition: tds.h:585
DSTR instance_name
Definition: tds.h:615
DSTR server_charset
charset of server e.g.
Definition: tds.h:590
DSTR language
Definition: tds.h:589
TDS_USMALLINT tds_version
TDS version.
Definition: tds.h:587
DSTR new_password
new password to set (TDS 7.2+)
Definition: tds.h:603
struct addrinfo * connected_addr
Definition: tds.h:614
unsigned int use_utf16
Definition: tds.h:631
DSTR server_host_name
Definition: tds.h:593
DSTR openssl_ciphers
Definition: tds.h:599
unsigned int bulk_copy
if bulk copy should be enabled
Definition: tds.h:624
DSTR cafile
certificate authorities file
Definition: tds.h:597
DSTR server_spn
server SPN (in freetds.conf)
Definition: tds.h:595
int block_size
Definition: tds.h:588
DSTR library
Definition: tds.h:605
DSTR app_name
Definition: tds.h:600
TDS_CHAR * sql_state
Definition: tds.h:949
TDS_CHAR * message
Definition: tds.h:947
TDS_INT msgno
Definition: tds.h:950
TDS_CHAR * proc_name
Definition: tds.h:948
TDS_INT line_number
Definition: tds.h:951
TDS_CHAR * server
Definition: tds.h:946
TDS_TINYINT priv_msg_type
Definition: tds.h:954
TDS_TINYINT severity
Definition: tds.h:955
TDS_SMALLINT state
Definition: tds.h:953
short sid
Definition: tds.h:1125
unsigned len
Definition: tds.h:1126
unsigned char buf[1]
Definition: tds.h:1127
struct tds_packet * next
Definition: tds.h:1124
unsigned capacity
Definition: tds.h:1126
Hold information for any results.
Definition: tds.h:842
unsigned char * current_row
Definition: tds.h:849
TDS_SMALLINT * bycolumns
Definition: tds.h:853
TDSCOLUMN ** columns
Definition: tds.h:844
TDS_USMALLINT num_cols
Definition: tds.h:845
TDS_INT ref_count
Definition: tds.h:847
void(* row_free)(struct tds_result_info *result, unsigned char *row)
Definition: tds.h:850
TDS_INT row_size
Definition: tds.h:851
TDSSOCKET * attached_to
Definition: tds.h:848
Information for a server connection.
Definition: tds.h:1211
void(* env_chg_func)(TDSSOCKET *tds, int type, char *oldval, char *newval)
Definition: tds.h:1285
TDSCOMPUTEINFO ** comp_info
Definition: tds.h:1266
TDS_INT ret_status
return status from store procedure
Definition: tds.h:1272
unsigned out_pos
current position in out_buf
Definition: tds.h:1238
TDSCURSOR * cur_cursor
cursor in use
Definition: tds.h:1268
void * parent
Definition: tds.h:1243
unsigned char * out_buf
Output buffer.
Definition: tds.h:1230
TDS_TINYINT has_status
true is ret_status is valid
Definition: tds.h:1270
tds_mutex wire_mtx
Definition: tds.h:1306
TDSPACKET * send_packet
packet we are preparing to send
Definition: tds.h:1256
unsigned char * in_buf
Input buffer.
Definition: tds.h:1223
TDSDYNAMIC * cur_dyn
dynamic structure in use
Definition: tds.h:1281
TDS_STATE state
Definition: tds.h:1273
bool in_row
true if we are getting rows
Definition: tds.h:1271
TDSCONNECTION conn[1]
Definition: tds.h:1215
TDSPACKET * recv_packet
Definition: tds.h:1254
TDSRESULTINFO * current_results
Current query information.
Definition: tds.h:1263
TDSRESULTINFO * res_info
Definition: tds.h:1264
TDS_UINT num_comp_info
Definition: tds.h:1265
unsigned int out_buf_max
Maximum size of packet pointed by out_buf.
Definition: tds.h:1236
TDS_INT query_timeout
Definition: tds.h:1279
TDSPARAMINFO * param_info
Definition: tds.h:1267
static CS_CONTEXT * context
Definition: will_convert.c:21
void free(voidpf ptr)
voidp malloc(uInt size)
Modified on Fri Sep 20 14:57:08 2024 by modify_doxy.py rev. 669887